Installation
Theme
Mode

Forms & input

Slash menu

Type / in a field and an inline command menu appears at the caret — insert a heading, a list, a mention, a date, or set status without leaving the keyboard. The Notion-style shortcut that makes a text field do far more than text.

$npx shadcn@latest add @orbit/slash-menu

Overview

Live — click into the field and press /. Keep typing to filter (try /men), ↑↓ to move, Enter to insert.

DescriptionType / for commands
Try /h1 /mention /status

last inserted:

Capabilities

One key turns a plain field into a command surface — formatting and data insertion without reaching for a toolbar.

Opens at the caret

The menu anchors exactly where you’re typing, so the command list never covers what you’re writing.

Filters as you type

Keep typing after the slash — /men narrows to Mention. The query lives in the text and clears on insert.

Inserts rich tokens

Mentions, dates and statuses drop in as styled chips, not plain text — so the field carries real structured data.

Keyboard-first

Arrows move the highlight, Enter inserts, Escape dismisses without touching your text. Hands stay home.

Custom commands

Pass your own groups through commands — each item declares its icon, description, extra filter keywords, and whether it inserts a styled chip or plain text. Here “/urgent” finds Priority via keywords.

Triage noteType / for commands

Props

PropTypeDefaultDescription
commandsSlashCommandGroup[]DEFAULT_SLASH_COMMANDSGrouped commands: { label, items }. Groups keep their order while the filter drops non-matching items.
labelstring"Description"Uppercase field label; also the editable’s accessible name.
placeholderstring"Write something, or press / to insert…"Empty-state placeholder inside the editable.
onSelect(command: SlashCommand) => voidCalled after a command inserts (chip or text) and the menu closes.
showFooterbooleantrueThe “Try /h1 /mention /status” hint row with the Clear button.
showToastbooleantrueFlash a “… inserted” toast under the card after each insert.
…restHTMLAttributes<HTMLDivElement>Everything else is forwarded to the root wrapper, including ref.
PropTypeDefaultDescription
SlashCommand.idstringUnique id — also matched by the filter, so /men hits “mention”.
SlashCommand.titlestringRow title; the filter matches it.
SlashCommand.descriptionstringSecondary line under the title.
SlashCommand.iconReactNode17px glyph shown in a 30px tile, drawn with currentColor.
SlashCommand.kbdstringTrailing markdown-shorthand hint — e.g. “#”, “-”, “```”.
SlashCommand.keywordsstring[]Extra filter terms that aren’t visible on the row.
SlashCommand.chipstringInsert this label as a styled, non-editable chip token.
SlashCommand.textstringInsert this plain text at the caret (when chip isn’t set).
PropTypeDefaultDescription
useSlashMenu(options)hookThe behavior layer for custom surfaces: pass { editorRef, commands, onSelect } and wire the returned onInput / onKeyDown to your own editable; it hands back open state, the filtered list, the highlight, the caret position, and pick().
<SlashMenuPopup menu={…} />componentThe caret-anchored listbox, purely presentational — render it inside a relative wrapper around your editable and feed it the hook’s return value. Optional heading and emptyMessage props relabel the header and no-match text (the Markdown Editor reuses it this way for @ mentions).

Usage

A slash menu is an accelerator inside a field. For app-wide actions use the Command Palette; for fixed formatting, the Markdown Editor’s toolbar is the discoverable path.

Do

Group and label commands

Basic blocks, then inserts. A short labelled list is faster to scan than one long alphabetical run.

Don’t

Hide it as the only path

Pair the slash menu with a visible toolbar. New users won’t guess that “/” does anything.

Do

Echo markdown shorthands

Show that /h1 equals “# ”. It teaches the even-faster inline syntax for the commands people use most.

Don’t

Leave the “/” behind

On insert, remove the slash and its query from the text. A stray “/men” left in the field is a bug people notice.

Keyboard & accessibility

The editable keeps focus the whole time — the popup is a role=listbox the field controls: aria-haspopup and aria-expanded on the textbox, aria-activedescendant tracking the highlighted option, and mouse picks on mousedown so the caret never moves. Escape closes without changing the text.

/Open the command menu at the caret
TypeFilter the commands after the slash
↑ ↓Move the highlight
Insert the highlighted command
EscDismiss without touching the text