[ @sdxc/ui ]
Menu
A menu surface anchored to whatever invoker opens it, riding the same native Popover API Popover does, sized to its own content and padded around a compact stack of Menu.Item rows, Menu.Separator dividers.
View code
<Button commandfor="issue-menu" command="toggle-popover" variant="outline">
Issue actions
<ChevronDownIcon />
</Button>
<Menu id="issue-menu" aria-label="Issue actions" placement="bottom" mix={[menuKeys()]}>
<Section aria-labelledby="issue-menu-edit">
<Header id="issue-menu-edit">Edit</Header>
<Menu.Item href="/examples/issues/482/edit">
<PencilIcon />
<span mix={[grow()]}>Rename</span>
<Keyboard>R</Keyboard>
</Menu.Item>
<Menu.Item>
<UserPlusIcon />
<span mix={[grow()]}>Assign to teammate</span>
<Keyboard>A</Keyboard>
</Menu.Item>
</Section>
<Menu.Separator />
<Section aria-labelledby="issue-menu-share">
<Header id="issue-menu-share">Share</Header>
<Menu.Item>
<CopyIcon />
<span mix={[grow()]}>Copy link</span>
<Keyboard>⌘C</Keyboard>
</Menu.Item>
<Menu.Item href="/examples/issues/482" target="_blank" rel="noreferrer">
<ExternalLinkIcon />
<span mix={[grow()]}>Open in new tab</span>
</Menu.Item>
<Menu.Item disabled>
<ShareIcon />
<span mix={[grow()]}>Share externally</span>
</Menu.Item>
</Section>
<Menu.Separator />
<Menu.Item danger>
<Trash2Icon />
<span mix={[grow()]}>Delete issue</span>
<Keyboard>⌫</Keyboard>
</Menu.Item>
</Menu>Installation
An ordinary dependency: install it, import the theme once, and import the component where it is used.
npm add @sdxc/ui remiximport "@sdxc/ui/theme.css";Usage
import { Menu } from "@sdxc/ui";Renders the menu's own host: a Popover defaulting to
"bottom-start" placement and "menu" role, sized to its content. Point a
row's commandfor at another <Menu>'s id to open it as a nested menu.
Composition
The parts the component publishes, each a static property of the host.
MenuMenu.ItemRenders a native<a>whenhrefis set, else a<button>, defaultingroleto"menuitem"; only omitting or neutralizinghrefstops the<a>variant's navigation, sincearia-disabledmutes it visually only.Menu.SeparatorRenders a hairline divider between two runs of Menu.Items: the shared Separator component with the small block-axis margin a menu's compact rows need on either side of it.
Examples
Row actions
View code
<Button
commandfor="row-menu"
command="toggle-popover"
variant="ghost"
color="neutral"
aria-label="Actions for Q3 roadmap"
>
<EllipsisIcon />
</Button>
<Menu id="row-menu" placement="left-start" aria-label="Project actions">
<Section aria-labelledby="row-menu-view-heading">
<Header id="row-menu-view-heading">View</Header>
<Menu.Item href="/examples/projects/q3-roadmap">Open project</Menu.Item>
<Menu.Item href="/examples/projects/q3-roadmap/edit">Edit details</Menu.Item>
</Section>
<Menu.Separator />
<Menu.Item danger commandfor="confirm-delete" command="show-modal">
Delete project
</Menu.Item>
</Menu>
<Modal id="confirm-delete" aria-labelledby="confirm-delete-title">
<Modal.Header>
<Modal.Title id="confirm-delete-title">Delete Q3 roadmap?</Modal.Title>
<Modal.Description>Its issues and comments are removed for everyone at Acme.</Modal.Description>
</Modal.Header>
<Modal.Footer>
<Button commandfor="confirm-delete" command="close" variant="outline" color="neutral">
Cancel
</Button>
<Button commandfor="confirm-delete" command="close" color="danger">
Delete project
</Button>
</Modal.Footer>
</Modal>Props
Read from the component's own types, so every prop, every default and every allowed value is listed.
| Prop | Type | Description |
|---|---|---|
children | RemixNode | The menu's rows: Menu.Item, Menu.Separator, or a Section/Header pair grouping related items together. |
Also accepts everything in Popover.Props.
Menu.Item
| Prop | Type | Description |
|---|---|---|
href? | string | Destination the row navigates to. Renders the row as a native <a> instead of a <button> when set. |
target? | TagProps<"a">["target"] | target for the link variant, applied only once href is set. |
rel? | TagProps<"a">["rel"] | rel for the link variant, applied only once href is set. |
danger? | boolean | Styles the row in the semantic danger tone, for a destructive action like deleting a resource. |
mix? | MixinDescriptor<HTMLAnchorElement | HTMLButtonElement, any, ElementProps>[] | Extra mixin(s) applied to the row's host element, whichever of <a>/<button> it renders as depending on href. |
Also accepts everything in TagProps<"button">.
Menu.Separator
Also accepts everything in Separator.Props.