Overlays@knitui/components
Menu
Menu is a compound component built on top of Popover. Compose Menu.Target (the trigger element), Menu.Dropdown (the panel), Menu.Item (an interactive row), Menu.Label (a section header), and Menu.Divider (a separator). State can be uncontrolled (defaultOpened) or fully controlled (opened + onChange).
import { Menu } from "@knitui/components";Playground
Loading playground…
<Menu
position="bottom-start"
closeOnItemClick
withArrow={false}
disabled={false}
trigger="click"
shadow="md"
/>Examples
Controlled
Fully controlled open state driven by React.useState — demonstrates the Trigger pattern.
Loading example…
With Labels And Divider
Labels and a divider group related items into named sections.
Loading example…
With Sections
Left and right sections hold icons or badges on either side of the label.
Loading example…
Disabled Items
Disabled items are visually muted and do not respond to press events.
Loading example…
Disabled Menu
The whole menu can be disabled — the dropdown never renders.
Loading example…
With Arrow
The arrow variant draws a pointer from the dropdown toward the target.
Loading example…
Styles
Per-slot styles targets individual parts — here the label, item, and itemLabel.
Loading example…
Shadows
All five shadow levels side by side to compare dropdown elevation. Each menu is always open and rendered in its own contained relative wrapper (withinPortal={false}) so the dropdowns sit inline and don't overlap.
Loading example…
Hover Trigger
Hover trigger opens the menu on pointer enter and closes on pointer leave.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
arrowOffset | number | undefined | 5 | Arrow distance from the start/end edge when `arrowPosition="side"`. |
arrowPosition | ArrowPosition | undefined | 'side' | Arrow alignment: centered, or pinned toward an aligned placement. |
arrowRadius | number | undefined | 0 | Corner radius of the arrow's outward corner in px. |
arrowSize | number | undefined | 7 | Arrow square edge length in px. |
children | ReactNode | — | `Menu.Target` + `Menu.Dropdown`. |
closeDelay | number | undefined | 100 | Close delay in ms for hover triggers. |
closeOnClickOutside | boolean | undefined | true | Close on outside press (web). |
closeOnEscape | boolean | undefined | true | Close on `Escape` (web). |
closeOnItemClick | boolean | undefined | true | Close the menu when an item is pressed. |
defaultOpened | boolean | undefined | false | Uncontrolled initial opened state. |
disabled system | boolean | undefined | false | Skip rendering the dropdown entirely. |
keepMounted | boolean | undefined | false | Keep the dropdown mounted while closed. |
menuItemTabIndex | 0 | -1 | undefined | -1 | `tabIndex` set on every item; `0` enables Tab navigation. |
offset | number | undefined | 8 | Gap between target and dropdown in px. |
onChange | ((opened: boolean) => void) | undefined | — | Called when the opened state changes. |
onClose | (() => void) | undefined | — | Called when the menu closes. |
onOpen | (() => void) | undefined | — | Called when the menu opens. |
openDelay | number | undefined | 0 | Open delay in ms for hover triggers. |
opened | boolean | undefined | — | Controlled opened state. |
position | Placement | undefinedtop · top-start · top-end · bottom · bottom-start · bottom-end · left · left-start · left-end · right · right-start · right-end | 'bottom-start' | Dropdown placement relative to the target. |
radius system | RadiusTokens | undefined | — | Dropdown border radius. |
shadow system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefinedxs · sm · md · lg · xl | 'md' | Dropdown shadow scale. |
styles system | SlotStyles<MenuStyles> | undefined | — | Per-slot style sugar — props spread onto the matching styled part. |
theme system | ThemeName | null | undefined | — | Accent theme applied to the menu subtree (trigger + dropdown). |
trigger | MenuTrigger | undefinedclick · hover · click-hover | 'click' | Event that opens the menu. |
width | PopoverWidth | undefined | 'max-content' | Dropdown width; `'target'` matches the target. |
withArrow | boolean | undefined | false | Render an arrow pointing at the target. |
withinPortal | boolean | undefined | true | Render the dropdown in a portal. |
zIndex | number | undefined | 300 | Dropdown `z-index`. |
Style slots
Every part of Menu can be styled through the styles prop. Explicit props on the component always win over slot styles.
| Slot | Usage |
|---|---|
divider | styles={{ divider: { … } }} |
dropdown | styles={{ dropdown: { … } }} |
item | styles={{ item: { … } }} |
itemLabel | styles={{ itemLabel: { … } }} |
itemSection | styles={{ itemSection: { … } }} |
label | styles={{ label: { … } }} |