{"name":"dropdown-menu","title":"Dropdown Menu","description":"Displays a menu to the user — such as a set of actions or functions — triggered by a button.","installCommand":"bunx marko-ui add dropdown-menu -y","usageTags":"<DropdownMenu>","importSnippet":"import DropdownMenu from \"@/components/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@/components/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@/components/ui/button/button.marko\";","usageSnippet":"static const ITEMS = [\n  { value: \"profile\", label: \"Profile\" },\n  { value: \"settings\", label: \"Settings\" },\n  { type: \"separator\" },\n  { value: \"logout\", label: \"Log out\" },\n] satisfies DropdownMenuItem[];\n\n<DropdownMenu items=ITEMS select(value) { /* ... */ }>\n  <@trigger|triggerProps|>\n    <Button variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n</DropdownMenu>","tags":["DropdownMenu"],"parts":[{"name":"trigger","param":"Record<string, unknown>"},{"name":"item","attributes":[{"name":"type","type":"\"item\" | \"separator\" | \"label\" | \"checkbox\" | \"radio\" | \"sub\"","required":false},{"name":"value","type":"string","required":false},{"name":"label","type":"string","required":false},{"name":"disabled","type":"boolean","required":false},{"name":"shortcut","type":"string","required":false},{"name":"variant","type":"\"default\" | \"destructive\"","required":false,"description":"Upstream `variant: \"default\" | \"destructive\"`, emitted as `data-variant`."},{"name":"inset","type":"boolean","required":false,"description":"Emits `data-inset` — indents the entry to align with icon-bearing siblings."},{"name":"checked","type":"boolean","required":false,"description":"Checked state for `type=\"checkbox\"` and `type=\"radio\"` entries."},{"name":"radioGroup","type":"string","required":false,"description":"Groups radio items — required for `type: \"radio\"` entries."},{"name":"radioValue","type":"string","required":false,"description":"`type: \"radio\"` entries only — this entry's value within its `radioGroup`."},{"name":"subEntries","type":"readonly DropdownMenuItem[]","required":false,"description":"`type: \"sub\"` entries only — the nested submenu's own item list. One level deep: a `type: \"sub\"` entry inside a submenu's own `subEntries` is not wired (same limit as menubar's submenu)."}],"repeatable":true}],"props":[{"name":"class","type":"string","required":false},{"name":"closeOnSelect","type":"boolean | undefined","required":false},{"name":"items","type":"DropdownMenuItem[]","required":false},{"name":"positioning","type":"menu.PositioningOptions | undefined","required":false,"description":"Machine pass-throughs, forwarded to `@zag-js/menu` by `<zag-machine ...\nfrom=input/>` regardless of whether they're declared here (see\n`buildMachineProps` in marko-zag) — declared for type safety and DX.\n`positioning`/`onHighlightChange` are what a caller needs to relocate the\npopup (side/align/gutter/mobile anchor override) and mirror the\nhighlighted item for a hover-preview, the two capabilities the typeset/\ncreate picker.marko files used to hand-roll a whole parallel menu for."},{"name":"select","type":"(value: string) => void","required":false}],"events":[{"name":"checkedChange","arg":"string, checked: boolean","description":"Fires when a checkbox item's checked state changes; receives its value and new checked state."},{"name":"onHighlightChange","arg":"menu.HighlightChangeDetails"},{"name":"onOpenChange","arg":"menu.OpenChangeDetails"},{"name":"radioChange","arg":"string, value: string","description":"Fires when a radio group's selected value changes; receives the group name and new value."}],"keyboard":[{"keys":"Enter / Space","description":"Opens the menu when focused on the trigger; activates the highlighted item when the menu is open."},{"keys":"ArrowDown / ArrowUp","description":"Moves the highlight to the next / previous item, wrapping at the ends."},{"keys":"ArrowRight","description":"On a submenu trigger item, opens the submenu and moves focus into it."},{"keys":"ArrowLeft / Escape","description":"Closes an open submenu (ArrowLeft) or the whole menu (Escape) and returns focus to the trigger."},{"keys":"Home / End","description":"Moves the highlight to the first / last item."},{"keys":"A–Z","description":"Typeahead: jumps the highlight to the next item whose label starts with the typed characters."}],"accessibilityNotes":["The trigger and content wire up `aria-haspopup`, `aria-expanded`, and `aria-controls` automatically via the underlying Zag menu machine — no manual ARIA authoring needed.","Checkbox and radio items expose `role=\"menuitemcheckbox\"` / `role=\"menuitemradio\"` with `aria-checked` reflecting the `checked` field.","Disabled items (`disabled: true`) are marked `aria-disabled` and skipped by both keyboard navigation and typeahead."],"examples":[{"id":"dropdown-menu-demo","title":"Basic","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { type: \"label\", label: \"My Account\" },\n  { type: \"separator\" },\n  { value: \"profile\", label: \"Profile\", shortcut: \"⇧⌘P\" },\n  { value: \"billing\", label: \"Billing\", shortcut: \"⌘B\" },\n  { value: \"settings\", label: \"Settings\", shortcut: \"⌘S\" },\n  { type: \"separator\" },\n  { value: \"team\", label: \"Team\" },\n  { value: \"invite\", label: \"Invite users\", disabled: true },\n  { type: \"separator\" },\n  { value: \"logout\", label: \"Log out\", variant: \"destructive\" },\n] satisfies DropdownMenuItem[];\n\n<DropdownMenu items=ITEMS>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n</DropdownMenu>","description":"Items are a plain array — mix labels, separators, shortcuts, and a destructive item without composing subcomponents."},{"id":"dropdown-menu-basic","title":"Labels and separators","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { type: \"label\", label: \"My Account\" },\n  { value: \"profile\", label: \"Profile\" },\n  { value: \"billing\", label: \"Billing\" },\n  { value: \"settings\", label: \"Settings\" },\n  { type: \"separator\" },\n  { value: \"github\", label: \"GitHub\" },\n  { value: \"support\", label: \"Support\" },\n  { value: \"api\", label: \"API\", disabled: true },\n] satisfies DropdownMenuItem[];\n\n<DropdownMenu items=ITEMS>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n</DropdownMenu>","description":"Labels and separators group related actions; a disabled item is skipped in the tab order."},{"id":"dropdown-menu-submenu","title":"Submenu","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { value: \"team\", label: \"Team\" },\n  {\n    type: \"sub\",\n    label: \"Invite users\",\n    subEntries: [\n      { value: \"email\", label: \"Email\" },\n      { value: \"message\", label: \"Message\" },\n      { type: \"separator\" },\n      { value: \"calendly\", label: \"Calendly\" },\n      { value: \"slack\", label: \"Slack\" },\n      { type: \"separator\" },\n      { value: \"webhook\", label: \"Webhook\" },\n      { type: \"separator\" },\n      { value: \"advanced\", label: \"Advanced...\" },\n    ],\n  },\n  { value: \"new-team\", label: \"New Team\", shortcut: \"⌘+T\" },\n] satisfies DropdownMenuItem[];\n\n<DropdownMenu items=ITEMS>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n</DropdownMenu>","description":"A `type: \"sub\"` entry with its own `subEntries` nests a secondary menu. Our submenu wiring supports one level of nesting: a `type: \"sub\"` entry inside a submenu's own `subEntries` is not wired, so upstream's second-level 'More options' items (Calendly, Slack, Webhook) are flattened directly into the 'Invite users' submenu instead of sitting behind their own nested trigger."},{"id":"dropdown-menu-shortcuts","title":"Shortcuts","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { type: \"label\", label: \"My Account\" },\n  { value: \"profile\", label: \"Profile\", shortcut: \"⇧⌘P\" },\n  { value: \"billing\", label: \"Billing\", shortcut: \"⌘B\" },\n  { value: \"settings\", label: \"Settings\", shortcut: \"⌘S\" },\n  { type: \"separator\" },\n  { value: \"logout\", label: \"Log out\", shortcut: \"⇧⌘Q\" },\n] satisfies DropdownMenuItem[];\n\n<DropdownMenu items=ITEMS>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n</DropdownMenu>","description":"The `shortcut` field renders a right-aligned keyboard hint."},{"id":"dropdown-menu-icons","title":"Icons","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\n<DropdownMenu>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n  <@item value=\"profile\">\n    <Icon name=\"User\"/>\n    Profile\n  </@item>\n  <@item value=\"billing\">\n    <Icon name=\"CreditCard\"/>\n    Billing\n  </@item>\n  <@item value=\"settings\">\n    <Icon name=\"Settings\"/>\n    Settings\n  </@item>\n  <@item type=\"separator\"/>\n  <@item value=\"logout\" variant=\"destructive\">\n    <Icon name=\"LogOutIcon\"/>\n    Log out\n  </@item>\n</DropdownMenu>","description":"Compose items with `<@item>` attribute tags to put an icon before the label."},{"id":"dropdown-menu-simple","title":"Simple","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { value: \"edit\", label: \"Edit\" },\n  { value: \"duplicate\", label: \"Duplicate\" },\n  { value: \"archive\", label: \"Archive\" },\n  { type: \"separator\" },\n  { value: \"delete\", label: \"Delete\", variant: \"destructive\" },\n] satisfies DropdownMenuItem[];\n\n<DropdownMenu items=ITEMS>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Actions</Button>\n  </@trigger>\n</DropdownMenu>","description":"A minimal menu with no label, just actions and a destructive item at the end."},{"id":"dropdown-menu-disabled-item","title":"Disabled item","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { value: \"cut\", label: \"Cut\" },\n  { value: \"copy\", label: \"Copy\", disabled: true },\n  { value: \"paste\", label: \"Paste\" },\n];\n\n<DropdownMenu items=ITEMS>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Edit</Button>\n  </@trigger>\n</DropdownMenu>","description":"Set `disabled` on an item to skip it in the tab order and block pointer input."},{"id":"dropdown-menu-selection","title":"Selection","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { value: \"edit\", label: \"Edit\" },\n  { value: \"duplicate\", label: \"Duplicate\" },\n  { value: \"archive\", label: \"Archive\" },\n  { type: \"separator\" },\n  { value: \"delete\", label: \"Delete\", variant: \"destructive\" },\n] satisfies DropdownMenuItem[];\n\n<let/selected=\"\"/>\n\n<div class=\"flex items-center gap-4\">\n  <DropdownMenu items=ITEMS select(value) { selected = value; }>\n    <@trigger|triggerProps|>\n      <Button type=\"button\" variant=\"outline\" ...triggerProps>Open menu</Button>\n    </@trigger>\n  </DropdownMenu>\n  <span class=\"text-sm text-muted-foreground\">selected: ${selected || \"none\"}</span>\n</div>","description":"Handle `select(value)` on the menu to react to whichever item was chosen."},{"id":"dropdown-menu-checkboxes","title":"Checkboxes","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<let/showStatusBar=true/>\n<let/showActivityBar=false/>\n<let/showPanel=false/>\n\n<const/items=[\n  { type: \"label\", label: \"Appearance\" },\n  { type: \"checkbox\", value: \"status-bar\", label: \"Status Bar\", checked: showStatusBar },\n  { type: \"checkbox\", value: \"activity-bar\", label: \"Activity Bar\", checked: showActivityBar, disabled: true },\n  { type: \"checkbox\", value: \"panel\", label: \"Panel\", checked: showPanel },\n] satisfies DropdownMenuItem[]/>\n\n<DropdownMenu\n  items=items\n  select(value) {\n    if (value === \"status-bar\") showStatusBar = !showStatusBar;\n    else if (value === \"activity-bar\") showActivityBar = !showActivityBar;\n    else if (value === \"panel\") showPanel = !showPanel;\n  }\n  class=\"w-40\"\n>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n</DropdownMenu>","description":"`type: \"checkbox\"` entries render a check indicator; toggle each `checked` flag from `select(value)`."},{"id":"dropdown-menu-checkboxes-icons","title":"Checkboxes with icons","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\n<let/email=true/>\n<let/sms=false/>\n<let/push=true/>\n\n<DropdownMenu\n  select(value) {\n    if (value === \"email\") email = !email;\n    else if (value === \"sms\") sms = !sms;\n    else if (value === \"push\") push = !push;\n  }\n  class=\"w-48\"\n>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Notifications</Button>\n  </@trigger>\n  <@item type=\"label\" label=\"Notification Preferences\"/>\n  <@item type=\"checkbox\" value=\"email\" checked=email>\n    <Icon name=\"Mail\"/>\n    Email notifications\n  </@item>\n  <@item type=\"checkbox\" value=\"sms\" checked=sms>\n    <Icon name=\"MessageSquareIcon\"/>\n    SMS notifications\n  </@item>\n  <@item type=\"checkbox\" value=\"push\" checked=push>\n    <Icon name=\"BellIcon\"/>\n    Push notifications\n  </@item>\n</DropdownMenu>","description":"Checkbox items can carry an icon before the label, same as regular items."},{"id":"dropdown-menu-radio-group","title":"Radio group","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<let/position=\"bottom\"/>\n\n<const/items=[\n  { type: \"label\", label: \"Panel Position\" },\n  { type: \"radio\", value: \"top\", label: \"Top\", checked: position === \"top\", radioGroup: \"position\" },\n  { type: \"radio\", value: \"bottom\", label: \"Bottom\", checked: position === \"bottom\", radioGroup: \"position\" },\n  { type: \"radio\", value: \"right\", label: \"Right\", checked: position === \"right\", radioGroup: \"position\" },\n] satisfies DropdownMenuItem[]/>\n\n<DropdownMenu\n  items=items\n  select(value) { position = value; }\n  class=\"w-32\"\n>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Open</Button>\n  </@trigger>\n</DropdownMenu>","description":"`type: \"radio\"` entries sharing a `radioGroup` name behave as an exclusive choice."},{"id":"dropdown-menu-radio-icons","title":"Radio icons","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\n<let/paymentMethod=\"card\"/>\n\n<DropdownMenu\n  select(value) { paymentMethod = value; }\n  class=\"min-w-56\"\n>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Payment Method</Button>\n  </@trigger>\n  <@item type=\"label\" label=\"Select Payment Method\"/>\n  <@item type=\"radio\" value=\"card\" radioGroup=\"payment\" checked=(paymentMethod === \"card\")>\n    <Icon name=\"CreditCard\"/>\n    Credit Card\n  </@item>\n  <@item type=\"radio\" value=\"paypal\" radioGroup=\"payment\" checked=(paymentMethod === \"paypal\")>\n    <Icon name=\"WalletIcon\"/>\n    PayPal\n  </@item>\n  <@item type=\"radio\" value=\"bank\" radioGroup=\"payment\" checked=(paymentMethod === \"bank\")>\n    <Icon name=\"Building2Icon\"/>\n    Bank Transfer\n  </@item>\n</DropdownMenu>","description":"Radio items can carry an icon before the label, same as regular items."},{"id":"dropdown-menu-destructive","title":"Danger action","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\nstatic const ITEMS = [\n  { value: \"rename\", label: \"Rename\" },\n  { value: \"duplicate\", label: \"Duplicate\" },\n  { type: \"separator\" },\n  { value: \"delete\", label: \"Delete\", variant: \"destructive\" },\n] satisfies DropdownMenuItem[];\n\n<DropdownMenu items=ITEMS>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"destructive\" ...triggerProps>Delete project</Button>\n  </@trigger>\n</DropdownMenu>","description":"Mark an item `variant=\"destructive\"` to style it as a destructive action, such as deleting a resource."},{"id":"dropdown-menu-avatar","title":"Avatar","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport Avatar from \"@marko-ui/shadcn/ui/avatar/avatar.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\nstatic const AVATAR_SRC =\n  \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Crect width='40' height='40' fill='%23404040'/%3E%3C/svg%3E\";\n\n<DropdownMenu class=\"w-auto\">\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"ghost\" size=\"icon\" class=\"rounded-full\" ...triggerProps>\n      <Avatar src=AVATAR_SRC alt=\"shadcn\" fallback=\"LR\"/>\n    </Button>\n  </@trigger>\n  <@item value=\"account\">\n    <Icon name=\"BadgeCheckIcon\"/>\n    Account\n  </@item>\n  <@item value=\"billing\">\n    <Icon name=\"CreditCard\"/>\n    Billing\n  </@item>\n  <@item value=\"notifications\">\n    <Icon name=\"BellIcon\"/>\n    Notifications\n  </@item>\n  <@item type=\"separator\"/>\n  <@item value=\"logout\">\n    <Icon name=\"LogOutIcon\"/>\n    Sign Out\n  </@item>\n</DropdownMenu>","description":"An account switcher triggered by an avatar instead of a labeled button."},{"id":"dropdown-menu-complex","title":"Complex","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\n<let/showSidebar=true/>\n<let/showStatusBar=false/>\n<let/theme=\"light\"/>\n\n<DropdownMenu\n  select(value) {\n    if (value === \"show-sidebar\") showSidebar = !showSidebar;\n    else if (value === \"show-status-bar\") showStatusBar = !showStatusBar;\n    else if (value === \"light\" || value === \"dark\" || value === \"system\") theme = value;\n  }\n  class=\"w-44\"\n>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Complex Menu</Button>\n  </@trigger>\n\n  <@item type=\"label\" label=\"File\"/>\n  <@item value=\"new-file\" shortcut=\"⌘N\">\n    <Icon name=\"FileIcon\"/>\n    New File\n  </@item>\n  <@item value=\"new-folder\" shortcut=\"⇧⌘N\">\n    <Icon name=\"FolderIcon\"/>\n    New Folder\n  </@item>\n  <@item\n    type=\"sub\"\n    label=\"Open Recent\"\n    subEntries=[\n      { type: \"label\", label: \"Recent Projects\" },\n      { value: \"project-alpha\", label: \"Project Alpha\" },\n      { value: \"project-beta\", label: \"Project Beta\" },\n      { type: \"separator\" },\n      { value: \"project-gamma\", label: \"Project Gamma\" },\n      { value: \"project-delta\", label: \"Project Delta\" },\n      { type: \"separator\" },\n      { value: \"browse\", label: \"Browse...\" },\n    ]\n  />\n  <@item type=\"separator\"/>\n  <@item value=\"save\" shortcut=\"⌘S\">\n    <Icon name=\"SaveIcon\"/>\n    Save\n  </@item>\n  <@item value=\"export\" shortcut=\"⇧⌘E\">\n    <Icon name=\"DownloadIcon\"/>\n    Export\n  </@item>\n  <@item type=\"separator\"/>\n\n  <@item type=\"label\" label=\"View\"/>\n  <@item type=\"checkbox\" value=\"show-sidebar\" checked=showSidebar>\n    <Icon name=\"EyeIcon\"/>\n    Show Sidebar\n  </@item>\n  <@item type=\"checkbox\" value=\"show-status-bar\" checked=showStatusBar>\n    <Icon name=\"LayoutIcon\"/>\n    Show Status Bar\n  </@item>\n  <@item\n    type=\"sub\"\n    label=\"Theme\"\n    subEntries=[\n      { type: \"label\", label: \"Appearance\" },\n      { type: \"radio\", value: \"light\", label: \"Light\", radioGroup: \"theme\", checked: theme === \"light\" },\n      { type: \"radio\", value: \"dark\", label: \"Dark\", radioGroup: \"theme\", checked: theme === \"dark\" },\n      { type: \"radio\", value: \"system\", label: \"System\", radioGroup: \"theme\", checked: theme === \"system\" },\n    ]\n  />\n  <@item type=\"separator\"/>\n\n  <@item type=\"label\" label=\"Account\"/>\n  <@item value=\"profile\" shortcut=\"⇧⌘P\">\n    <Icon name=\"User\"/>\n    Profile\n  </@item>\n  <@item value=\"billing\">\n    <Icon name=\"CreditCard\"/>\n    Billing\n  </@item>\n  <@item\n    type=\"sub\"\n    label=\"Settings\"\n    subEntries=[\n      { type: \"label\", label: \"Preferences\" },\n      { value: \"keyboard-shortcuts\", label: \"Keyboard Shortcuts\" },\n      { value: \"language\", label: \"Language\" },\n      { type: \"separator\" },\n      { type: \"label\", label: \"Notification Types\" },\n      { value: \"push-notifications\", label: \"Push Notifications\" },\n      { value: \"email-notifications\", label: \"Email Notifications\" },\n      { type: \"separator\" },\n      { value: \"privacy\", label: \"Privacy & Security\" },\n    ]\n  />\n  <@item type=\"separator\"/>\n\n  <@item value=\"help\">\n    <Icon name=\"HelpCircleIcon\"/>\n    Help & Support\n  </@item>\n  <@item value=\"docs\">\n    <Icon name=\"FileTextIcon\"/>\n    Documentation\n  </@item>\n  <@item type=\"separator\"/>\n  <@item value=\"sign-out\" shortcut=\"⇧⌘Q\" variant=\"destructive\">\n    <Icon name=\"LogOutIcon\"/>\n    Sign Out\n  </@item>\n</DropdownMenu>","description":"A richer menu combining groups, icons, checkboxes, a radio group, and submenus. Two technically-forced omissions: nesting is one level deep (upstream nests a third level in two places — 'Open Recent' > 'More Projects', 'Settings' > 'Notifications' — so each nested submenu's items are flattened into its parent, in order, with a separator marking the old nesting point), and icons cannot appear inside a submenu or on a `type: 'sub'` trigger (`subEntries` is plain `DropdownMenuItem[]`, and the sub branch renders its trigger as a plain string with no body slot) — which is why 'New File', 'Save' and 'Profile' keep their icons while 'Open Recent', 'Theme' and 'Settings' do not."},{"id":"dropdown-menu-compound","title":"Compound (attr tags)","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<DropdownMenu>\n  <@trigger|triggerProps|>\n    <Button type=\"button\" variant=\"outline\" ...triggerProps>Actions</Button>\n  </@trigger>\n  <@item value=\"edit\" shortcut=\"⌘E\">Edit</@item>\n  <@item value=\"duplicate\" label=\"Duplicate\"/>\n  <@item value=\"archive\" label=\"Archive\"/>\n  <@item type=\"separator\"/>\n  <@item value=\"delete\" label=\"Delete\" variant=\"destructive\"/>\n</DropdownMenu>","description":"Use `<@item>` attribute tags instead of `items=` to compose the menu directly in markup — pass `type=\"separator\"` for a divider or `type=\"label\"` for a group label. Entries render in the order they are written. An item's text can come from either a `label=` attribute or a markup body, whichever you prefer.","essential":true},{"id":"dropdown-menu-rtl","title":"RTL","source":"import DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<let/statusBar=true/>\n<let/activityBar=false/>\n<let/panel=false/>\n<let/position=\"bottom\"/>\n\n<const/items=[\n  {\n    type: \"sub\",\n    label: \"الحساب\",\n    subEntries: [\n      { value: \"profile\", label: \"الملف الشخصي\" },\n      { value: \"billing\", label: \"الفوترة\" },\n      { value: \"settings\", label: \"الإعدادات\" },\n    ],\n  },\n  { type: \"separator\" },\n  { type: \"label\", label: \"الفريق\" },\n  { value: \"team\", label: \"الفريق\" },\n  {\n    type: \"sub\",\n    label: \"دعوة المستخدمين\",\n    subEntries: [\n      { value: \"email\", label: \"البريد الإلكتروني\" },\n      { value: \"message\", label: \"رسالة\" },\n      { type: \"separator\" },\n      { value: \"calendar\", label: \"تقويم\" },\n      { value: \"chat\", label: \"دردشة\" },\n      { type: \"separator\" },\n      { value: \"webhook\", label: \"خطاف ويب\" },\n      { type: \"separator\" },\n      { value: \"advanced\", label: \"متقدم...\" },\n    ],\n  },\n  { value: \"new-team\", label: \"فريق جديد\", shortcut: \"⌘+T\" },\n  { type: \"separator\" },\n  { type: \"label\", label: \"عرض\" },\n  { type: \"checkbox\", value: \"status-bar\", label: \"شريط الحالة\", checked: statusBar },\n  { type: \"checkbox\", value: \"activity-bar\", label: \"شريط النشاط\", checked: activityBar },\n  { type: \"checkbox\", value: \"panel\", label: \"لوحة\", checked: panel },\n  { type: \"separator\" },\n  { type: \"label\", label: \"الموضع\" },\n  { type: \"radio\", value: \"top\", label: \"أعلى\", radioGroup: \"position\", checked: position === \"top\" },\n  { type: \"radio\", value: \"bottom\", label: \"أسفل\", radioGroup: \"position\", checked: position === \"bottom\" },\n  { type: \"radio\", value: \"right\", label: \"يمين\", radioGroup: \"position\", checked: position === \"right\" },\n  { type: \"radio\", value: \"left\", label: \"يسار\", radioGroup: \"position\", checked: position === \"left\" },\n  { type: \"separator\" },\n  { value: \"logout\", label: \"تسجيل الخروج\", variant: \"destructive\" },\n] satisfies DropdownMenuItem[]/>\n\n<div dir=\"rtl\" class=\"flex justify-center\">\n  <DropdownMenu\n    items=items\n    select(value) {\n      if (value === \"status-bar\") statusBar = !statusBar;\n      else if (value === \"activity-bar\") activityBar = !activityBar;\n      else if (value === \"panel\") panel = !panel;\n      else if (value === \"top\" || value === \"bottom\" || value === \"right\" || value === \"left\") position = value;\n    }\n    class=\"w-36\"\n  >\n    <@trigger|triggerProps|>\n      <Button type=\"button\" variant=\"outline\" ...triggerProps>افتح القائمة</Button>\n    </@trigger>\n  </DropdownMenu>\n</div>","description":"A `dir=\"rtl\"` wrapper with Arabic content, matching the precedent set by button/avatar/input's RTL demos. The underlying Zag menu machine does accept a `dir` prop for floating-ui placement flipping, but our `Input` type doesn't re-expose it yet (component-source change, out of scope here)."}],"importInstallCommand":"bun add @marko-ui/shadcn marko-zag","requires":["button"],"itemTypes":[{"prop":"items","typeName":"DropdownMenuItem","fields":[{"name":"type","type":"\"item\" | \"separator\" | \"label\" | \"checkbox\" | \"radio\" | \"sub\"","required":false},{"name":"value","type":"string","required":false},{"name":"label","type":"string","required":false},{"name":"disabled","type":"boolean","required":false},{"name":"shortcut","type":"string","required":false},{"name":"variant","type":"\"default\" | \"destructive\"","required":false,"description":"Upstream `variant: \"default\" | \"destructive\"`, emitted as `data-variant`."},{"name":"inset","type":"boolean","required":false,"description":"Emits `data-inset` — indents the entry to align with icon-bearing siblings."},{"name":"checked","type":"boolean","required":false,"description":"Checked state for `type=\"checkbox\"` and `type=\"radio\"` entries."},{"name":"radioGroup","type":"string","required":false,"description":"Groups radio items — required for `type: \"radio\"` entries."},{"name":"radioValue","type":"string","required":false,"description":"`type: \"radio\"` entries only — this entry's value within its `radioGroup`."},{"name":"subEntries","type":"readonly DropdownMenuItem[]","required":false,"description":"`type: \"sub\"` entries only — the nested submenu's own item list. One level deep: a `type: \"sub\"` entry inside a submenu's own `subEntries` is not wired (same limit as menubar's submenu)."}]}]}
