Skip to content

Conversation

@Kiarokh
Copy link
Contributor

@Kiarokh Kiarokh commented Oct 15, 2025

fix https://github.com/Lundalogik/crm-client/issues/367
fix https://github.com/Lundalogik/crm-client/issues/364

Summary by CodeRabbit

  • New Features

    • Improved keyboard support: Enter/Space now toggle selection on focused list items.
    • Centralized interaction handling for more consistent selection across list variants.
  • Bug Fixes

    • Clicking action menus no longer toggles items.
    • Disabled and aria-disabled items correctly ignore clicks and key presses.
    • More accurate selection state and feedback messages (Selected/Deselected).
  • Refactor

    • Moved interaction handling from individual items to the list container for consistent behavior.

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

@Kiarokh Kiarokh force-pushed the list-item-double-events branch from db7c25c to 9dec4ac Compare October 15, 2025 09:13
@coderabbitai
Copy link

coderabbitai bot commented Oct 15, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Centralizes interaction handling in list-item examples to container-level click/keyboard events and removes the list-item component’s internal click handling and interact event. Selection state and “last interaction” messages are now managed by the example containers using data-value attributes. No public API signatures remain for the removed interact event.

Changes

Cohort / File(s) Summary of changes
Core list-item interaction removal
src/components/list-item/list-item.tsx
Removed internal click-based selection logic and the interact EventEmitter; dropped isSelectableType and related handlers; keyboard now triggers host click without internal toggling; ARIA/role handling retained.
Examples: centralized container handlers
src/components/list-item/examples/list-item-actions.tsx, src/components/list-item/examples/list-item-checkbox.tsx, src/components/list-item/examples/list-item-interactive.tsx, src/components/list-item/examples/list-item-radio.tsx
Replaced per-item onInteract with ul-level onClick/onKeyDown; added data-value on items; introduced toggle/select helpers; guard against disabled and action menu targets; maintain selected state and last interaction strings; removed onInteract wiring.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant UL as List Container (ul)
  participant LI as <limel-list-item>
  participant State as Example State

  U->>LI: Click or Key (Enter/Space)
  note right of LI: No internal interact event<br/>No internal selection toggle
  LI-->>UL: Event bubbles (click/keydown)
  UL->>UL: Guard checks (disabled, action menu, aria-disabled)
  UL->>State: Toggle/update selected value(s)
  State-->>UL: Update lastInteraction text
  UL-->>U: Rerender with updated selection
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

maintenance

Suggested reviewers

  • jgroth
  • adrianschmidt
  • LucyChyzhova

Pre-merge checks and finishing touches

✅ 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 accurately describes the primary change of preventing duplicate interact event emissions in the list component after item clicks and uses concise, specific phrasing to highlight the bug fix.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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

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

Copy link

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/list-item/examples/list-item-interactive.tsx (1)

3-35: Update example docs to reflect removal of interact event

The description still says “emits an event with details about the item”. That no longer applies after removing the component’s interact event. Please update the docs accordingly.

src/components/list-item/list-item.tsx (1)

176-183: Remove component-level keyboard handling in limel-list-item

In src/components/list-item/list-item.tsx, drop the import of Element, the @Element host property, the onKeyDown={this.onKeyDown} on <Host>, and the onKeyDown method. Delegate all Enter/Space handling to container components.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d816178 and 9dec4ac.

📒 Files selected for processing (5)
  • src/components/list-item/examples/list-item-actions.tsx (3 hunks)
  • src/components/list-item/examples/list-item-checkbox.tsx (2 hunks)
  • src/components/list-item/examples/list-item-interactive.tsx (3 hunks)
  • src/components/list-item/examples/list-item-radio.tsx (2 hunks)
  • src/components/list-item/list-item.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/wrap-multiple-jsx-elements-in-host-not-in-array.mdc)

When returning multiple JSX elements from the render method, never wrap them in an array literal. Instead, always wrap them in the special <Host> element. When there is already a single top-level element, it does not have to be wrapped in <Host>.

Files:

  • src/components/list-item/examples/list-item-interactive.tsx
  • src/components/list-item/examples/list-item-checkbox.tsx
  • src/components/list-item/examples/list-item-radio.tsx
  • src/components/list-item/list-item.tsx
  • src/components/list-item/examples/list-item-actions.tsx

