Overlays

color-picker-popup

#existingsource

A compact colour chooser. Use it for brand / theme / label colour entry where a curated palette covers most needs but a custom hex must still be possible. It pairs a preset swatch grid with a hex field and a live preview; Enter commits, Escape closes, focus is trapped while open and restored on close.

Readiness
complete
Preview
live
Props
3
Examples
2
Code
implementation mapped

When to use

  • Brand or theme colour selection from a curated palette
  • Tag / label colour assignment with an occasional custom value
  • Any surface that previously hand-rolled a colour overlay

When not to use

  • Full gradient / alpha authoring — needs a richer colour tool
  • A fixed, non-custom set of choices — use a swatch radio group
  • Inline single-field entry — use the ColorInput primitive

Accessibility

Role: dialog

  • Escape — Close the picker
  • Enter — Commit the selected colour
  • Tab — Cycle focus within the picker (focus is trapped)

Screen reader: The panel is role=dialog aria-modal=true. Swatches form a listbox of options, each labelled with its hex value and carrying aria-selected. The preview is presentational; the hex field is a labelled text input. Focus is trapped and restored to the trigger on close.

Notes: Swatch colour is conveyed by the accessible name (hex), not colour alone, so the grid is usable without colour perception.

Props

NameTypeDefaultDescription
valuestring#3B82F6Initial selected colour (hex).
swatchesarrayPreset hex swatches. Falls back to a built-in palette when empty.
trigger_labelstringPick a colourLabel for the button that opens the picker.

Examples

Brand colour

Brand-colour picker with the default palette.

YAML
type: color-picker-popup
props:
  value: '#3B82F6'
  trigger_label: Pick a colour
Custom palette

Constrained custom palette.

YAML
type: color-picker-popup
props:
  value: '#22C55E'
  trigger_label: Label colour
  swatches:
  - '#EF4444'
  - '#F59E0B'
  - '#22C55E'
  - '#3B82F6'
  - '#A855F7'
  - '#EC4899'
Edit YAML

command-palette

#existingsource

An application-wide command launcher. Use CommandPalette to give power users a single keyboard-first entry point to navigate and run actions: it filters a flat command list as the user types and is fully keyboard-navigable (Arrow up/down to move, Enter to run, Escape to dismiss). Focus is trapped while open and restored on close. EditorPalette is the IDE-scoped sibling; this is the app-wide variant.

Readiness
complete
Preview
live
Props
3
Examples
2
Code
implementation mapped

When to use

  • A global 'do anything' launcher reached by a keyboard shortcut
  • Surfaces with many actions that would bloat a visible toolbar
  • Power-user navigation across an app's whole command surface

When not to use

  • A small set of contextual actions — use DropdownMenu
  • IDE / editor command context — use EditorPalette
  • Selecting one value from a list in a form — use Select / Combobox

Accessibility

Role: dialog

  • Escape — Close the palette
  • Enter — Run the highlighted command
  • ArrowDown — Move highlight down (wraps)
  • ArrowUp — Move highlight up (wraps)

Screen reader: The panel is role=dialog aria-modal=true. The list is a listbox and each command an option with aria-selected tracking the highlight. Focus is trapped in the panel and restored to the trigger on close. An empty result set announces "No matching commands".

Notes: Keep labels action-first ("Create circle", not "Circle, create") so type-ahead matches what users think first.

Props

NameTypeDefaultDescription
items*arrayCommands offered by the palette.
placeholderstringType a command or search…Placeholder for the search field.
trigger_labelstringOpen command paletteLabel for the button that opens the palette.

Examples

App command palette

A global launcher with shortcut hints.

YAML
type: command-palette
props:
  trigger_label: Open command palette
  items:
  - label: Create circle
    hint: C
  - label: Search elements
    hint: /
  - label: Open settings
    hint: ','
  - label: Invite teammate
Plain palette

Minimal palette, no hints.

YAML
type: command-palette
props:
  items:
  - label: New document
  - label: New folder
Edit YAML

context-menu

#existingsource

ContextMenu exposes actions for the object under the pointer. It keeps context actions keyboard-navigable and visually aligned with dropdown menus while preserving the right-click interaction pattern.

Readiness
complete
Preview
live
Props
2
Examples
1
Code
implementation mapped

When to use

  • Object-specific actions such as duplicate, archive, inspect, or delete
  • Dense canvases, graphs, and lists where secondary actions should stay tucked away
  • Power-user workflows that also have discoverable primary actions elsewhere

When not to use

  • Primary actions that every user must discover
  • Mobile-first interactions where right-click is unavailable
  • Navigation menus or product-level command palettes

Accessibility

Role: menu

  • Escape — Closes the menu
  • ArrowDown — Moves focus to the next item
  • ArrowUp — Moves focus to the previous item
  • Enter — Activates the focused item
  • Space — Activates the focused item

