{
  "name": "DropdownMenu",
  "category": "Overlay",
  "subcategory": null,
  "description": "Menu button with items, separators, submenus, and checkboxes.",
  "thumbnail": "/preview-cards/dropdown-menu.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/DropdownMenu/DropdownMenu.razor",
    "UI/DropdownMenu/DropdownMenuCheckboxItem.razor",
    "UI/DropdownMenu/DropdownMenuContent.razor",
    "UI/DropdownMenu/DropdownMenuGroup.razor",
    "UI/DropdownMenu/DropdownMenuItem.razor",
    "UI/DropdownMenu/DropdownMenuLabel.razor",
    "UI/DropdownMenu/DropdownMenuRadioGroup.razor",
    "UI/DropdownMenu/DropdownMenuRadioItem.razor",
    "UI/DropdownMenu/DropdownMenuSeparator.razor",
    "UI/DropdownMenu/DropdownMenuTrigger.razor"
  ],
  "dependencies": [],
  "packageDependencies": [
    "Blazicons.Lucide"
  ],
  "cssVars": [
    "--color-accent",
    "--color-accent-foreground",
    "--color-border",
    "--color-popover",
    "--color-popover-foreground",
    "--radius"
  ],
  "api": {
    "name": "DropdownMenu",
    "category": "Overlay",
    "subcategory": null,
    "description": "Menu button with items, separators, submenus, and checkboxes.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/DropdownMenu/DropdownMenu.razor",
      "UI/DropdownMenu/DropdownMenuCheckboxItem.razor",
      "UI/DropdownMenu/DropdownMenuContent.razor",
      "UI/DropdownMenu/DropdownMenuGroup.razor",
      "UI/DropdownMenu/DropdownMenuItem.razor",
      "UI/DropdownMenu/DropdownMenuLabel.razor",
      "UI/DropdownMenu/DropdownMenuRadioGroup.razor",
      "UI/DropdownMenu/DropdownMenuRadioItem.razor",
      "UI/DropdownMenu/DropdownMenuSeparator.razor",
      "UI/DropdownMenu/DropdownMenuTrigger.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "ChildContent",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Open",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OpenChanged",
        "type": "EventCallback<bool>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsOpen",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsOpenChanged",
        "type": "EventCallback<bool>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "AdditionalAttributes",
        "type": "Dictionary<string, object>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": true
      }
    ],
    "events": [
      {
        "name": "OpenChanged",
        "type": "EventCallback<bool>",
        "description": null
      },
      {
        "name": "IsOpenChanged",
        "type": "EventCallback<bool>",
        "description": null
      }
    ],
    "enums": [],
    "records": [
      {
        "name": "DropdownMenuContext",
        "signature": "DropdownMenuContext(bool IsOpen, EventCallback<bool> SetOpen, string WrapperId, string ContentId)",
        "description": null
      }
    ],
    "cssVars": [
      "--color-accent",
      "--color-accent-foreground",
      "--color-border",
      "--color-popover",
      "--color-popover-foreground",
      "--radius"
    ],
    "examples": [
      {
        "title": "Default",
        "code": "<DropdownMenu>\n    <DropdownMenuTrigger>\n        <Button Variant=\"Button.ButtonVariant.Outline\">Open</Button>\n    </DropdownMenuTrigger>\n    <DropdownMenuContent>\n        <DropdownMenuLabel>My Account</DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>Profile</DropdownMenuItem>\n        <DropdownMenuItem>Settings</DropdownMenuItem>\n        <DropdownMenuItem>Billing</DropdownMenuItem>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>Log out</DropdownMenuItem>\n    </DropdownMenuContent>\n</DropdownMenu>"
      },
      {
        "title": "With Groups",
        "code": "<DropdownMenu>\n    <DropdownMenuTrigger>\n        <Button Variant=\"Button.ButtonVariant.Outline\">Actions</Button>\n    </DropdownMenuTrigger>\n    <DropdownMenuContent>\n        <DropdownMenuLabel>File</DropdownMenuLabel>\n        <DropdownMenuGroup>\n            <DropdownMenuItem>New File</DropdownMenuItem>\n            <DropdownMenuItem>Open File</DropdownMenuItem>\n            <DropdownMenuItem>Save</DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuLabel>Edit</DropdownMenuLabel>\n        <DropdownMenuGroup>\n            <DropdownMenuItem>Undo</DropdownMenuItem>\n            <DropdownMenuItem>Redo</DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem Disabled=\"true\">Delete</DropdownMenuItem>\n    </DropdownMenuContent>\n</DropdownMenu>"
      },
      {
        "title": "With Arrow",
        "code": "<DropdownMenu>\n    <DropdownMenuTrigger><Button Variant=\"Button.ButtonVariant.Outline\">Actions</Button></DropdownMenuTrigger>\n    <DropdownMenuContent ShowArrow=\"true\">\n        <DropdownMenuItem>Edit</DropdownMenuItem>\n        <DropdownMenuItem>Duplicate</DropdownMenuItem>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>Archive</DropdownMenuItem>\n    </DropdownMenuContent>\n</DropdownMenu>"
      },
      {
        "title": "Alignment",
        "code": "<DropdownMenu>\n    <DropdownMenuTrigger>\n        <Button Variant=\"Button.ButtonVariant.Outline\">Start</Button>\n    </DropdownMenuTrigger>\n    <DropdownMenuContent Align=\"DropdownMenuContent.DropdownMenuAlign.Start\">\n        <DropdownMenuItem>Option 1</DropdownMenuItem>\n        <DropdownMenuItem>Option 2</DropdownMenuItem>\n    </DropdownMenuContent>\n</DropdownMenu>\n\n<DropdownMenu>\n    <DropdownMenuTrigger>\n        <Button Variant=\"Button.ButtonVariant.Outline\">End</Button>\n    </DropdownMenuTrigger>\n    <DropdownMenuContent Align=\"DropdownMenuContent.DropdownMenuAlign.End\">\n        <DropdownMenuItem>Option 1</DropdownMenuItem>\n        <DropdownMenuItem>Option 2</DropdownMenuItem>\n    </DropdownMenuContent>\n</DropdownMenu>"
      }
    ],
    "subComponents": {
      "DropdownMenuCheckboxItem": {
        "componentName": "DropdownMenuCheckboxItem",
        "fileName": "DropdownMenuCheckboxItem.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Checked",
            "type": "bool",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "CheckedChanged",
            "type": "EventCallback<bool>",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [
          {
            "name": "CheckedChanged",
            "type": "EventCallback<bool>",
            "description": null
          }
        ],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuContent": {
        "componentName": "DropdownMenuContent",
        "fileName": "DropdownMenuContent.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [
          "IAsyncDisposable"
        ],
        "parameters": [
          {
            "name": "Context",
            "type": "DropdownMenu.DropdownMenuContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Align",
            "type": "DropdownMenuAlign",
            "default": "DropdownMenuAlign.Start",
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Side",
            "type": "DropdownMenuSide",
            "default": "DropdownMenuSide.Bottom",
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "ShowArrow",
            "type": "bool",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [
          {
            "name": "DropdownMenuAlign",
            "values": [
              "Start",
              "Center",
              "End"
            ],
            "description": null
          },
          {
            "name": "DropdownMenuSide",
            "values": [
              "Top",
              "Bottom",
              "Left",
              "Right"
            ],
            "description": null
          }
        ],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuGroup": {
        "componentName": "DropdownMenuGroup",
        "fileName": "DropdownMenuGroup.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AriaLabel",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuItem": {
        "componentName": "DropdownMenuItem",
        "fileName": "DropdownMenuItem.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Context",
            "type": "DropdownMenu.DropdownMenuContext?",
            "default": null,
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "OnClick",
            "type": "EventCallback",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Disabled",
            "type": "bool",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [
          {
            "name": "OnClick",
            "type": "EventCallback",
            "description": null
          }
        ],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuLabel": {
        "componentName": "DropdownMenuLabel",
        "fileName": "DropdownMenuLabel.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuRadioGroup": {
        "componentName": "DropdownMenuRadioGroup",
        "fileName": "DropdownMenuRadioGroup.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Value",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "ValueChanged",
            "type": "EventCallback<string>",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [
          {
            "name": "ValueChanged",
            "type": "EventCallback<string>",
            "description": null
          }
        ],
        "enums": [],
        "records": [
          {
            "name": "DropdownMenuRadioGroupContext",
            "signature": "DropdownMenuRadioGroupContext(string? Value, EventCallback<string> OnSelect)",
            "description": null
          }
        ],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuRadioItem": {
        "componentName": "DropdownMenuRadioItem",
        "fileName": "DropdownMenuRadioItem.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Context",
            "type": "DropdownMenuRadioGroup.DropdownMenuRadioGroupContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Value",
            "type": "string",
            "default": "\"\"",
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuSeparator": {
        "componentName": "DropdownMenuSeparator",
        "fileName": "DropdownMenuSeparator.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DropdownMenuTrigger": {
        "componentName": "DropdownMenuTrigger",
        "fileName": "DropdownMenuTrigger.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Context",
            "type": "DropdownMenu.DropdownMenuContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Class",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "AdditionalAttributes",
            "type": "Dictionary<string, object>?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": true
          }
        ],
        "events": [],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      }
    },
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "dropdown-menu",
  "docsUrl": "https://lumeo.nativ.sh/components/dropdown-menu",
  "sourceUrl": [
    {
      "file": "UI/DropdownMenu/DropdownMenu.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenu.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuCheckboxItem.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuCheckboxItem.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuContent.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuContent.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuGroup.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuGroup.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuItem.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuItem.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuLabel.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuLabel.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuRadioGroup.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuRadioGroup.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuRadioItem.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuRadioItem.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuSeparator.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuSeparator.razor"
    },
    {
      "file": "UI/DropdownMenu/DropdownMenuTrigger.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/DropdownMenu/DropdownMenuTrigger.razor"
    }
  ],
  "source": [
    {
      "path": "UI/DropdownMenu/DropdownMenu.razor",
      "content": "@namespace Lumeo\n\n@{\n    var context = new DropdownMenuContext(Open, EventCallback.Factory.Create<bool>(this, SetOpen), _wrapperId, _contentId);\n}\n\n<CascadingValue Value=\"context\" IsFixed=\"false\">\n    <div id=\"@_wrapperId\" class=\"relative inline-block\" @attributes=\"AdditionalAttributes\">\n        @ChildContent\n    </div>\n</CascadingValue>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public bool Open { get; set; }\n    [Parameter] public EventCallback<bool> OpenChanged { get; set; }\n\n    [Obsolete(\"Use Open instead. IsOpen will be removed in a future release.\")]\n    [Parameter] public bool IsOpen { get => Open; set => Open = value; }\n\n    [Obsolete(\"Use OpenChanged instead. IsOpenChanged will be removed in a future release.\")]\n    [Parameter] public EventCallback<bool> IsOpenChanged { get => OpenChanged; set => OpenChanged = value; }\n\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private readonly string _wrapperId = $\"dropdown-{Guid.NewGuid():N}\";\n    // Stable content id shared with trigger via context for aria-controls\n    internal readonly string _contentId = $\"dropdown-content-{Guid.NewGuid():N}\";\n\n    private async Task SetOpen(bool value)\n    {\n        Open = value;\n        await OpenChanged.InvokeAsync(value);\n    }\n\n    public record DropdownMenuContext(bool IsOpen, EventCallback<bool> SetOpen, string WrapperId, string ContentId);\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuCheckboxItem.razor",
      "content": "@namespace Lumeo\n\n<button type=\"button\" role=\"menuitemcheckbox\" aria-checked=\"@Checked.ToString().ToLower()\" tabindex=\"-1\" class=\"@CssClass\" @onclick=\"Toggle\" @attributes=\"AdditionalAttributes\">\n    <span class=\"flex h-3.5 w-3.5 items-center justify-center\">\n        @if (Checked)\n        {\n            <Blazicon Svg=\"Lucide.Check\" class=\"h-3.5 w-3.5\" />\n        }\n    </span>\n    @ChildContent\n</button>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public bool Checked { get; set; }\n    [Parameter] public EventCallback<bool> CheckedChanged { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground {Class}\".Trim();\n\n    private async Task Toggle()\n    {\n        Checked = !Checked;\n        await CheckedChanged.InvokeAsync(Checked);\n    }\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuContent.razor",
      "content": "@namespace Lumeo\n@implements IAsyncDisposable\n\n@if (Context.IsOpen)\n{\n    <div id=\"@Context.ContentId\"\n         role=\"menu\"\n         aria-orientation=\"vertical\"\n         class=\"@CssClass\"\n         @onkeydown=\"HandleKeyDown\"\n         tabindex=\"-1\"\n         @attributes=\"AdditionalAttributes\">\n        @ChildContent\n        @if (ShowArrow)\n        {\n            <div class=\"@ArrowClasses\"></div>\n        }\n    </div>\n}\n\n@inject ComponentInteropService Interop\n\n@code {\n    [CascadingParameter] public DropdownMenu.DropdownMenuContext Context { get; set; } = default!;\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public DropdownMenuAlign Align { get; set; } = DropdownMenuAlign.Start;\n    [Parameter] public DropdownMenuSide Side { get; set; } = DropdownMenuSide.Bottom;\n    [Parameter] public bool ShowArrow { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private bool _registered;\n    private int _focusedIndex = -1;\n\n    private string CssClass => string.Join(\" \", new[] { \"fixed z-50 min-w-[8rem] rounded-md border border-border/60 bg-popover p-1 text-popover-foreground shadow-lg animate-fade-in\", ShowArrow ? \"overflow-visible\" : \"overflow-hidden\", Class }.Where(s => !string.IsNullOrWhiteSpace(s)));\n\n    private string ArrowClasses => Side switch\n    {\n        DropdownMenuSide.Top => \"absolute left-1/2 top-full -translate-x-1/2 -translate-y-1/2 rotate-45 h-2.5 w-2.5 bg-popover border-b border-r border-border/60\",\n        DropdownMenuSide.Bottom => \"absolute left-1/2 bottom-full -translate-x-1/2 translate-y-1/2 rotate-45 h-2.5 w-2.5 bg-popover border-t border-l border-border/60\",\n        DropdownMenuSide.Left => \"absolute top-1/2 left-full -translate-y-1/2 -translate-x-1/2 rotate-45 h-2.5 w-2.5 bg-popover border-t border-r border-border/60\",\n        DropdownMenuSide.Right => \"absolute top-1/2 right-full -translate-y-1/2 translate-x-1/2 rotate-45 h-2.5 w-2.5 bg-popover border-b border-l border-border/60\",\n        _ => \"absolute left-1/2 bottom-full -translate-x-1/2 translate-y-1/2 rotate-45 h-2.5 w-2.5 bg-popover border-t border-l border-border/60\"\n    };\n\n    private string AlignStr => Align switch\n    {\n        DropdownMenuAlign.Start => \"start\",\n        DropdownMenuAlign.Center => \"center\",\n        DropdownMenuAlign.End => \"end\",\n        _ => \"start\"\n    };\n\n    private string SideStr => Side switch\n    {\n        DropdownMenuSide.Top => \"top\",\n        DropdownMenuSide.Left => \"left\",\n        DropdownMenuSide.Right => \"right\",\n        _ => \"bottom\"\n    };\n\n    protected override async Task OnAfterRenderAsync(bool firstRender)\n    {\n        if (Context.IsOpen && !_registered)\n        {\n            await Interop.PositionFixed(Context.ContentId, Context.WrapperId, AlignStr, false, SideStr);\n            await Interop.RegisterClickOutside(Context.ContentId, null, async () =>\n            {\n                await Context.SetOpen.InvokeAsync(false);\n                await InvokeAsync(StateHasChanged);\n            });\n            _registered = true;\n            _focusedIndex = -1;\n\n            // Move focus to the menu container so Escape/ArrowUp/ArrowDown reach\n            // the @onkeydown handler. Without this, focus stays on the trigger\n            // button and keyboard nav silently breaks (per WAI-ARIA menu pattern).\n            try { await Interop.FocusElement(Context.ContentId); } catch (JSDisconnectedException) { }\n        }\n        else if (!Context.IsOpen && _registered)\n        {\n            await Cleanup();\n        }\n    }\n\n    private async Task HandleKeyDown(KeyboardEventArgs e)\n    {\n        switch (e.Key)\n        {\n            case \"Escape\":\n                await Context.SetOpen.InvokeAsync(false);\n                break;\n            case \"ArrowDown\":\n                {\n                    var count = await Interop.GetMenuItemCount(Context.ContentId);\n                    if (count > 0)\n                    {\n                        _focusedIndex = (_focusedIndex + 1) % count;\n                        await Interop.FocusMenuItemByIndex(Context.ContentId, _focusedIndex);\n                    }\n                    break;\n                }\n            case \"ArrowUp\":\n                {\n                    var count = await Interop.GetMenuItemCount(Context.ContentId);\n                    if (count > 0)\n                    {\n                        _focusedIndex = _focusedIndex <= 0 ? count - 1 : _focusedIndex - 1;\n                        await Interop.FocusMenuItemByIndex(Context.ContentId, _focusedIndex);\n                    }\n                    break;\n                }\n            case \"Home\":\n                {\n                    var count = await Interop.GetMenuItemCount(Context.ContentId);\n                    if (count > 0)\n                    {\n                        _focusedIndex = 0;\n                        await Interop.FocusMenuItemByIndex(Context.ContentId, _focusedIndex);\n                    }\n                    break;\n                }\n            case \"End\":\n                {\n                    var count = await Interop.GetMenuItemCount(Context.ContentId);\n                    if (count > 0)\n                    {\n                        _focusedIndex = count - 1;\n                        await Interop.FocusMenuItemByIndex(Context.ContentId, _focusedIndex);\n                    }\n                    break;\n                }\n        }\n    }\n\n    private async Task Cleanup()\n    {\n        try { await Interop.UnpositionFixed(Context.ContentId); } catch (JSDisconnectedException) { }\n        try { await Interop.UnregisterClickOutside(Context.ContentId); } catch (JSDisconnectedException) { }\n        _registered = false;\n    }\n\n    public async ValueTask DisposeAsync()\n    {\n        if (_registered) await Cleanup();\n    }\n\n    public enum DropdownMenuAlign { Start, Center, End }\n    public enum DropdownMenuSide { Top, Bottom, Left, Right }\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuGroup.razor",
      "content": "@namespace Lumeo\n\n<div role=\"group\" aria-label=\"@AriaLabel\" class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? AriaLabel { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"{Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuItem.razor",
      "content": "@namespace Lumeo\n\n<button class=\"@CssClass\" role=\"menuitem\" tabindex=\"-1\" @onclick=\"HandleClick\" disabled=\"@Disabled\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</button>\n\n@code {\n    [CascadingParameter] public DropdownMenu.DropdownMenuContext? Context { get; set; }\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public EventCallback OnClick { get; set; }\n    [Parameter] public bool Disabled { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 min-h-11 sm:min-h-0 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed {Class}\".Trim();\n\n    private async Task HandleClick()\n    {\n        await OnClick.InvokeAsync();\n        if (Context is not null)\n        {\n            await Context.SetOpen.InvokeAsync(false);\n        }\n    }\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuLabel.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"px-2 py-1.5 text-sm font-semibold {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuRadioGroup.razor",
      "content": "@namespace Lumeo\n\n@{\n    var context = new DropdownMenuRadioGroupContext(Value, EventCallback.Factory.Create<string>(this, OnValueSelected));\n}\n\n<CascadingValue Value=\"context\" IsFixed=\"false\">\n    <div role=\"group\" @attributes=\"AdditionalAttributes\">\n        @ChildContent\n    </div>\n</CascadingValue>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Value { get; set; }\n    [Parameter] public EventCallback<string> ValueChanged { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private async Task OnValueSelected(string value)\n    {\n        Value = value;\n        await ValueChanged.InvokeAsync(value);\n    }\n\n    public record DropdownMenuRadioGroupContext(string? Value, EventCallback<string> OnSelect);\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuRadioItem.razor",
      "content": "@namespace Lumeo\n\n<button type=\"button\" role=\"menuitemradio\" aria-checked=\"@IsSelected.ToString().ToLower()\" tabindex=\"-1\" class=\"@CssClass\" @onclick=\"Select\" @attributes=\"AdditionalAttributes\">\n    <span class=\"flex h-3.5 w-3.5 items-center justify-center\">\n        @if (IsSelected)\n        {\n            <Blazicon Svg=\"Lucide.Circle\" class=\"h-2 w-2 fill-current\" />\n        }\n    </span>\n    @ChildContent\n</button>\n\n@code {\n    [CascadingParameter] public DropdownMenuRadioGroup.DropdownMenuRadioGroupContext Context { get; set; } = default!;\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter, EditorRequired] public string Value { get; set; } = \"\";\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private bool IsSelected => Context.Value == Value;\n\n    private string CssClass => $\"relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground {Class}\".Trim();\n\n    private async Task Select() => await Context.OnSelect.InvokeAsync(Value);\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuSeparator.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@CssClass\" role=\"none\" @attributes=\"AdditionalAttributes\"></div>\n\n@code {\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"-mx-1 my-1 h-px bg-border {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/DropdownMenu/DropdownMenuTrigger.razor",
      "content": "@namespace Lumeo\n\n@* The `group` class + `data-state` attribute let consumers rotate a chevron on open with\n   `group-data-[state=open]:rotate-180` on any descendant icon — no EventCallbacks or bindings needed. *@\n<div id=\"@_triggerId\"\n     class=\"@CssClass\"\n     role=\"button\"\n     data-state=\"@(Context.IsOpen ? \"open\" : \"closed\")\"\n     aria-haspopup=\"menu\"\n     aria-expanded=\"@Context.IsOpen.ToString().ToLower()\"\n     aria-controls=\"@Context.ContentId\"\n     @onclick=\"Toggle\"\n     @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [CascadingParameter] public DropdownMenu.DropdownMenuContext Context { get; set; } = default!;\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    internal string TriggerId => _triggerId;\n    private readonly string _triggerId = $\"dropdown-trigger-{Guid.NewGuid():N}\";\n\n    private string CssClass => $\"group inline-flex {Class}\".Trim();\n\n    private async Task Toggle() => await Context.SetOpen.InvokeAsync(!Context.IsOpen);\n}\n"
    }
  ],
  "slots": [
    {
      "name": "ChildContent",
      "owner": "DropdownMenu",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuCheckboxItem",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuContent",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuGroup",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuItem",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuLabel",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuRadioGroup",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuRadioItem",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DropdownMenuTrigger",
      "type": "RenderFragment?",
      "description": null
    }
  ],
  "serviceDependencies": [
    {
      "service": "ComponentInteropService",
      "namespace": ""
    }
  ],
  "cascadingDependencies": [
    {
      "name": "Context",
      "type": "DropdownMenu.DropdownMenuContext",
      "required": true
    }
  ],
  "relatedComponents": [
    {
      "name": "DropdownMenuCheckboxItem",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuContent",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuGroup",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuItem",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuLabel",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuRadioGroup",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuRadioItem",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuSeparator",
      "reason": "sub-component"
    },
    {
      "name": "DropdownMenuTrigger",
      "reason": "sub-component"
    }
  ],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests.E2E/Smokes/DropdownKeyboardTests.cs",
    "tests/Lumeo.Tests/Components/DropdownMenu/DropdownMenuTests.cs"
  ],
  "mdSummary": "# DropdownMenu\n\nMenu button with items, separators, submenus, and checkboxes.\n\n**Package:** `Lumeo` · **Category:** Overlay\n**Docs:** https://lumeo.nativ.sh/components/dropdown-menu\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| DropdownMenu | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenu | Open | `bool` | `` |  |\n| DropdownMenu | OpenChanged | `EventCallback<bool>` | `` |  |\n| DropdownMenu | IsOpen | `bool` | `` |  |\n| DropdownMenu | IsOpenChanged | `EventCallback<bool>` | `` |  |\n| DropdownMenu | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuCheckboxItem | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuCheckboxItem | Checked | `bool` | `` |  |\n| DropdownMenuCheckboxItem | CheckedChanged | `EventCallback<bool>` | `` |  |\n| DropdownMenuCheckboxItem | Class | `string?` | `` |  |\n| DropdownMenuCheckboxItem | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuContent | Context | `DropdownMenu.DropdownMenuContext` | `default!` |  |\n| DropdownMenuContent | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuContent | Align | `DropdownMenuAlign` | `DropdownMenuAlign.Start` |  |\n| DropdownMenuContent | Side | `DropdownMenuSide` | `DropdownMenuSide.Bottom` |  |\n| DropdownMenuContent | ShowArrow | `bool` | `` |  |\n| DropdownMenuContent | Class | `string?` | `` |  |\n| DropdownMenuContent | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuGroup | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuGroup | AriaLabel | `string?` | `` |  |\n| DropdownMenuGroup | Class | `string?` | `` |  |\n| DropdownMenuGroup | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuItem | Context | `DropdownMenu.DropdownMenuContext?` | `` |  |\n| DropdownMenuItem | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuItem | OnClick | `EventCallback` | `` |  |\n| DropdownMenuItem | Disabled | `bool` | `` |  |\n| DropdownMenuItem | Class | `string?` | `` |  |\n| DropdownMenuItem | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuLabel | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuLabel | Class | `string?` | `` |  |\n| DropdownMenuLabel | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuRadioGroup | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuRadioGroup | Value | `string?` | `` |  |\n| DropdownMenuRadioGroup | ValueChanged | `EventCallback<string>` | `` |  |\n| DropdownMenuRadioGroup | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuRadioItem | Context | `DropdownMenuRadioGroup.DropdownMenuRadioGroupContext` | `default!` |  |\n| DropdownMenuRadioItem | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuRadioItem | Value | `string` | `\"\"` |  |\n| DropdownMenuRadioItem | Class | `string?` | `` |  |\n| DropdownMenuRadioItem | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuSeparator | Class | `string?` | `` |  |\n| DropdownMenuSeparator | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DropdownMenuTrigger | Context | `DropdownMenu.DropdownMenuContext` | `default!` |  |\n| DropdownMenuTrigger | ChildContent | `RenderFragment?` | `` |  |\n| DropdownMenuTrigger | Class | `string?` | `` |  |\n| DropdownMenuTrigger | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `ChildContent` (DropdownMenu) — RenderFragment slot\n- `ChildContent` (DropdownMenuCheckboxItem) — RenderFragment slot\n- `ChildContent` (DropdownMenuContent) — RenderFragment slot\n- `ChildContent` (DropdownMenuGroup) — RenderFragment slot\n- `ChildContent` (DropdownMenuItem) — RenderFragment slot\n- `ChildContent` (DropdownMenuLabel) — RenderFragment slot\n- `ChildContent` (DropdownMenuRadioGroup) — RenderFragment slot\n- `ChildContent` (DropdownMenuRadioItem) — RenderFragment slot\n- `ChildContent` (DropdownMenuTrigger) — RenderFragment slot\n\n## Events\n- `OpenChanged` (`EventCallback<bool>`)\n- `IsOpenChanged` (`EventCallback<bool>`)\n\n## Sub-components\n- `DropdownMenuCheckboxItem`, `DropdownMenuContent`, `DropdownMenuGroup`, `DropdownMenuItem`, `DropdownMenuLabel`, `DropdownMenuRadioGroup`, `DropdownMenuRadioItem`, `DropdownMenuSeparator`, `DropdownMenuTrigger`\n\n## Cascading values it expects\n- `Context` (`DropdownMenu.DropdownMenuContext`)\n\n## Services it injects\n- `ComponentInteropService` ()\n\n## Keyboard\n—\n\n## Example\n```razor\n<DropdownMenu />\n```\n\n## CSS variables\n`--color-accent`, `--color-accent-foreground`, `--color-border`, `--color-popover`, `--color-popover-foreground`, `--radius`\n\n## Files\n- `UI/DropdownMenu/DropdownMenu.razor`\n- `UI/DropdownMenu/DropdownMenuCheckboxItem.razor`\n- `UI/DropdownMenu/DropdownMenuContent.razor`\n- `UI/DropdownMenu/DropdownMenuGroup.razor`\n- `UI/DropdownMenu/DropdownMenuItem.razor`\n- `UI/DropdownMenu/DropdownMenuLabel.razor`\n- `UI/DropdownMenu/DropdownMenuRadioGroup.razor`\n- `UI/DropdownMenu/DropdownMenuRadioItem.razor`\n- `UI/DropdownMenu/DropdownMenuSeparator.razor`\n- `UI/DropdownMenu/DropdownMenuTrigger.razor`\n"
}