# useCommandShortcut

A hook that runs a function when the user presses the command key or the control key with a letter.

```tsx
import * as React from 'react'
import { Button, CommandMenu, Kbd, toast, useCommandShortcut, useModKey, type CommandMenuGroup } from 'ferry-ui'
import { FolderKanban, Receipt, Users } from 'lucide-react'

const GROUPS: CommandMenuGroup[] = [
  {
    id: 'pages',
    label: 'Go to',
    items: [
      { id: 'projects', label: 'Projects', icon: <FolderKanban />, onSelect: () => toast('Projects') },
      { id: 'members', label: 'Members', icon: <Users />, onSelect: () => toast('Members') },
      { id: 'invoices', label: 'Invoices', icon: <Receipt />, onSelect: () => toast('Invoices') },
    ],
  },
]

export default function UseCommandShortcutHero() {
  const [open, setOpen] = React.useState(false)
  const mod = useModKey()
  // The letter J: this site already binds the letter K to its search.
  useCommandShortcut(() => setOpen((current) => !current), 'j')
  return (
    <>
      <Button onClick={() => setOpen(true)}>
        Open the menu <Kbd>{mod} J</Kbd>
      </Button>
      <CommandMenu open={open} onOpenChange={setOpen} groups={GROUPS} />
    </>
  )
}
```

## Usage

Call the hook one time, near the root of the app. Put it next to the state of your [Command Menu](/docs/components/command-menu). With no second argument, the shortcut is <Kbd>⌘ K</Kbd> on an Apple device and <Kbd>Ctrl K</Kbd> on other devices.

```tsx

  const [open, setOpen] = React.useState(false)
  useCommandShortcut(() => setOpen((current) => !current))
  return <CommandMenu open={open} onOpenChange={setOpen} groups={groups} />
}
```

- **The shortcut works in the full window.** It also works when the focus is in a text field.
- **The browser does not get the shortcut.** The hook stops the default action of the browser.
- **The modifier keys matter.** The hook ignores a press with <Kbd>Shift</Kbd> or <Kbd>Alt</Kbd>.
- **The hook shows no key.** To show the keys, use [Kbd](/docs/components/kbd) with `useModKey()` from [usePlatform](/docs/utilities/use-platform).
- **Not for one widget.** For a shortcut that works only in one widget, use `onKeyDown` on this widget.

<Callout tone="warning" title="Bind each letter in one place">
  [App Shell](/docs/components/app-shell) calls this hook for its `onCommandShortcut` prop. `CommandMenu` calls it for its `shortcut` prop. Use only one of the three for a letter. If not, each press runs more than one handler.
</Callout>

## Examples

### Another letter

Pass a letter as the second argument. The case of the letter does not matter. For two letters, call the hook two times.

```tsx
useCommandShortcut(openInvoiceSearch, 'j')
```

### Shortcut on and off

Pass an object with `enabled`. While `enabled` is `false`, the hook does not listen.

```tsx
import * as React from 'react'
import { Kbd, Label, Switch, useCommandShortcut, useModKey } from 'ferry-ui'

export default function UseCommandShortcutEnabled() {
  const [enabled, setEnabled] = React.useState(true)
  const [count, setCount] = React.useState(0)
  const mod = useModKey()
  // The hook listens only while `enabled` is true.
  useCommandShortcut(() => setCount((current) => current + 1), { key: 'u', enabled })
  return (
    <div className="flex flex-col items-center gap-4">
      <p className="flex items-center gap-2 text-sm text-foreground-light">
        Press <Kbd>{mod} U</Kbd>
        <span className="text-foreground tabular">Presses: {count}</span>
      </p>
      <div className="flex items-center gap-2">
        <Switch id="shortcut-enabled" checked={enabled} onCheckedChange={setEnabled} />
        <Label htmlFor="shortcut-enabled">Shortcut enabled</Label>
      </div>
    </div>
  )
}
```

## API reference

`useCommandShortcut(handler, options)` returns nothing.

| Parameter | Type | Role |
| --- | --- | --- |
| `handler` | `(event: KeyboardEvent) => void` | Runs on each press. The hook always calls the latest function. |
| `options` | `string \| CommandShortcutOptions` | Optional. A letter, or an object with the options below. |

| Option | Type | Default | Role |
| --- | --- | --- | --- |
| `key` | `string` | `'k'` | The letter of the shortcut. |
| `enabled` | `boolean` | `true` | The hook listens only while the value is `true`. |