Screen reader: Menu items announce role=menuitem and disabled state.

Notes: Provide another visible path for the same actions when they are important.

Props

NameTypeDefaultDescription
items*arrayContext actions in menu order.
on_selectstring

Examples

Component row menu

Context actions for a component row.

YAML
type: context-menu
props:
  items:
  - label: Open
  - label: Duplicate
  - label: Delete
    danger: true
slots:
  trigger:
  - type: button
    props:
      variant: secondary
    slots:
      default: Right-click component
Edit YAML

date-picker-popup

#existingsource

A calendar overlay for picking a single date. Use it when date entry needs a consistent cross-browser look and full keyboard support: Arrow keys move the selection by day (left/right) and week (up/down), Enter commits, Escape closes; prev/next step the visible month. The month grid is computed without any date library so the component is self-contained.

Readiness
complete
Preview
live
Props
4
Examples
2
Code
implementation mapped

When to use

  • Single-date entry where the native control's look is unacceptable
  • Forms that need keyboard-navigable date selection
  • Surfaces that must look identical across browsers

When not to use

  • Date ranges — needs a dedicated range picker
  • Free-form date typing only — a masked text input is lighter
  • Relative dates ('last 7 days') — use a preset selector

Accessibility

Role: dialog

  • ArrowLeft — Previous day
  • ArrowRight — Next day
  • ArrowUp — Previous week
  • ArrowDown — Next week
  • Enter — Commit the selected date
  • Escape — Close the picker

Screen reader: The panel is role=dialog aria-modal=true. The grid is role=grid with each day a gridcell carrying an ISO aria-label and aria-selected. Focus is trapped while open and restored to the trigger on close. The month label is a polite live region.

Notes: Pad cells before the 1st are aria-hidden so the screen reader only encounters real, selectable days.

Props

NameTypeDefaultDescription
yearinteger2026Initial year shown.
monthinteger1Initial month shown (1–12).
selected_dayintegerOptional pre-selected day of the initial month.
trigger_labelstringPick a dateLabel for the button that opens the picker.

Examples

Pre-selected date

May 2026 with the 17th pre-selected.

YAML
type: date-picker-popup
props:
  year: 2026
  month: 5
  selected_day: 17
  trigger_label: Pick a date
No selection

Empty month, nothing selected yet.

YAML
type: date-picker-popup
props:
  year: 2026
  month: 1
  trigger_label: Choose start date
Edit YAML

drawer

#existingsource

A modal surface anchored to one edge of the viewport. Use Drawer for secondary flows — filters, a detail inspector, contextual settings — where the user should stay oriented in the page behind it. Focus is trapped within the panel while open and restored on close; the scrim blocks interaction with the page until dismissed. The panel slides in from the chosen edge with a reduced-motion fallback.

Readiness
complete
Preview
live
Props
3
Examples
2
Code
implementation mapped

When to use

  • Filters or facets that refine the surface behind them
  • A detail inspector for the currently selected row
  • Contextual settings that don't deserve a route change

When not to use

  • A focused confirm / form task — use Dialog (centred modal)
  • Persistent workspace chrome — use a docked panel
  • A small anchored menu — use DropdownMenu or Popover

Accessibility

Role: dialog

  • Escape — Close the drawer
  • Tab — Cycle focus within the drawer (focus is trapped)

Screen reader: The panel has role=dialog and aria-modal=true, labelled by its title. Focus moves into the panel on open and is restored to the trigger on close. The scrim is presentational.

Notes: Keep the body scrollable rather than letting the whole drawer grow past the viewport; the header stays pinned.

Props

NameTypeDefaultDescription
titlestringDrawerDrawer heading and accessible name.
sideenum: left | right | top | bottomright
trigger_labelstringOpen drawerLabel for the button that opens the drawer.

Examples

Filters drawer

Right-anchored filter drawer.

YAML
type: drawer
props:
  title: Filters
  side: right
  trigger_label: Open filters
slots:
  default: Filter controls go here.
Bottom sheet

Bottom sheet variant.

YAML
type: drawer
props:
  title: Details
  side: bottom
  trigger_label: Show details
slots:
  default: Detail content for the selected item.
Edit YAML

info-tooltip

#existingsource

InfoTooltip annotates compact technical language without interrupting the layout. It pairs the term with a focusable info trigger so mouse, keyboard, and screen-reader users can reach the explanation.

Readiness
complete
Preview
live
Props
2
Examples
1
Code
implementation mapped

When to use

  • Metrics, model terms, and abbreviations that need plain-language help
  • Dense dashboards where inline helper copy would overwhelm scanning
  • Labels that are correct but not self-explanatory to new users

