Dropdown Menu Form
The parts a dropdown menu needs to hold a small form — a text input that keeps its keys, a switch row with a hint, and a menu that opens at a point.
- Status
- Since
0.26.0- Accessibility pattern
- the switch row is one checkbox item; typing stays put
Last updated
Install
Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Dropdown Menu Form before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify dropdown-menu-formInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/dropdown-menu-formRun the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.
The same command installs the registry items it composes: @vegastack/dropdown-menu, @vegastack/input, @vegastack/switch.
Usage
import {
DropdownMenuAtPoint,
DropdownMenuInput,
DropdownMenuSwitchItem,
} from "@/components/ui/dropdown-menu-form";
<DropdownMenuAtPoint point={point} onClose={() => setPoint(null)}>
<DropdownMenuInput
passArrows
aria-label="Name"
value={name}
onChange={(event) => setName(event.target.value)}
/>
<DropdownMenuSwitchItem
label="Required"
hint="A row can't be saved without it."
checked={required}
onCheckedChange={setRequired}
/>
</DropdownMenuAtPoint>;DropdownMenu is the upstream menu and stays as it is; these parts compose it.
DropdownMenuInputis anInputwhose keys stay its own: typing, arrows, Home and End do not reach the menu's arrow-key and type-ahead handling. Escape and Tab still do. WithpassArrows, ArrowUp and ArrowDown also pass, so a name field at the top of a menu can hand the keyboard to the rows below it.DropdownMenuSwitchItemis a checkbox item drawn as a switch row: a click anywhere on the row toggles, it keeps a menu item's focus and keys, and an optionalhintsits under the label.DropdownMenuAtPointopens a menu beside a point in the viewport, for a request that has no trigger to hang from (a "+" at the end of a header, a context click).stopMenuTyping(event)is the same guard for a field that is not anInput(a textarea, a number field).
Anatomy
Examples
A field's menu
API Reference
DropdownMenuInput
| Prop | Type | Default | Description |
|---|---|---|---|
credential | boolean | true | false (FRM-17) marks a name-like field that is not a credential — a record, table or field
name — so browsers and password managers stop offering to fill it: autoComplete="off",
data-1p-ignore, data-lpignore="true", data-bwignore. An explicit autoComplete wins. |
passArrows | boolean | false | Let ArrowUp and ArrowDown reach the menu, so the keyboard moves on to the rows around the field (a name field at the top of a settings menu). |
size | "default" | "lg" | "sm" | null | — | |
variant | "default" | "ghost" | null | — |
Data attributes and CSS variables on DropdownMenuInput
| Attribute | Values |
|---|---|
data-slot | "dropdown-menu-input" |
DropdownMenuSwitchItem
| Prop | Type | Default | Description |
|---|---|---|---|
label* | React.ReactNode | — | The row's name. |
hint | React.ReactNode | — | A muted line under the name. |
inset | boolean | — |
Data attributes and CSS variables on DropdownMenuSwitchItem
| Attribute | Values |
|---|---|
data-slot | "dropdown-menu-switch-item" |
DropdownMenuAtPoint
| Prop | Type | Default | Description |
|---|---|---|---|
children* | React.ReactNode | — | The menu's content: items, or a form. |
onClose* | () => void | — | The menu asked to close (Escape, a press outside, a choice). |
point* | DropdownMenuPoint | null | — | Where the menu opens, or null while it is closed. |
align | "center" | "end" | "start" | "start" | Which edge of the point the menu lines up with. |
className | string | — | The content's extra classes. |
Data attributes and CSS variables on DropdownMenuAtPoint
| Attribute | Values |
|---|---|
data-slot | "dropdown-menu-point" |
--anchor-x | CSS custom property |
--anchor-y | CSS custom property |
Accessibility
- The switch row is one
menuitemcheckbox; the switch inside it is decorative (inert and hidden from assistive tech), so the state is read once. - The point trigger is invisible,
aria-hiddenand not a focus stop.
| Key | Action |
|---|---|
| ↑ ↓ | In the input: move the caret (or, with passArrows, leave the field) |
| Space | On a switch row: toggle |
| Esc | Close the menu |
| Contract | States tested |
|---|---|
| Behaviour | default, open, checked |
| Accessibility | labeled, browser-accessibility-test |
| Visual | default, hover |