Skip to content

feat(menu): use primaryComponent from the limel-list#3994

Open
LucyChyzhova wants to merge 1 commit intomainfrom
feat/menu-list-reflect-primaryComponent
Open

feat(menu): use primaryComponent from the limel-list#3994
LucyChyzhova wants to merge 1 commit intomainfrom
feat/menu-list-reflect-primaryComponent

Conversation

@LucyChyzhova
Copy link
Copy Markdown
Contributor

@LucyChyzhova LucyChyzhova commented Apr 1, 2026

fix: https://github.com/Lundalogik/lime-crm-components/pull/4166

Screenshot 2026-04-01 at 15 55 02

Summary by CodeRabbit

  • New Features
    • Menu items can include a custom primary component rendered before text, badge, and chevron for richer item visuals.
  • Bug Fixes
    • The menu item's disabled state now correctly propagates to primary components and their visual opacity reflects disabled styling.
  • Documentation
    • Added an example demonstrating menu items with a primary component and selection display.

Review:

  • Commits are atomic
  • Commits have the correct type for the changes made
  • Commits with breaking changes are marked as such

Browsers tested:

(Check any that applies, it's ok to leave boxes unchecked if testing something didn't seem relevant.)

Windows:

  • Chrome
  • Edge
  • Firefox

Linux:

  • Chrome
  • Firefox

macOS:

  • Chrome
  • Firefox
  • Safari

Mobile:

  • Chrome on Android
  • iOS

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

Warning

Rate limit exceeded

@LucyChyzhova has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 14 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 13 minutes and 14 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 515e0637-33bb-445b-807e-1dd3532acd06

📥 Commits

Reviewing files that changed from the base of the PR and between 3cd9a50 and a63a9e6.

⛔ Files ignored due to path filters (1)
  • etc/lime-elements.api.md is excluded by !etc/lime-elements.api.md
📒 Files selected for processing (7)
  • src/components/list-item/list-item.scss
  • src/components/list-item/list-item.tsx
  • src/components/list-item/menu-item-meta/menu-item-meta.tsx
  • src/components/menu-list/menu-list-renderer.tsx
  • src/components/menu/examples/menu-primary-component.tsx
  • src/components/menu/menu.tsx
  • src/components/menu/menu.types.ts
📝 Walkthrough

Walkthrough

Adds an optional primaryComponent property to MenuItem and threads it through menu-list-renderer into MenuItemMeta, which conditionally renders the provided component before existing meta content and propagates the disabled state.

Changes

Cohort / File(s) Summary
Type Definitions
src/components/menu/menu.types.ts
Added primaryComponent?: ListComponent to MenuItem and imported ListComponent.
Menu item meta
src/components/list-item/menu-item-meta/menu-item-meta.tsx
Added primaryComponent prop and renderPrimaryComponent() to instantiate the provided component (spreading props and forcing disabled={this.disabled}) before existing meta rendering.
Menu list renderer
src/components/menu-list/menu-list-renderer.tsx
renderMenuItem now includes item.primaryComponent when deciding to render limel-menu-item-meta and passes it through as primaryComponent.
List item propagation
src/components/list-item/list-item.tsx
Propagates the parent list item's disabled state to rendered primary components (disabled={this.disabled}).
Styling
src/components/list-item/list-item.scss
Include limel-menu-item-meta in disabled opacity selectors so primary component fades when parent is disabled.
Examples & docs
src/components/menu/examples/menu-primary-component.tsx, src/components/menu/menu.tsx
Added example component demonstrating primaryComponent usage and registered it as an example for limel-menu.

Sequence Diagram(s)

sequenceDiagram
    participant Renderer as MenuListRenderer
    participant Meta as MenuItemMeta
    participant Primary as PrimaryComponent
    participant User as User (DOM / Event)

    Renderer->>Meta: render with props (commandText, badge, hotkey, disabled, primaryComponent?)
    Meta->>Meta: renderPrimaryComponent() checks primaryComponent?.name
    alt primaryComponent present
        Meta->>Primary: instantiate PrimaryComponent + props + disabled={disabled}
        Primary-->>Meta: rendered component node
    end
    Meta->>User: render commandText, badge, chevron after primary component
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

released

Suggested reviewers

  • adrianschmidt
  • Kiarokh
  • jgroth
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: extending the menu component to support primaryComponent from list items, which aligns with all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/menu-list-reflect-primaryComponent

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