⚙️ CodeRabbit configuration file

**/*.tsx: Our .tsx files are typically using StencilJS, not React. When a developer wants to return multiple top-level JSX elements from the render method, they will sometimes wrap them in an array literal. In these cases, rather than recommending they add key properties to the elements, recommend removing the hardcoded array literal. Recommend wrapping the elements in StencilJS's special <Host> element.

Files:

  • src/components/list-item/examples/list-item-interactive.tsx
  • src/components/list-item/examples/list-item-checkbox.tsx
  • src/components/list-item/examples/list-item-radio.tsx
  • src/components/list-item/list-item.tsx
  • src/components/list-item/examples/list-item-actions.tsx
**/*.{ts,tsx}

⚙️ CodeRabbit configuration file

**/*.{ts,tsx}: Imports from other files in the same module (lime-elements) must use relative paths. Using absolute paths for imports will cause the production build to fail.

Files:

  • src/components/list-item/examples/list-item-interactive.tsx
  • src/components/list-item/examples/list-item-checkbox.tsx
  • src/components/list-item/examples/list-item-radio.tsx
  • src/components/list-item/list-item.tsx
  • src/components/list-item/examples/list-item-actions.tsx
**/*.{tsx,scss}

⚙️ CodeRabbit configuration file

**/*.{tsx,scss}: Almost all our components use shadow-DOM. Therefore, we have no need of BEM-style class names in our CSS.

Files:

  • src/components/list-item/examples/list-item-interactive.tsx
  • src/components/list-item/examples/list-item-checkbox.tsx
  • src/components/list-item/examples/list-item-radio.tsx
  • src/components/list-item/list-item.tsx
  • src/components/list-item/examples/list-item-actions.tsx
src/components/**/examples/**/*.{ts,tsx}

⚙️ CodeRabbit configuration file

src/components/**/examples/**/*.{ts,tsx}: These files are an exception to the rule that all imports should use relative paths. When these example files import something that is publicly exported by lime-elements, the import should be made from @limetech/lime-elements. If they import something from another file inside the example folder, the import should use a relative path.

Files:

  • src/components/list-item/examples/list-item-interactive.tsx
  • src/components/list-item/examples/list-item-checkbox.tsx
  • src/components/list-item/examples/list-item-radio.tsx
  • src/components/list-item/examples/list-item-actions.tsx
src/components/**/*.tsx

⚙️ CodeRabbit configuration file

src/components/**/*.tsx: When contributors add new props to existing components in the lime-elements repository, they should always add documentation examples that demonstrate the new prop's usage and explain how it works. This helps with user adoption, feature discoverability, and maintains comprehensive documentation.

Files:

  • src/components/list-item/examples/list-item-interactive.tsx
  • src/components/list-item/examples/list-item-checkbox.tsx
  • src/components/list-item/examples/list-item-radio.tsx
  • src/components/list-item/list-item.tsx
  • src/components/list-item/examples/list-item-actions.tsx
🧠 Learnings (4)
📚 Learning: 2025-08-26T08:42:17.994Z
Learnt from: Kiarokh
PR: Lundalogik/lime-elements#3628
File: src/components/list-item/list-item.tsx:316-321
Timestamp: 2025-08-26T08:42:17.994Z
Learning: In src/components/list-item/list-item.tsx, the RadioButtonTemplate and CheckboxTemplate components are used purely for visualization and receive their checked state from the parent component's selected prop. The actual interaction is handled by a centralized onClick handler on the Host element, making the entire list item clickable. Adding onChange handlers to these templates would be redundant and potentially problematic.

Applied to files:

  • src/components/list-item/examples/list-item-interactive.tsx
  • src/components/list-item/examples/list-item-checkbox.tsx
  • src/components/list-item/examples/list-item-radio.tsx
  • src/components/list-item/list-item.tsx
  • src/components/list-item/examples/list-item-actions.tsx
📚 Learning: 2025-08-12T14:01:27.846Z
Learnt from: Kiarokh
PR: Lundalogik/lime-elements#3638
File: src/components/radio-button-group/radio-button-group.tsx:91-91
Timestamp: 2025-08-12T14:01:27.846Z
Learning: The `limel-radio-button-group` component has accessibility concerns because it uses `limel-list` for rendering, which doesn't follow WAI-ARIA APG keyboard navigation patterns for radio button groups. Arrow keys should move focus AND select in radio groups, but limel-list requires arrow keys to move focus, then Enter/Space to select.

