Skip to content
HooksPro

useMenuKeys

Arrow keys, Enter and Escape for a menu that opens from a text field.

For a list that opens under a prompt, such as slash commands or mentions, while focus stays in the textarea. Returns the highlighted , a setter, and an handler for the textarea.

See alsoSlash Command Menu

Import

tsx
import { useMenuKeys } from "@wunderui/react"

Comes with WunderUI Core and Pro, in the package from your plan. See the plans.

Signature

ts
useMenuKeys(count: number, options: { open: boolean; onEnter: (index: number) => void; onEscape?: () => void; }): { index: number; setIndex: React.Dispatch<React.SetStateAction<number>>; onKeyDown: (e: React.KeyboardEvent) => void; }

Parameters

ParameterType
countnumber
options.openboolean
options.onEnter(index: number) => void
options.onEscape?(() => void) | undefined

Returns

FieldType
indexnumber
setIndexReact.Dispatch<React.SetStateAction<number>>
onKeyDown(e: React.KeyboardEvent) => void

Examples

Slash commands on a prompt

tsx
import * as React from "react"
import { useMenuKeys } from "@wunderui/react"

export function Prompt({ commands }: { commands: { id: string; label: string }[] }) {
  const [text, setText] = React.useState("")
  const open = text.startsWith("/")
  const keys = useMenuKeys(commands.length, {
    open,
    onEnter: (index) => setText(`${commands[index].label} `),
    onEscape: () => setText(""),
  })
  return <textarea value={text} onChange={(e) => setText(e.target.value)} onKeyDown={keys.onKeyDown} />
}

Notes

  • The keys only act while is true and the list has items; otherwise typing is untouched.
  • The index goes back to the first item when the list opens or its length changes.
  • An Enter that confirms an IME composition (Japanese, Chinese input) belongs to the composition, not the menu.
  • Shift+Enter is left alone, so it can still add a line break.