Documentation has been published to https://lundalogik.github.io/lime-elements/versions/PR-3994/

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/menu/menu.types.ts`:
- Around line 125-130: Add a documentation example file demonstrating how to use
the new primaryComponent prop for the Menu component (similar to the existing
ListItem example); specifically, create a new example (e.g.,
menu-primary-component.tsx) that shows Menu/MenuItem rendering an icon or custom
component via the primaryComponent prop, mirror patterns from
list-item-primary-component.tsx, export/register the example per the project's
examples convention, and ensure the JSDoc for primaryComponent in menu.types.ts
references this new example so developers can see usage with MenuItem and custom
ListComponent implementations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: da042012-9ecb-4aaf-b3aa-cddebb0490b3

📥 Commits

Reviewing files that changed from the base of the PR and between 603788b and d58487e.

📒 Files selected for processing (3)
  • src/components/list-item/menu-item-meta/menu-item-meta.tsx
  • src/components/menu-list/menu-list-renderer.tsx
  • src/components/menu/menu.types.ts

Comment on lines +125 to +130
/**
* Component used to render additional content in the menu item.
* Rendered before the item's text, similar to `primaryComponent`
* on `ListItem`.
*/
primaryComponent?: ListComponent;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we maybe should add an example as mr Robot here says, what do you think?

Comment on lines +125 to +130
/**
* Component used to render additional content in the menu item.
* Rendered before the item's text, similar to `primaryComponent`
* on `ListItem`.
*/
primaryComponent?: ListComponent;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we maybe should add an example as mr Robot here says, what do you think?

@LucyChyzhova LucyChyzhova force-pushed the feat/menu-list-reflect-primaryComponent branch from 5a80fc8 to 3cd9a50 Compare April 2, 2026 08:20
@LucyChyzhova LucyChyzhova removed their assignment Apr 2, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/menu/examples/menu-primary-component.tsx`:
- Line 2: The render method currently returns an array literal; update it to
import and use Host from '@stencil/core' and wrap the multiple child elements
inside <Host> instead of returning an array (modify the existing import line to
include Host and change the render implementation in the component class's
render method to return a single <Host> element containing the children). Ensure
no array is returned and that all previous child elements are placed as direct
children of Host.

In `@src/components/menu/menu.types.ts`:
- Around line 125-133: Update the JSDoc for the primaryComponent prop to clarify
that primaryComponent is rendered in the menu item's meta/trailing area (routed
via limel-menu-item-meta), is display-only and must remain non-interactive so
the row still behaves as a single ARIA menuitem; mention that it must not
contain focusable controls or assume leading/list-item placement, and update the
limel-example-menu-primary-component example text to reflect this contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9832a307-083c-4c4c-b1c6-38221db80ee2

📥 Commits

Reviewing files that changed from the base of the PR and between d58487e and 3cd9a50.

📒 Files selected for processing (7)
  • src/components/list-item/list-item.scss
  • src/components/list-item/list-item.tsx
  • src/components/list-item/menu-item-meta/menu-item-meta.tsx
  • src/components/menu-list/menu-list-renderer.tsx
  • src/components/menu/examples/menu-primary-component.tsx
  • src/components/menu/menu.tsx
  • src/components/menu/menu.types.ts

@@ -0,0 +1,77 @@
import { LimelMenuCustomEvent, MenuItem } from '@limetech/lime-elements';
import { Component, h, State } from '@stencil/core';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

fd -a "menu-primary-component.tsx" src/components/menu/examples/

Repository: Lundalogik/lime-elements

Length of output: 142


🏁 Script executed:

# Check if file exists and examine the relevant lines
if [ -f "src/components/menu/examples/menu-primary-component.tsx" ]; then
  echo "=== File Content with Line Numbers ==="
  cat -n "src/components/menu/examples/menu-primary-component.tsx" | head -80
fi

Repository: Lundalogik/lime-elements

Length of output: 2882


Wrap the example output in <Host>.

Returning an array literal from the render method violates the repo's StencilJS pattern. Use <Host> to wrap multiple child elements instead, which aligns with the codebase and removes the missing-key warnings.

