Widgets
Dropdown
Dropdown menu positioned relative to an anchor widget.
Dropdown menu positioned relative to an anchor widget.
Usage
ui.dropdown({
id: "file-menu",
anchorId: "file-button",
position: "below-start",
items: [
{ id: "new", label: "New", shortcut: "Ctrl+N" },
{ id: "open", label: "Open", shortcut: "Ctrl+O" },
{ id: "divider", label: "", divider: true },
{ id: "exit", label: "Exit" },
],
onSelect: (item) => handleAction(item.id),
onClose: () => app.update((s) => ({ ...s, menuOpen: false })),
})Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | required | Unique dropdown identifier |
anchorId | string | required | ID of anchor widget used for positioning |
position | DropdownPosition | "below-start" | Placement relative to anchor |
items | DropdownItem[] | required | Menu rows (including optional dividers) |
frameStyle | { background?, foreground?, border? } | - | Optional frame/surface colors for menu background, text, and border |
onSelect | (item) => void | - | Called when a selectable item is activated |
onClose | () => void | - | Called when dropdown should close |
Behavior
- Arrow keys navigate items. Enter selects the highlighted item.
- The current selection is visually highlighted.
- Long menus render a deterministic visible window and keep the highlighted item in view as you navigate.
- Mouse click on an item selects it and fires the
onSelectcallback. - Clicking outside the dropdown closes it (calls
onClose). - Dropdown overlays register in the shared
LayerRegistry, so z-order and hit-testing behavior is consistent with modal/layer overlays. - Item
shortcutbindings are active for the topmost open dropdown and trigger the same selection/close path as keyboard or mouse activation.
Notes
- Use
anchorIdto position the dropdown relative to an element in the layout tree. - Render dropdowns inside
ui.layers(...)so they stack above base UI.
Keyboard shortcut example
ui.dropdown({
id: "file-menu",
anchorId: "file-btn",
items: [
{ id: "save", label: "Save", shortcut: "Ctrl+S" },
{ id: "quit", label: "Quit", shortcut: "Ctrl+Q" },
],
onSelect: (item) => runCommand(item.id),
})Optional app-level bindings for the same actions:
app.keys({
"ctrl+s": () => runCommand("save"),
"ctrl+q": () => runCommand("quit"),
})Use app.keys() for app-level shortcuts that should work even when the dropdown is closed.