Usage
Command Menu lets users navigate and act in an app without touching the mouse, helping them become power users who reach advanced features faster. It is the familiar Ctrl/⌘+K palette: a searchable list of commands grouped into sections.
Commands are supplied as data through the commands property — an array of objects — rather than as markup. Open the menu programmatically with show() (typically from a global keyboard shortcut), and run a command from its handler.
import "@nordhealth/components/lib/CommandMenu"
import "@nordhealth/components/lib/CommandMenuAction"
Set the commands array and open the menu from a button:
Composition
Command Menu renders its own UI from the commands data: the search input, the grouped list, and a footer of keyboard hints. Each command in the array is rendered as a Command Menu Action row, so you don't author those elements yourself.
CommandMenu
├── Search input
├── List of sections
│ └── CommandMenuAction (one per command object)
└── Footer (keyboard hints, slot="footer" to override)
Each command object has the following shape:
{
id: "patient", // unique identifier
title: "New patient", // visible label
section: "Commands", // optional group heading
keywords: "new create", // optional extra search terms
shortcut: "Alt+KeyP", // optional keyboard shortcut
icon: "interface-add", // optional Nordicon name
parent: null, // optional id of a parent command (for nested views)
handler: (menu) => {}, // run when the command is selected
}
Command Menu Action
Command Menu Action is the internal part that displays a single command — its icon, title, and shortcut — and the selected state as the user moves through the list. It is created for you from each entry in the commands array, so it is not authored directly in markup; you describe each action through its command object instead.
Examples
Sections
Group related commands by giving them a section. Commands without a section appear ungrouped at the top of the list.
Nested commands
Give a command a parent matching another command's id to nest it. Selecting the parent reveals its children in a focused sub-view — useful for grouped choices like switching theme.
External filtering
Add external-filtering to turn off the built-in text matching so you can run your own search — for example, querying a server. Read the typed text from the searchQuery property on the input event and reassign commands with your filtered results.
Preventing open
The menu fires an open event before it opens. Call preventDefault() on it to keep the menu closed — handy for gating access behind a permission or condition.
Without sections
Omit the section from every command to render a single flat list — useful for short menus where grouping adds no value.
Without custom icons
Commands render fine without icons. Leave the icon off to keep the list text-only and compact.
Exit nested view on search
When the user is inside a nested command view, typing a search query returns them to the top level so the search runs across all commands rather than just the children.
RTL
The Command Menu follows the document or container direction. Toggle the direction to see the layout mirror.
Accessibility
- The Command Menu is modal: it traps focus while open, moves focus to its search input, and returns focus to the previously focused element when it closes.
- It implements the full keyboard pattern — arrow keys move through commands, Enter runs the selected one, Backspace exits a nested view, and Esc closes the menu — with the active command tracked for assistive technology.
- Each command's
shortcutis shown in its row and described in the footer, so keyboard users can discover and learn the shortcuts. - Give every command a meaningful
title; it is the command's accessible name in the list.
API reference
CommandMenu
Command Menu allows users to navigate and use an app without touching the mouse and helps them transform into “power users” who can harness more advanced features far faster.
<nord-command-menu></nord-command-menu>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
open | open | Show or hide the command menu. | boolean | false |
externalFiltering | external-filtering | Use external filtering mode. When set to true, the component will not perform internal text-based filtering and expects external filtering logic to be implemented. | boolean | false |
exitNestedOnSearch | exit-nested-on-search | When enabled, typing in the search input will automatically exit nested views to allow global search across all commands. | boolean | false |
Slots
| Slot name | Description |
|---|---|
footer | Used to replace the default footer contents. |
Methods
| Method name | Parameters | Description |
|---|---|---|
show(options: { parent?: string }, options.parent: unknown) => void | options: Options for showing the menu.options.parent: Opens the menu filtered to a specific parent command. | Show the command menu programmatically. |
close() => void | N/A | Close the command menu programmatically. |
focus() => void | N/A | Focus the command menu's input. |
| Event | Detail Type | Description |
|---|---|---|
open | NordEvent | The command menu was opened. |
close | NordEvent | The command menu was closed. |
input | NordEvent | Fired as the user types into the search input. |
nord-select | SelectEvent | User selected a command from the menu. |
CSS Properties
CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.
| Property | Description | Default |
|---|---|---|
--n-command-menu-inline-size | Controls the max inline size, or width, of the command menu. | 640px |
--n-command-menu-block-size | Controls the max block size, or height, of the command menu. | 290px |
--n-command-menu-block-start | Controls the command menu offset from the block start, or top, of the screen. | 16% |
Parts
This component is made up of the following parts.
Command Menu Action
Command Menu Action displays a single action that can be executed by the user. For usage examples, please see Command Menu component.
<nord-command-menu-action></nord-command-menu-action>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
command | command | ICommandMenuAction | — | |
selected | selected | boolean | false |
Dependencies
This component is internally dependent on the following components:
- <nord-icon>
Icon
Icons are used to provide additional meaning or in places where text label doesn’t fit. Icon component allows you to display an icon from the Nordicons library.
- <nord-visually-hidden>
VisuallyHidden
Visually hidden is used when an element needs to be available to assistive technologies like screen readers, but be otherwise hidden.
Design guidelinesFor designers
Usage
This section includes guidelines for designers and developers about the usage of this component in different contexts.
Do
- Use to provide global and contextual keyboard shortcuts for users.
- Make command menu available everywhere. Users must be able to bring up the command menu easily.
- Make command menu central. Users should be able to find global shortcuts from one location.
- Make command menu omnipotent. Give users access to every possible action.
- Group related commands logically under sections with the section setting.
- Use
Altkey as the modifier, since this is less likely to clash with existing shortcuts.
Don’t
- Don’t make command menu available only in certain views of the application.
- Don’t define shortcuts such as
Ctrl+C, since this will clash with the native "Copy" shortcut. - Don't create complex shortcuts, as users will struggle to remember them.
- Avoid using
KeyboardEvent.keyfor defining the shortcut keys. - Don’t use as a search field only.
Content guidelines
Command titles should be clear, accurate and predictable. It should be possible for the user to understand what will happen when they execute a command:
Always lead with a strong verb that encourages action. To provide enough context to user, use the {verb} + {noun} content formula:
When writing command titles, always write them in sentence case, not title case. The first word should be capitalized and the rest lowercase (unless a proper noun):
Avoid unnecessary words and articles in command titles, such as “the”, “an” or “a”:
Avoid ending in punctuation:
Use ellipsis in the title when describing sections that have commands grouped inside of them:
Commands data
Each command in the commands data array must include at least an id and title. A command may also include properties for section, icon, handler, shortcut, forceShortcut, parent, and keywords:
| Name | Purpose |
|---|---|
id | An identifier for each command, must be unique. Example: id: "user". |
title | The title shown to users. This is used when searching for a command. Example: title: "Change theme...". |
keywords | Not visible in the user interface, but can make it easier to discover commands through search. Example: keywords: "command change log sign out in". |
shortcut | The keyboard shortcut. Example: shortcut: "Alt+KeyU". See the sections Defining Shortcuts and Choosing shortcuts below for more information. |
forceShortcut | Set to true to let the command override a browser-reserved shortcut (the menu calls preventDefault() for it). Off by default. See Browser-reserved shortcuts. Example: forceShortcut: true. |
section | Used for grouping many commands under a common header. Example: section: "Commands". |
icon | A name of an icon form Nordicons to show beside the title. If not specified, default command icon will be used instead. Example: icon: "file-picture". |
parent | The id of a parent command. This is used for nesting commands. Example: parent: "theme". |
handler | A function to execute when an user triggers a command. Example: handler: () => { alert("Change to light theme") }. In cases where a command is only used as a parent command e.g. "Change theme", this is not required. |
Defining shortcuts
Shortcuts in the Command Menu have the following form: [modifier]+[key]. Shortcuts are made up of a sequence of presses. A press can be as simple as a single key which matches against KeyboardEvent.code:
// Matches: event.code:
'KeyD'
Presses can optionally be prefixed with modifiers which match against any valid value to KeyboardEvent.getModifierState().
'Control+KeyD'
'Meta+KeyD'
'Shift+KeyD'
'Alt+KeyD'
'Meta+Shift+KeyD'
There is also a special $mod modifier that makes it easy to support cross platform keybindings:
- Mac:
$mod=Meta(⌘) - Windows/Linux:
$mod=Control
'$mod+KeyD' // ⌘/Ctrl + D
'$mod+Shift+KeyD' // ⌘/Ctrl + Shift + D
The Command Menu itself can be opened using ⌘+k (or Ctrl+k on Windows) and closed by hitting Esc. These are both non-configurable shortcuts in order to unify the experience across our platforms.
Choosing shortcuts
When choosing shortcuts, it is very important that they do not clash with native operating system or browser shortcuts.
For example, you should not define a shortcut like $mod+KeyC, since this will clash with the native “Copy” shortcut, and will be triggered every time a user copies text in the app. Nor should you use shortcuts like Shift+KeyA since this will get triggered whenever a user types an uppercase “A” character. Therefore, special care and attention must be given to each and every shortcut choice.
In general, we recommend using the Alt modifier, since this is less likely to clash with existing shortcuts. However, be aware, the Alt key is also used for accented characters e.g. Alt+KeyA produces the letter “å”. Again, it is crucial that you choose shortcuts carefully.
Browser-reserved shortcuts
Some key combinations are reserved by the browser or operating system and are unsafe to use as a command shortcut. By default a command's handler runs but the browser's own action runs too, so a reserved combo (for example Alt+KeyD) will still focus the address bar. Avoid the following:
| Combination | Reserved for | Reclaimable? |
|---|---|---|
Alt+KeyD | Focus the browser address bar | Yes, with forceShortcut |
$mod+KeyL (Ctrl+L / Cmd+L) | Focus the browser address bar | Yes, with forceShortcut |
Alt+Home | Navigate to the browser home page | No — intercepted before the page |
Alt+F4 | Close the current window (Windows) | No — handled by the OS |
If you knowingly want a command to take over a reclaimable reserved combo, set forceShortcut: true on that command — the Command Menu then calls event.preventDefault() so the browser default does not run:
({
id: 'dashboard',
title: 'Go to dashboard',
shortcut: 'Alt+KeyD',
forceShortcut: true, // opt in to reclaim Alt+D from the browser
handler: () => {
// navigate to the dashboard
},
})
This is opt-in so command shortcuts never silently override browser or OS keys. Even so, reusing a reserved combo will surprise users who expect the address bar, so prefer a different combination where you can. Alt+Home and Alt+F4 are intercepted before the page receives the event and cannot be reclaimed even with forceShortcut.
You should strive to choose shortcuts that are intuitive and easy to remember. The more complex a shortcut, the less likely a user is to remember it. Of course, a user can still find a command by searching the command menu, and for some users this may be their preferred way of triggering commands.
Common keybindings
Keybindings will be matched against KeyboardEvent.key and KeyboardEvent.code which may have some names you don’t expect. Please note that we recommend always using KeyboardEvent.code for defining the keys and only using KeyboardEvent.key for defining modifiers.
| Windows | macOS | key | code |
|---|---|---|---|
| N/A | Command / ⌘ | Meta | MetaLeft / MetaRight |
Alt | Option / ⌥ | Alt | AltLeft / AltRight |
Control | Control / ^ | Control | ControlLeft / ControlRight |
Shift | Shift | Shift | ShiftLeft / ShiftRight |
Space | Space | N/A | Space |
Enter | Return | Enter | Enter |
Esc | Esc | Escape | Escape |
1, 2, etc | 1, 2, etc | 1, 2, etc | Digit1, Digit2, etc |
a, b, etc | a, b, etc | a, b, etc | KeyA, KeyB, etc |
- | - | - | Minus |
= | = | = | Equal |
+ | + | + | Equal* |
In addition to the above table, you can use https://keycode.info/ for checking the specific values needed. Note that some keys will have the same code as others because they appear on the same key on the keyboard. Keep in mind how this is affected by international keyboards which may have different layouts.
Navigating with the command menu
- Use
Ctrl+K(Windows/Linux) orCmd+K(Mac) to open the command menu. - Start typing the command you want to execute. The suggestions in the command menu change to match your text.
- Finish entering the name, or use the arrow keys to highlight the command you want from the list of suggestions.
- Use
Enterto execute the chosen command. - If you chose a command that has nested commands, you can use
Backspaceto return to the previous menu. - When the command menu is active, you can use one of the following keyboard shortcuts to close it:
Esc,Ctrl+K(Windows and Linux) orCmd+K(Mac).