♻️ Suggested change
-import { Component, h, State } from '@stencil/core';
+import { Component, h, Host, State } from '@stencil/core';
…
     public render() {
-        return [
-            <limel-menu items={this.items} onSelect={this.handleSelect}>
-                <limel-button label="Tasks" slot="trigger" />
-            </limel-menu>,
-            <limel-example-value value={this.lastSelectedItem} />,
-        ];
+        return (
+            <Host>
+                <limel-menu items={this.items} onSelect={this.handleSelect}>
+                    <limel-button label="Tasks" slot="trigger" />
+                </limel-menu>
+                <limel-example-value value={this.lastSelectedItem} />
+            </Host>
+        );
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/menu/examples/menu-primary-component.tsx` at line 2, The
render method currently returns an array literal; update it to import and use
Host from '@stencil/core' and wrap the multiple child elements inside <Host>
instead of returning an array (modify the existing import line to include Host
and change the render implementation in the component class's render method to
return a single <Host> element containing the children). Ensure no array is
returned and that all previous child elements are placed as direct children of
Host.

Comment on lines +125 to +133
/**
* Component used to render additional content in the menu item.
*
* When the menu item is disabled, the `disabled` prop is automatically
* propagated to the primary component.
*
* See `limel-example-menu-primary-component` for usage.
*/
primaryComponent?: ListComponent;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Clarify that menu primaryComponent is trailing, display-only content.

This public prop is routed through limel-menu-item-meta, while the row itself still behaves as a single menuitem. Please spell out here that it renders in the menu item's meta area and must stay non-interactive; otherwise consumers can assume list-item-like leading placement or nest focusable controls that break menu keyboarding. Please align the example copy with that contract too.

✏️ Suggested JSDoc update
     /**
-     * Component used to render additional content in the menu item.
+     * Component used to render additional trailing meta content in the menu item.
+     *
+     * It is rendered together with the menu item's meta content, before
+     * shortcut text, badges, and submenu chevrons.
+     *
+     * This content must be presentational only. Do not pass focusable or
+     * interactive components, since the row itself remains the single
+     * `menuitem`.
      *
      * When the menu item is disabled, the `disabled` prop is automatically
      * propagated to the primary component.
      *
      * See `limel-example-menu-primary-component` for usage.
      */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Component used to render additional content in the menu item.
*
* When the menu item is disabled, the `disabled` prop is automatically
* propagated to the primary component.
*
* See `limel-example-menu-primary-component` for usage.
*/
primaryComponent?: ListComponent;
/**
* Component used to render additional trailing meta content in the menu item.
*
* It is rendered together with the menu item's meta content, before
* shortcut text, badges, and submenu chevrons.
*
* This content must be presentational only. Do not pass focusable or
* interactive components, since the row itself remains the single
* `menuitem`.
*
* When the menu item is disabled, the `disabled` prop is automatically
* propagated to the primary component.
*
* See `limel-example-menu-primary-component` for usage.
*/
primaryComponent?: ListComponent;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/menu/menu.types.ts` around lines 125 - 133, Update the JSDoc
for the primaryComponent prop to clarify that primaryComponent is rendered in
the menu item's meta/trailing area (routed via limel-menu-item-meta), is
display-only and must remain non-interactive so the row still behaves as a
single ARIA menuitem; mention that it must not contain focusable controls or
assume leading/list-item placement, and update the
limel-example-menu-primary-component example text to reflect this contract.

@LucyChyzhova LucyChyzhova force-pushed the feat/menu-list-reflect-primaryComponent branch from 3cd9a50 to a63a9e6 Compare April 2, 2026 08:37
@LucyChyzhova LucyChyzhova requested a review from a team as a code owner April 2, 2026 08:37
@LucyChyzhova LucyChyzhova self-assigned this Apr 2, 2026
*
* See `limel-example-menu-primary-component` for usage.
*/
primaryComponent?: ListComponent;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a chat with @LucyChyzhova earlier today. Mayeb you have already talked about it.

But just to make sure you have heard my feedback 😄 :

I don't think it's a good idea to make the interface and APIs of the menu more complicated than it already is. The primary component slot is already being used by the menu itself, for other internal things (such as hotkeys, command text, caret, badge).

It's really hard to motivate having additional stuff here, decided by the consumer. They need to coexist and work well. The UI will be really hard to maintain if you add this, because we have to deal with many unforeseen scenarios. Please don't merge this PR. 🙏

if this was really a must have, a better choice would be perhaps introducing a new slot. But I wouldn't do that neither.

Regarding your design needs

For your particular use case, a badge would be enough, which already exists. No need for more features like this really, to address that need.

But I would also question that design. I think you have better choices for what you wanna achieve 🤗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants