Overlays
Dropdown menu
Actions from a trigger. A menu is not a styled list: it has roving focus, typeahead, and a role a screen reader recognises.
Basic
Open it and start typing. Focus jumps to the matching item.
<DropdownMenu.Root> <DropdownMenu.Trigger asChild> <Button variant="secondary"> Actions <Icon name="expand_more" /> </Button> </DropdownMenu.Trigger> <DropdownMenu.Content> <DropdownMenu.Label>Package</DropdownMenu.Label> <DropdownMenu.Item>Rename</DropdownMenu.Item> <DropdownMenu.Item>Deprecate</DropdownMenu.Item> <DropdownMenu.Sub> <DropdownMenu.SubTrigger>Transfer to…</DropdownMenu.SubTrigger> <DropdownMenu.SubContent> <DropdownMenu.Item>Another user</DropdownMenu.Item> <DropdownMenu.Item>An organisation</DropdownMenu.Item> </DropdownMenu.SubContent> </DropdownMenu.Sub> <DropdownMenu.Separator /> <DropdownMenu.Item destructive>Unpublish</DropdownMenu.Item> </DropdownMenu.Content></DropdownMenu.Root>Typeahead, arrow keys, Escape and outside-click dismissal all come from the base layer. All of them are things a hand-rolled menu ships without.
Checkbox and radio items
These keep a gutter for the indicator, so the list does not shift sideways when one becomes selected.
<DropdownMenu.Root> <DropdownMenu.Trigger asChild> <Button variant="secondary"> Publish options <Icon name="expand_more" /> </Button> </DropdownMenu.Trigger> <DropdownMenu.Content> <DropdownMenu.CheckboxItem checked={dryRun} onCheckedChange={setDryRun}> Dry run </DropdownMenu.CheckboxItem> <DropdownMenu.Separator /> <DropdownMenu.Label>Tag</DropdownMenu.Label> <DropdownMenu.RadioGroup value={tag} onValueChange={setTag}> <DropdownMenu.RadioItem value="latest">latest</DropdownMenu.RadioItem> <DropdownMenu.RadioItem value="next">next</DropdownMenu.RadioItem> <DropdownMenu.RadioItem value="canary">canary</DropdownMenu.RadioItem> </DropdownMenu.RadioGroup> </DropdownMenu.Content></DropdownMenu.Root>destructive gives a row a red label, and fills it red once it is highlighted. Color alone does not carry that meaning, so the label still has to say “Unpublish”.Parts
Import it as a namespace, and the parts work on either side of the server boundary.
import * as DropdownMenu from '@minuk-hwang-design-system/components-react/dropdown-menu';| Part | What it is |
|---|---|
DropdownMenu.Root | Owns the open state. |
DropdownMenu.Trigger | Gets role and aria-expanded. |
DropdownMenu.Content | The menu. Portalled, flips near an edge. |
DropdownMenu.Item | An action. |
DropdownMenu.CheckboxItem | Toggles, with an indicator gutter. |
DropdownMenu.RadioGroup / RadioItem | One of a set. |
DropdownMenu.Label | Group heading. Skipped by the keyboard. |
DropdownMenu.Separator | Divider. |
DropdownMenu.Sub / SubTrigger / SubContent | Nested menu. |
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
destructive | boolean | false | On Item. Red label, filled red when highlighted; the label still carries the meaning. |
onSelect | (event) => void | — | On Item. Fires for click and Enter alike. |
side / align | string | — | On Content. Preferred placement. |