Skip to content

fix(editor): run the slash command that was clicked - #3747

Merged
felipefreitag merged 2 commits into
resend:canaryfrom
kaanisthatyou:fix/slash-command-grouped-index
Oct 2, 2026
Merged

felipefreitag merged 2 commits into
resend:canaryfrom
kaanisthatyou:fix/slash-command-grouped-index

Conversation

@kaanisthatyou

@kaanisthatyou kaanisthatyou commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Closes #3746.

Problem

With no query typed, the slash command menu can run a different item's command than the one clicked or highlighted. Using the docs' own custom commands example (an Image item with category: 'Media' appended to defaultSlashCommands), the menu shows Text → Media → Layout, but clicking Image inserts a Button, and arrow keys highlight one row while Enter runs another.

Root cause

The two sides numbered the rows differently.

  • ui/slash-command/command-list.tsx reorders the items for display: groupByCategory pulls the categories in CATEGORY_ORDER to the front, everything else follows in first-seen order. Each row then called onSelect(flatIndex) — its position in the grouped display order — and highlighted itself with the same number.
  • ui/slash-command/root.tsx resolves both onSelect and the Enter handler against suggestionItemsRef.current[index], i.e. the original, unordered array, and the arrow keys walk that same array.

As long as the array happens to be in CATEGORY_ORDER the two orders agree, which is why the built-in commands don't show it. Any other order — a custom category, a translated one, or a command appended at the end — shifts every row after the first group. With a query typed the list is rendered flat, so it works.

Change

  • command-list.tsx: groupByCategory now carries each item's index in the list the root holds, and the rows use that index for both onSelect and data-selected, instead of counting display positions. No flatIndex counter.
  • command-list.tsx: exports orderItemsByCategory, the same grouping flattened back into a list.
  • root.tsx: defaultFilterItems returns the items in that display order when there is no query, so the arrow keys move down the list the way it is drawn instead of jumping between groups. With a query the list stays flat and ranked by score.

What I deliberately left alone

  • CATEGORY_ORDER itself, and the choice to group only when there is no query.
  • A custom filterItems still controls its own order — the index bookkeeping keeps clicks correct whatever order it returns, including categories interleaved in the array.
  • search.ts ranking is untouched.

Test

packages/editor/src/ui/slash-command/command-list.spec.tsx renders the menu with [Text (Text), Divider (Layout), Image (Media)] — display order Text → Media → Layout, array order Text → Layout → Media — and covers the click index, the highlighted row and orderItemsByCategory.

$ cd packages/editor && pnpm vitest run --project unit
 Test Files  53 passed (53)
      Tests  516 passed (516)

$ pnpm typecheck        # clean
$ pnpm biome check packages/editor/src/ui/slash-command   # clean

Before the fix, the new tests fail exactly the way the issue describes:

 × selects the clicked item and not the one in its display position
   AssertionError: expected "vi.fn()" to be called with arguments: [ 2 ]
   Received: 1                      // clicking Image selected Divider
 × highlights the item the index points at
   AssertionError: expected 'Divider' to contain 'Image'

🤖 Generated with Claude Code

https://claude.ai/code/session_011Yyp6p2GWzkWKLsrxxJR1U


Summary by cubic

Fixes the slash command menu running a different command than clicked and arrow keys landing on the wrong row when categories display out of array order — for example, a custom Image command appended after the defaults could insert a Button.

  • Rows resolve clicks and highlighting against the original item index, not their display position.
  • Sorts items into displayed category order in the root after filtering, only when the built-in list renders with no query, so arrow keys follow the drawn rows even with a custom filterItems.
  • Keeps custom children renderers receiving items in array order.
  • Exports orderItemsByCategory and adds unit tests for click, highlight, arrow-key, and renderer ordering.

Written for commit 16d5ff7. Summary will update on new commits.

Review in cubic

The grouped slash command list numbered its rows by display position while
the root resolved the selection against the unordered items array, so any
category order other than the array order ran a different item's command.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Yyp6p2GWzkWKLsrxxJR1U
@vercel

vercel Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

@kaanisthatyou is attempting to deploy a commit to the resend Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot

changeset-bot Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 16d5ff7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@react-email/editor Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added the linear-synced PR has been synced to Linear label Sep 18, 2026
Sort the items into category order in the root, after any filter, and
only when the built-in list renders with no query. Before, the sort ran
inside the default filter. A custom filterItems then made the arrow keys
skip rows, and a custom children renderer got items in a new order.

Add root tests for the arrow-key order with the default and a custom
filter, Enter on the highlighted row, and the order children receive.
@felipefreitag

Copy link
Copy Markdown
Member

Thanks for this. There was a issue where navigating with the keyboard on a custom list made the cursor jump around, I pushed a commit to fix it.

@pkg-pr-new

pkg-pr-new Bot commented Oct 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@react-email/editor@3747

commit: 16d5ff7

@kaanisthatyou

Copy link
Copy Markdown
Contributor Author

Thanks for catching that. I pulled 16d5ff7 and the editor unit tests pass locally (520/520).

@felipefreitag
felipefreitag merged commit 7d6ec3c into resend:canary Oct 2, 2026
8 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

linear-synced PR has been synced to Linear

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[editor] Slash command runs the wrong command when category groups are displayed out of array order

2 participants