Skip to main content

PromptInputSlash

Composerai

The slash-command palette over a composer — type /, filter by prefix, pick a command with the keyboard.

import { PromptInputSlash } from "@elabs-ai/components-ai";
Install
npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-ai

Skipping the @source line is the most common first failure: Tailwind does not scan node_modules, so every component renders unstyled. The one-time wiring

Prompt for your coding agent

Paste it into Claude Code, Cursor, Codex or any other coding agent. Text in [brackets] is yours to fill in.

Add the brand-ui PromptInputSlash component (from @elabs-ai/components-ai) to this project.

1. Read https://elabs-ai.com/llms.txt first: it maps every package and the rules. If you can use MCP servers, connect https://elabs-ai.com/mcp and use its search, docs and tokens tools. If not, run the same lookups in the terminal: `npx -y @elabs-ai/components-cli search "<what you need>"` and `npx -y @elabs-ai/components-cli docs <Component>`.
2. Look PromptInputSlash up before writing code: `npx -y @elabs-ai/components-cli docs PromptInputSlash` prints its real props, variants, what it pairs with and what to avoid.
3. If @elabs-ai/components-ai is not installed yet: `pnpm add @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-ai` (or `npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-ai`). If this is the first brand-ui package in the project, wire it once: import `@elabs-ai/components-tokens/styles.css` plus the `themes/light.css` and `themes/dark.css` stylesheets in the CSS entry, add one Tailwind `@source` line per installed @elabs-ai package (Tailwind does not scan node_modules, so without it everything renders unstyled), and wrap the app root in `ThemeProvider` from `@elabs-ai/components-tokens`.
4. Use it here: [the screen or file, and what it should show]
5. Rules: use only @elabs-ai/components-* components and the semantic tokens — no raw colours, no raw font sizes, no arbitrary Tailwind values. Look up each component's real props with the docs tool before you use it; never guess a prop.
6. Done means: the typecheck passes, `npx -y @elabs-ai/components-cli audit src --strict` reports nothing, and you have opened the app and looked at every screen you touched in the light and the dark theme.

Avoid

  • Moving DOM focus into the list — the textarea keeps focus and points at the active option with aria-activedescendant; a palette that steals focus loses the caret.
  • Passing aria-label or id to the command list — cmdk overwrites both; use its own `label` prop and read the rendered id back off the node.
  • Leaving aria-activedescendant set after the palette closes — a stale id points at a node that no longer exists.
  • Hand-rolling the trigger scan — the caret/trigger machinery is shared with MentionInput (findTriggerQuery in @elabs-ai/components-ui), not re-derived here.
  • Submitting the composer on Enter while the palette is open — Enter selects the command; the textarea's own onKeyDown-before-submit order is what makes that possible.

PromptInputSlash — a /-triggered slash-command palette for the composer. Typing / at the START of a line (never mid-word) opens a filtered listbox of app-defined commands; arrow keys move the highlight, Enter/Tab inserts /name , Escape dismisses — and, like MentionInput, focus never leaves the textarea. Ships no command vocabulary of its own; commands is entirely prop-driven.

Works with

Contains

  • PromptInputSlashTextarea
  • PromptInputCommand
  • PromptInputCommandList
  • PromptInputCommandItem

Examples

7 live examples

Palette Open

Typing `/` at the start of the line opens the palette; arrow keys move the highlight without ever moving focus off the textarea.

Not Mid Word

Typing `/` mid-word (not at the start of a line) never opens the palette — the acceptance test for the line-start boundary.

Narrowing Clamps The Highlight

Narrowing the query clamps the highlighted option into the filtered list — it can never point at an option that has scrolled out of the results.

Select With Enter

Enter inserts the highlighted command and closes the palette.

Close With Escape

Escape closes the palette and returns focus to the textarea.

No Matches

No commands match the typed query — the empty state renders in the listbox. Ends by dismissing the palette: `cmdk`'s empty state is a bare `role="presentation"` node with no `option`/`group` children, which is a pre-existing `aria-required-children` shape shared by every cmdk-based combobox in this repo (already baselined for `overlays-command--groups`) — closing the palette before the story's axe pass avoids re-asserting that same, already-accepted primitive limitation here too.

API

PromptInputSlash

PropTypeDescription
commandsrequiredSlashCommand[]The registered commands the palette offers.
valuerequiredstringThe composer's current text — must match what the wrapped textarea renders.
textareaRefrequiredRefObject<HTMLTextAreaElement | null>Ref to the composer's `<textarea>` (usually the one `PromptInputSlashTextarea` renders).
lineStartOnlybooleanOnly trigger at the start of a line (index 0, or right after `"\n"`). `false` falls back to `MentionInput`'s word-boundary rule. @default true
filter(command: SlashCommand, query: string) => booleanWhich commands survive the current query. @default defaultSlashCommandFilter
onValueChangerequired(next: { text: string; caret: number }) => voidA command was chosen — apply the spliced `{ text, caret }` to your own controlled value (the same shape `replaceTriggerRun` returns). The splice inserts `"/" + command.name + " "` in place of the typed query.
onSelect(command: SlashCommand) => voidA command was chosen (fires alongside, not instead of, `onValueChange`).
onOpenChange(open: boolean) => voidThe popup opened or closed.
childrenrequiredReactNode

Also accepts: Omit< HTMLAttributes<HTMLDivElement>, "onSelect" | "children" >

PromptInputSlashTextarea

Also accepts: PromptInputTextareaProps

PromptInputCommand

Also accepts: ComponentProps<typeof Command>

PromptInputCommandList

Also accepts: ComponentProps<typeof CommandList>

PromptInputCommandItem

Also accepts: ComponentProps<typeof CommandItem>

Theming

The tokens each state resolves to. Change the token and every theme follows.

StateToken
activethe highlighted command is reported to the textarea via aria-activedescendant — focus never leaves the input
emptya real empty state with a sentence, never a blank popover