Applied to files:

  • src/components/list-item/examples/list-item-radio.tsx
📚 Learning: 2025-04-25T13:32:56.396Z
Learnt from: adrianschmidt
PR: Lundalogik/lime-elements#3529
File: src/components/lime-ai-avatar/lime-ai-avatar.tsx:30-38
Timestamp: 2025-04-25T13:32:56.396Z
Learning: For StencilJS components in lime-elements, prefer using the `<Host>` element to wrap child elements in the render method instead of returning an array of elements, which eliminates the need for key attributes and follows StencilJS best practices.

Applied to files:

  • src/components/list-item/examples/list-item-actions.tsx
📚 Learning: 2025-08-21T15:57:46.879Z
Learnt from: Kiarokh
PR: Lundalogik/lime-elements#3628
File: src/components/list-item/examples/list-item-actions.tsx:40-63
Timestamp: 2025-08-21T15:57:46.879Z
Learning: The examples in src/components/list-item/examples/ are for internal usage and verification, not for external developers. The actual consumers of limel-list-item are other internal components like limel-list or limel-menu-list. These examples should be taken with a pinch of salt regarding semantic correctness and accessibility, as the proper implementation will be handled by the consuming components.

Applied to files:

  • src/components/list-item/examples/list-item-actions.tsx
🪛 Biome (2.1.2)
src/components/list-item/examples/list-item-checkbox.tsx

[error] 76-76: The elements with this role can be changed to the following elements:

For examples and more information, see WAI-ARIA Roles

(lint/a11y/useSemanticElements)

src/components/list-item/examples/list-item-radio.tsx

[error] 60-60: The HTML element ul is non-interactive and should not have an interactive role.

Replace ul with a div or a span.
Unsafe fix: Remove the role attribute.

(lint/a11y/noNoninteractiveElementToInteractiveRole)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Docs / Publish Docs
  • GitHub Check: Build
  • GitHub Check: Test
🔇 Additional comments (2)
src/components/list-item/examples/list-item-actions.tsx (1)

47-47: Centralized interaction looks good, but prevent double activation with component keydown

Handlers are solid: ignore action-menu clicks, respect disabled, and update Set immutably. However, limel-list-item’s own keydown currently dispatches a click, so Enter/Space here will also trigger an additional click → two toggles.

Resolve by removing limel-list-item’s keydown (see my list-item.tsx comment). Then keep this container’s onKeyDown/onClick as the only paths.

Also applies to: 101-165

src/components/list-item/examples/list-item-interactive.tsx (1)

103-127: Use correct focus detection and JSX attribute casing in the example

  • Change tabindex={0} to tabIndex={0}.
  • In onHostKeyDown, replace
    const active = document.activeElement as HTMLElement | null;
    with
    const active = this.host.shadowRoot
        ? (this.host.shadowRoot.activeElement as HTMLElement | null)
        : null;
  • Do not remove or alter the core list-item.tsx onKeyDown handler—it already handles shadow-DOM focus correctly.

Likely an incorrect or invalid review comment.

@Kiarokh Kiarokh force-pushed the list-item-double-events branch 2 times, most recently from 4de4eeb to 96b5657 Compare October 15, 2025 11:30
@Kiarokh Kiarokh requested a review from a team as a code owner October 15, 2025 11:50
@Kiarokh Kiarokh force-pushed the list-item-double-events branch from a4d2998 to 87ca624 Compare October 15, 2025 11:50
@Kiarokh Kiarokh enabled auto-merge (rebase) October 15, 2025 12:03
Copy link
Contributor

@adrianschmidt adrianschmidt left a comment

Choose a reason for hiding this comment

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

Changes to external API approved.

@Kiarokh Kiarokh merged commit 7672994 into main Oct 15, 2025
12 checks passed
@Kiarokh Kiarokh deleted the list-item-double-events branch October 15, 2025 12:35
@lime-opensource
Copy link
Collaborator

🎉 This PR is included in version 38.28.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants