Skip to content

⌨️ fix: Make Scope Selector Operable with the Enter Key - #121

Open
dustinhealy wants to merge 1 commit into
chore/click-ui-0.9.1from
fix/click-ui-scope-selector-enter
Open

⌨️ fix: Make Scope Selector Operable with the Enter Key#121
dustinhealy wants to merge 1 commit into
chore/click-ui-0.9.1from
fix/click-ui-scope-selector-enter

Conversation

@dustinhealy

Copy link
Copy Markdown
Contributor

Summary

Four Enter-key bugs in the configuration scope selector, all one root cause and all pre-existing (not click-ui 0.9.1 regressions): the whole selector renders inside cmdk's Command.Dialog, and cmdk's root onKeyDown calls preventDefault() unconditionally for Enter and re-dispatches to the highlighted [cmdk-item]. That cancels native button activation for every button inside the dialog.

Symptoms fixed:

  1. Enter on the "Create configuration" button (or in the empty search input) silently selected the auto-highlighted Base configuration scope and closed the modal, switching the active scope as a side effect.
  2. Enter on a role/group button in the creation view did nothing (mouse-only).
  3. The per-scope delete button was not operable via Enter.
  4. Enter did nothing in the delete confirmation view.

Fixes, two shapes for one cause: the creation view and the delete confirmation use no cmdk features, so they moved out of Command.Dialog into click-ui Dialog/Dialog.Content (house pattern from DeleteProfileValueModal; the confirmation autofocuses its Delete button). For buttons that remain inside the cmdk root (Create, per-scope delete), Enter/Space keydowns stop propagation so native activation proceeds while cmdk never sees the key. The search input additionally stops Enter only while empty and unnavigated, so Enter-to-select after filtering or arrow navigation is unchanged.

Also: the icon-only back button in the creation view gained an aria-label (new com_ui_back key), and @testing-library/user-event was added as a devDependency for the new tests.

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

7 new Vitest cases (real click-ui and cmdk, server layer mocked); 6 fail against the unfixed component: Enter on Create opens the creation view without selecting/closing; Enter in the empty search does not select the Base scope; Enter on a role button creates the configuration; Enter on a delete button opens the confirmation without selecting; Enter on Delete deletes exactly once; Enter on Cancel returns without deleting; arrow navigation plus Enter still selects a scope.

Manually verified in the app: full keyboard-only pass through create, select, and delete flows.

Behavioral proof: 6 of the 7 new Enter-key cases fail against the unfixed component and pass with this change, driven by real keyboard events via user-event.

Test Configuration:

  • bunx tsc --noEmit, bunx eslint src/ --max-warnings 0, bunx vitest run (806/806), bun run build: all green
  • Local dev server against local LibreChat backend

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

The whole selector rendered inside cmdk's Command.Dialog, whose root keydown handler calls preventDefault on every Enter press and redispatches it to the aria-selected item. preventDefault cancels native button activation, so Enter did nothing on any button, and in the list view the redispatch activated the auto-highlighted first item. Since that item is Base configuration, pressing Enter on the Create button or in the empty search input silently switched the active scope to Base and closed the dialog, discarding the user's scope context.

The creation and delete confirmation views contain no cmdk items or input, so they now render in a plain click-ui Dialog with Dialog.Content, dropping the VisuallyHidden title and description shims and letting buttons activate natively. The delete confirmation focuses the Delete button on open and keeps Escape and overlay dismissal closing the whole selector as before, while Cancel returns to the list view.

The list view keeps cmdk for search and arrow navigation. The Create button and the per-scope delete buttons stop propagation of Enter and Space in their own keydown handlers, so native activation proceeds and the key never reaches the Command root. Enter in the search input is only forwarded to cmdk after the user has typed a query or navigated with the keyboard, which removes the silent switch to Base while preserving Enter-to-select on real list items.

Adds jsdom regression tests covering all four Enter paths plus arrow navigation, using the real click-ui and cmdk packages with only the server layer mocked, and adds @testing-library/user-event as a dev dependency.
@dustinhealy dustinhealy changed the title 🐛 fix: Make Scope Selector Operable with the Enter Key ⌨️ fix: Make Scope Selector Operable with the Enter Key Aug 11, 2026
@dustinhealy
dustinhealy marked this pull request as ready for review August 11, 2026 23:01

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 385730e. Configure here.

if (e.key === 'Enter' && search === '' && !navigatedRef.current) e.stopPropagation();
},
[search],
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty Enter ignores mouse highlight

Medium Severity

handleSearchKeyDown treats only keyboard navigation as an explicit highlight via navigatedRef. cmdk also moves the highlight on pointer hover, so Enter in an empty search after hovering a non-Base scope is stopped and never selects, regressing normal cmdk mouse-then-Enter selection.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 385730e. Configure here.

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.

1 participant