When not to use

  • Critical instructions that must be visible without hover or focus
  • Long documentation; link to docs or use a disclosure block instead
  • Interactive content inside the floating tooltip

Accessibility

Role: tooltip

  • Tab — Focuses the info trigger
  • Escape — Browser focus movement closes the tooltip when focus leaves

Screen reader: The trigger references the tooltip body with aria-describedby.

Notes: The explanation should be plain language, not another technical definition.

Props

NameTypeDefaultDescription
term*stringVisible term being explained.
explanation*stringShort plain-language explanation.

Examples

Metric help

Explain a dashboard percentile metric.

p95 latency
YAML
type: info-tooltip
props:
  term: p95 latency
  explanation: 95% of requests finish faster than this value.
Edit YAML

popover

#existingsource

An anchored overlay that opens next to a trigger element. Unlike Modal, it does NOT trap focus or dim the background — keyboard users can tab past it. Use for inline editing, anchored helper UI, and inline filters. For menu-style action lists use DropdownMenu (purpose-built variant). For modal flows use Modal.

Readiness
complete
Preview
live
Props
5
Examples
1
Code
implementation mapped

When to use

  • Inline editing (e.g. quick rename without a modal)
  • Anchored helper UI (filter pickers, date pickers)
  • Detail expansion next to a trigger
  • Keyboard-shortcut hints (paired with InfoTooltip)

When not to use

  • Action menus — use DropdownMenu (better defaults for menu semantics)
  • Modal forms / confirmations — use Modal (focus trap + dim)
  • Tooltips for brief hover hints — use Tooltip (lighter, ARIA-tooltip role)
  • Persistent side regions — use PanelShell

Accessibility

Role: dialog

  • Escape — Closes the popover
  • Tab — Moves focus through popover content (does NOT trap)

Screen reader: `aria-modal=false` declared (it's a non-modal popover). `aria-haspopup` on the trigger announces the relationship. Caller wires aria-controls + aria-expanded on the trigger.

Notes: Use `trigger: click` for menus / forms. Use `trigger: hover` only when the content is purely informative (otherwise touch users have no way to access it).

Props

NameTypeDefaultDescription
openboolean
on_closestring
positionenum: top | right | bottom | leftbottom
alignenum: start | center | endstart
triggerenum: click | hover | focusclick

Examples

Quick rename

Inline rename popover.

YAML
type: popover
props:
  open: ${state.rename_open}
  on_close: ${actions.close_rename}
  position: bottom
  align: start
slots:
  trigger:
  - type: button
    props:
      variant: ghost
    slots:
      default: Rename
  default:
  - type: stack
    props:
      gap: sm
      direction: column
    children:
    - type: input
      props:
        value: ${state.new_name}
        on_input: ${actions.set_new_name}
        auto_focus: true
    - type: button
      props:
        variant: primary
        on_click: ${actions.commit_rename}
      slots:
        default: Save
Edit YAML

tooltip

#existingsource

An anchored helper text bubble that appears on hover AND focus. Use for short clarifications (truncated names, icon-button labels, terms of art). For technical-term explanations with a `?` trigger, use InfoTooltip (sibling, has explicit affordance). For longer interactive content, use Popover.

Readiness
complete
Preview
live
Props
3
Examples
2
Code
implementation mapped

When to use

  • Truncated text full value (text-overflow:ellipsis revealed)
  • Icon-button labels (paired with IconButton title prop)
  • Brief clarification of an unclear control
  • Keyboard shortcut display next to action affordances

When not to use

  • Long interactive content — use Popover
  • Mobile-only (tooltips don't work without hover) — use inline text
  • Content the user must read to operate the page — make it visible
  • Anything you can't read in <2s — too long for a tooltip

Accessibility

Role: tooltip

  • Tab — Focus reveals the tooltip
  • Escape — Hides the tooltip

Screen reader: Tooltip content is wired to the trigger via `aria-describedby`. SR users hear the trigger's name, then the tooltip's prose. The tooltip is not focusable itself.

Notes: Tooltips MUST appear on keyboard focus, not just on hover. The audit fails if hover-only tooltip wiring is detected.

Props

NameTypeDefaultDescription
textstringTooltip content.
positionenum: top | right | bottom | lefttop
delayinteger500Delay (ms) before tooltip appears on hover.

Examples

Truncated value

Tooltip on a truncated agent name.

Acme Onboarding…Acme Onboarding Automation v2
YAML
type: tooltip
props:
  text: Acme Onboarding Automation v2
  position: top
slots:
  default:
  - type: text
    slots:
      default: Acme Onboarding…
Shortcut hint

Tooltip beside a keyboard shortcut hint.

⌘KOpen command palette
YAML
type: tooltip
props:
  text: Open command palette
  position: bottom
slots:
  default:
  - type: kbd
    slots:
      default: ⌘K
Edit YAML