Skip to content

Command palette

Press ⌘K on a Mac, or Ctrl+K on Windows and Linux, to search WerkOS from any screen. It lists the modules before you type, and from the second letter it finds projects, jobs, candidates and files.

Before and after you type

Global Projects
Local Projects
Job Board
Candidates Leads
Companies
Contacts
Companies Leads
Activities
Werkcall
Email
Chat
Drive
Before you type: the modules you can open
Welders, shipyard in Split12 places, interviews from 6 October
Welders, shipyard in Rijeka8 places, visas in progress
MIG welder, SplitPublished, 34 applicants
Suman TamangWelder from Nepal, CV received
Rajesh KumarWelder from India, visa approved
Welding certificate, Suman Tamang.pdfDrive, Candidates
After typing weld: results grouped by where they live

Before you type, the palette lists the modules you can open, so it already works as a jump list. Once you type two letters, results arrive grouped by where they live: projects, jobs, candidates, files.

When to use it

Use the palette to reach a module or a record you can name, such as a candidate or a project, from wherever you are.

To narrow the list you are looking at, use the search field of that page, since the palette takes you away from it. The palette is a shortcut beside the rail and the modules panel: people who do not know a name still find things by looking.

Anatomy

A raised panel near the top of the screen holds the search field and, under it, a list that scrolls on its own. A row shows the name people know, with one line of context when two results could be confused. Group titles name the place. A module keeps its proper name, such as Global Projects, and any other title is in sentence case, such as Files.

Panel width
Up to 512 px
Distance from the top
12 percent of the window
Radius
16 px
--radius-2xl
Surface
Raised glass, no border
--glass-fill-raised
Backdrop
Dimmed, blurred 8 px
--overlay
Field row
52 px, 16 px glyph, 14 px text
Result row
40 px, 54 px with a second line
Row glyph
18 px, muted ink
--text-muted
Active row
Soft fill, 8 px radius
--glass-fill-hover
Group title
13 px, weight 500
--text-label
List height
Up to 60 percent of the window

States

One letter keeps the module list. From the second letter the palette searches after a short pause, and a newer query replaces an older answer.

While the first results load, gray rows hold their place. If nothing matches, the palette says so and repeats your words. If the search fails, it says so and offers to try again.

Search starts
At 2 characters
Pause before searching
120 ms
Loading
Four placeholder rows, a spinner at the end of the field
No results
No results for “crane operator”
--text-muted
Failed
Search did not finish. Try again
Loading

No results for “crane operator”

No results

Search did not finish.

The search did not finish

Keyboard and screen readers

The palette is a modal dialog. Its field owns the result list and announces the active row as you move, so a screen reader follows the highlight. A quiet status line reports how many results arrived.

⌘K or Ctrl+K
Opens or closes the palette from anywhere
Up and Down
Move the active row and keep it in view
Enter
Opens the active row
Escape
Closes the palette and returns focus to where it was

Permitted and not permitted

Permitted

  • The module list before the first letter

    The palette is useful the moment it opens.

  • Results grouped by where they live

    Global Projects, Job Board, Candidates Leads, Files.

Not permitted

  • A highlight only the eye can follow

    Announce the active row to screen readers as well.

  • An older answer after a newer query

    Discard any response that is no longer the latest.

  • A failed search shown as no results

    Say it did not finish, so people try again.

NextHuman and agent selector

Command palette

A modal search, opened with ⌘K or Ctrl+K from any WerkOS screen, that jumps to a module or a record.

  • Kind: component
  • Page: https://design.werklist.com/components/command-palette
  • Version: 2.1.2

When to use it

  • Reaching a module or a record by name from anywhere.
  • Before a letter is typed it lists the modules you can open, so it also serves as a jump list.

When not to use it

  • Narrowing the list on the current page: use that page's search field.
  • Commands that change data: actions stay in toolbars.
  • In place of the rail and the modules panel.

