# Command palette

The ⌘K dialog that filters every screen as you type and goes to the lit one with Enter.

The palette is a modal dialog with a filter field over one link row per nav item that has an address, each marked data-command. The top bar's search pill opens it without script, and every row is a plain link. The base island adds ⌘K, Ctrl+K and / (when no field has focus) to open it, filtering as you type, the arrow keys to move the lit row and Enter to follow it; Esc closes it.

## Use it

Web:

```rust
use ocean_ui_web::{Island, Page};
Page { shell: &shell, nav_hrefs: &[("tickets", "/tickets"), ("people", "/people")], title: "Tickets", island: Island::Auto }.render_parts(|out| out.push_str("…"))
```

Native:

```rust
use ocean_ui_native::shell::Palette;
Palette::toggle(ui.ctx());
Palette::show(ui.ctx(), &mut reg);
```

Cargo feature `shell`; since 2026-10-29.

## Props

| Name | Type | Default | What |
|---|---|---|---|
| `nav` | `Vec<NavItem>` | `—` | The Shell's rows; each one with an address becomes a row of its icon and label. |
| `nav_hrefs` | `&[(&'static str, &'static str)]` | `—` | Page's map from a row's id to its address; a row it does not name is left out. |
| `island` | `Island` | `—` | Page's island build, Base, Live or Auto, which loads base for these rows; without one the palette opens and links but does not filter. |

On the Mac: ![Command palette, dark](/ui/native/palette-dark.png) ![Command palette, light](/ui/native/palette-light.png)

## Examples

### Every screen

Shown open here; on a page ⌘K, Ctrl+K, / or the search pill opens it.

```rust
let shell = Shell {
    app_name: "Service desk",
    version: "0.8.8".into(),
    nav: nav(),
    here: "queue",
    crumb: vec![
        Crumb { text: "Service desk".into(), href: Some("#queue".into()) },
        Crumb { text: "Queue".into(), href: None },
    ],
    title: "Queue".into(),
    sub: Some("Every ticket open now".into()),
    actions: vec![Button::new("Build an agent", Variant::Solid).href("#build")],
    status: None,
};
out.push_str(&page(&shell));
```

### Two screens

The palette lists what the sidebar lists.

```rust
let shell = Shell { nav: nav().into_iter().take(2).collect(),..desk() };
out.push_str(&page(&shell));
```

### One screen

Even a one-screen app answers ⌘K.

```rust
let shell = Shell { nav: nav().into_iter().take(1).collect(),..desk() };
out.push_str(&page(&shell));
```

## Accessibility

- The dialog is labelled by its Search title, and its field by a visually hidden label, Go to a screen.
- The field is a text field, not a search field, so Esc closes the dialog instead of clearing it.
- The arrow keys light a row with aria-selected, and a line says Nothing matches when no row does.

## Related

- [Dialog](/ui/components/dialog.md)
- [Sidebar](/ui/components/sidebar.md)
- [Top bar](/ui/components/topbar.md)
- [Keyboard shortcut](/ui/components/kbd.md)
