diff --git a/packages/headless/package.json b/packages/headless/package.json index 97d663f1487..a11fefd3a35 100644 --- a/packages/headless/package.json +++ b/packages/headless/package.json @@ -24,6 +24,10 @@ "import": "./dist/primitives/select/index.js", "types": "./dist/primitives/select/index.d.ts" }, + "./menu": { + "import": "./dist/primitives/menu/index.js", + "types": "./dist/primitives/menu/index.d.ts" + }, "./dialog": { "import": "./dist/primitives/dialog/index.js", "types": "./dist/primitives/dialog/index.d.ts" diff --git a/packages/headless/src/primitives/menu/README.md b/packages/headless/src/primitives/menu/README.md new file mode 100644 index 00000000000..c15ce942ab6 --- /dev/null +++ b/packages/headless/src/primitives/menu/README.md @@ -0,0 +1,157 @@ +# Menu + +A dropdown menu with keyboard navigation, typeahead, and nested submenu support. Handles ARIA roles, safe hover zones for submenus, and tree-level close-on-click. + +## When to Use + +- Action menus, context menus, dropdown menus attached to a button trigger. +- When you need nested submenus with safe pointer zones between trigger and submenu. +- Prefer Menu over Popover when the content is a list of actions/commands rather than arbitrary content. + +## Usage + +```tsx +import { Menu } from '@/primitives/menu'; + + + Actions + + + handleEdit()} + /> + handleDuplicate()} + /> + + handleDelete()} + /> + + +; +``` + +### Nested Submenus + +Nest a `` inside a parent `` — the nested trigger automatically renders as a `menuitem` and opens on hover with a safe polygon zone. + +```tsx + + Actions + + + + + Share + + + + + + + + + + +``` + +### Controlled + +```tsx +const [open, setOpen] = useState(false); + + + {/* ... */} +; +``` + +## Parts + +| Part | Default Element | Description | +| ----------------- | --------------- | -------------------------------------- | +| `Menu` | — | Root context provider | +| `Menu.Trigger` | `