Anatomy

  • Layer: over the whole window, the panel 12 percent of the window from the top, 16 px from the sides (--layer-dialog)
  • Backdrop: dimmed and blurred 8 px. A click on it closes the palette (--overlay)
  • Panel: up to 512 px wide, radius 16 px, no border. In dark it adds the glass highlight and a 0.5 px ring, in light the shadow alone (--radius-2xl, --glass-fill-raised, --glass-shadow-raised, --glass-highlight, --glass-ring-raised)
  • Field row: 52 px, padding 12 px by 16 px, 16 px search glyph, gap 10 px, text 14 px, 16 px on a touch screen. A 16 px spinner at the end while a search runs (--text-muted)
  • Separator: 1 px under the field row, because the list scrolls beneath it (--border-rule)
  • List: up to 60 percent of the window high, padding 8 px, with its own scroll
  • Row: 40 px, padding 10 px by 12 px, radius 8 px, 18 px glyph in muted ink, gap 12 px, title 14 px (--radius-lg, --text, --text-muted)
  • Row with context: 54 px, padding 8 px by 12 px, second line 12 px on 18 px. Each line ends in an ellipsis when it is too long (--text-muted)
  • Group title: 13 px on 20 px, weight 500, padding 8 px 12 px 4 px (--text-label)
  • Placeholder rows: four rows 34 px high, 4 px apart, each an 18 px square and a 12 px bar at 70, 60, 50 and 40 percent, radius 4 px, pulsing (--glass-fill-hover, --radius-sm)

States

  • Empty query: Lists the modules you can open
  • One character: The module list stays
  • Searching: From 2 characters, after a 120 ms pause. The newest query wins. Four placeholder rows hold the place until the first results
  • Results: Grouped by where they live (--text-label)
  • No results: No results for “{query}”, with 40 px of padding (--text-muted)
  • Failed: Search did not finish, with a quiet Try again button
  • Active row: Soft fill, the same for pointer and keyboard, aria-selected true, kept in view (--glass-fill-hover)
  • Enter and exit: Fades in with a 12 px rise from a scale of 0.97, and leaves quicker than it came. With reduced motion it only fades

Keyboard

  • ⌘K (Mac), Ctrl+K (Windows, Linux): Opens or closes the palette
  • ArrowDown, ArrowUp: Moves the active row and keeps it in view. Stops at the first and the last row
  • Enter: Opens the active row
  • Escape: Closes the palette when it is the front layer. Focus returns to where it was
  • Tab: Stays inside the dialog

Accessibility

  • Panel: role dialog, aria-modal true, named Search.
  • Field: role combobox that controls the list and points to the active option with aria-activedescendant.
  • List: role listbox. Each group is named by its title, and each row is an option with aria-selected.
  • A polite live region says how many results arrived, or No results.
  • Group titles meet 4.5 to 1 on the panel, and muted ink meets 4.5 to 1 on the active row, in both themes.

Content

  • Placeholder: Search everything…
  • Rows: the name people know. A second line only when two results could be confused.
  • Group titles: the place. A module keeps its proper name with its capitals, such as Global Projects. Any other title is in sentence case: Modules, Files.
  • Empty: No results for “{query}”. Failed: Search did not finish. Try again.

Tokens

  • --layer-dialog
  • --overlay
  • --radius-2xl
  • --radius-lg
  • --glass-fill-raised
  • --glass-shadow-raised
  • --glass-fill-hover
  • --glass-highlight
  • --glass-ring-raised
  • --border-rule
  • --text
  • --text-muted
  • --text-label
  • --focus-ring

JSON

{
  "title": "Command palette",
  "path": "/components/command-palette",
  "url": "https://design.werklist.com/components/command-palette",
  "text": "https://design.werklist.com/agent/components/command-palette",
  "summary": "A search that opens over any WerkOS screen and takes you straight to a module or a record.",
  "version": "2.1.2",
  "kind": "component",
  "name": "Command palette",
  "purpose": "A modal search, opened with ⌘K or Ctrl+K from any WerkOS screen, that jumps to a module or a record.",
  "use": [
    "Reaching a module or a record by name from anywhere.",
    "Before a letter is typed it lists the modules you can open, so it also serves as a jump list."
  ],
  "avoid": [
    "Narrowing the list on the current page: use that page's search field.",
    "Commands that change data: actions stay in toolbars.",
    "In place of the rail and the modules panel."
  ],
  "anatomy": [
    {
      "part": "Layer",
      "measure": "over the whole window, the panel 12 percent of the window from the top, 16 px from the sides",
      "token": "--layer-dialog"
    },
    {
      "part": "Backdrop",
      "measure": "dimmed and blurred 8 px. A click on it closes the palette",
      "token": "--overlay"
    },
    {
      "part": "Panel",
      "measure": "up to 512 px wide, radius 16 px, no border. In dark it adds the glass highlight and a 0.5 px ring, in light the shadow alone",
      "token": "--radius-2xl, --glass-fill-raised, --glass-shadow-raised, --glass-highlight, --glass-ring-raised"
    },
    {
      "part": "Field row",
      "measure": "52 px, padding 12 px by 16 px, 16 px search glyph, gap 10 px, text 14 px, 16 px on a touch screen. A 16 px spinner at the end while a search runs",
      "token": "--text-muted"
    },
    {
      "part": "Separator",
      "measure": "1 px under the field row, because the list scrolls beneath it",
      "token": "--border-rule"
    },
    {
      "part": "List",
      "measure": "up to 60 percent of the window high, padding 8 px, with its own scroll"
    },
    {
      "part": "Row",
      "measure": "40 px, padding 10 px by 12 px, radius 8 px, 18 px glyph in muted ink, gap 12 px, title 14 px",
      "token": "--radius-lg, --text, --text-muted"
    },
    {
      "part": "Row with context",
      "measure": "54 px, padding 8 px by 12 px, second line 12 px on 18 px. Each line ends in an ellipsis when it is too long",
      "token": "--text-muted"
    },
    {
      "part": "Group title",
      "measure": "13 px on 20 px, weight 500, padding 8 px 12 px 4 px",
      "token": "--text-label"
    },
    {
      "part": "Placeholder rows",
      "measure": "four rows 34 px high, 4 px apart, each an 18 px square and a 12 px bar at 70, 60, 50 and 40 percent, radius 4 px, pulsing",
      "token": "--glass-fill-hover, --radius-sm"
    }
  ],
  "states": [
    {
      "name": "Empty query",
      "change": "Lists the modules you can open"
    },
    {
      "name": "One character",
      "change": "The module list stays"
    },
    {
      "name": "Searching",
      "change": "From 2 characters, after a 120 ms pause. The newest query wins. Four placeholder rows hold the place until the first results"
    },
    {
      "name": "Results",
      "change": "Grouped by where they live",
      "tokens": [
        "--text-label"
      ]
    },
    {
      "name": "No results",
      "change": "No results for “{query}”, with 40 px of padding",
      "tokens": [
        "--text-muted"
      ]
    },
    {
      "name": "Failed",
      "change": "Search did not finish, with a quiet Try again button"
    },
    {
      "name": "Active row",
      "change": "Soft fill, the same for pointer and keyboard, aria-selected true, kept in view",
      "tokens": [
        "--glass-fill-hover"
      ]
    },
    {
      "name": "Enter and exit",
      "change": "Fades in with a 12 px rise from a scale of 0.97, and leaves quicker than it came. With reduced motion it only fades"
    }
  ],
  "keys": [
    {
      "key": "⌘K (Mac), Ctrl+K (Windows, Linux)",
      "action": "Opens or closes the palette"
    },
    {
      "key": "ArrowDown, ArrowUp",
      "action": "Moves the active row and keeps it in view. Stops at the first and the last row"
    },
    {
      "key": "Enter",
      "action": "Opens the active row"
    },
    {
      "key": "Escape",
      "action": "Closes the palette when it is the front layer. Focus returns to where it was"
    },
    {
      "key": "Tab",
      "action": "Stays inside the dialog"
    }
  ],
  "accessibility": [
    "Panel: role dialog, aria-modal true, named Search.",
    "Field: role combobox that controls the list and points to the active option with aria-activedescendant.",
    "List: role listbox. Each group is named by its title, and each row is an option with aria-selected.",
    "A polite live region says how many results arrived, or No results.",
    "Group titles meet 4.5 to 1 on the panel, and muted ink meets 4.5 to 1 on the active row, in both themes."
  ],
  "content": [
    "Placeholder: Search everything…",
    "Rows: the name people know. A second line only when two results could be confused.",
    "Group titles: the place. A module keeps its proper name with its capitals, such as Global Projects. Any other title is in sentence case: Modules, Files.",
    "Empty: No results for “{query}”. Failed: Search did not finish. Try again."
  ],
  "tokens": [
    "--layer-dialog",
    "--overlay",
    "--radius-2xl",
    "--radius-lg",
    "--glass-fill-raised",
    "--glass-shadow-raised",
    "--glass-fill-hover",
    "--glass-highlight",
    "--glass-ring-raised",
    "--border-rule",
    "--text",
    "--text-muted",
    "--text-label",
    "--focus-ring"
  ]
}

Raw file: https://design.werklist.com/agent/components/command-palette