{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dropdown-menu",
  "type": "registry:ui",
  "title": "Dropdown Menu",
  "description": "Menu of actions from a button. Native Popover API + APG menu keyboard contract (arrows, Home/End, type-to-find).",
  "files": [
    {
      "path": "registry/ui/dropdown-menu.tsx",
      "type": "registry:ui",
      "target": "components/ui/dropdown-menu.tsx",
      "content": "/** @jsxImportSource hono/jsx */\nimport type { PropsWithChildren } from \"hono/jsx\"\nimport { cn, type ClassValue } from \"@/registry/lib/cn\"\n\n// Dropdown Menu — shadcn-htmx, htmx v4 + Tailwind v4.\n//\n// Built on top of the native HTML Popover API (popover + popovertarget),\n// so the platform gives us:\n//   - Light dismiss when the user clicks outside.\n//   - ESC closes the menu.\n//   - Top-layer rendering.\n//   - Focus restoration to the trigger after close.\n//\n// On top, public/site.js implements the APG menu keyboard contract:\n//   - ArrowDown / ArrowUp move focus between menuitems.\n//   - Home / End jump to first / last.\n//   - Type-to-find: pressing a letter focuses the next menuitem whose\n//     label starts with that letter.\n//   - Enter / Space activate the focused item.\n//\n// Refs:\n//   repos/aria-practices/content/patterns/menu-button/\n//   repos/mdn/files/en-us/web/accessibility/aria/reference/roles/menu_role/\n\nexport type DropdownMenuSide = \"top\" | \"right\" | \"bottom\" | \"left\"\n\ntype DropdownMenuProps = PropsWithChildren<{\n  // Required — matches popovertarget on the trigger.\n  id: string\n  // Which side of the trigger the menu opens on. site.js reads data-side\n  // and positions the popover via JS (CSS Anchor Positioning isn't yet\n  // shipped in every browser).\n  side?: DropdownMenuSide\n  // role=\"menu\" REQUIRES an accessible name. Point aria-labelledby at the\n  // trigger's id (canonical menu-button wiring) or pass aria-label for\n  // icon-only triggers.\n  // menu_role: aria-labelledby=\"menubutton\".\n  ariaLabelledBy?: string\n  ariaLabel?: string\n  class?: ClassValue\n}>\n\nexport function DropdownMenu(props: DropdownMenuProps) {\n  const { id, side = \"bottom\", ariaLabelledBy, ariaLabel, class: className, children } = props\n  return (\n    <div\n      id={id}\n      popover=\"auto\"\n      role=\"menu\"\n      aria-labelledby={ariaLabelledBy}\n      aria-label={ariaLabel}\n      data-slot=\"dropdown-menu\"\n      data-side={side}\n      class={cn(\n        \"z-50 m-0 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none\",\n        \"[&:not(:popover-open)]:hidden\",\n        \"[&:popover-open]:animate-[scn-popover-in_120ms_ease-out]\",\n        className,\n      )}\n    >\n      {children}\n    </div>\n  )\n}\n\ntype DropdownMenuTriggerProps = PropsWithChildren<{\n  menuFor: string\n  class?: ClassValue\n  id?: string\n}>\n\nexport function DropdownMenuTrigger(props: DropdownMenuTriggerProps) {\n  return (\n    <button\n      id={props.id}\n      type=\"button\"\n      popovertarget={props.menuFor}\n      popovertargetaction=\"toggle\"\n      data-slot=\"dropdown-menu-trigger\"\n      aria-haspopup=\"menu\"\n      // menu-button pattern: advertise the controlled menu and its state.\n      // Initial state is collapsed; site.js flips aria-expanded on toggle.\n      aria-controls={props.menuFor}\n      aria-expanded=\"false\"\n      class={cn(props.class)}\n    >\n      {props.children}\n    </button>\n  )\n}\n\ntype DropdownMenuItemProps = PropsWithChildren<{\n  // Action when the item is activated. Most calls just need `onClickHref`\n  // or pass htmx attrs; we keep the API thin.\n  onclick?: string\n  href?: string\n  disabled?: boolean\n  // Show as a destructive/danger menu item (red).\n  variant?: \"default\" | \"destructive\"\n  class?: ClassValue\n  // htmx attributes ride along onto the button/anchor.\n  \"hx-get\"?: string\n  \"hx-post\"?: string\n  \"hx-target\"?: string\n  \"hx-swap\"?: string\n  \"hx-trigger\"?: string\n}>\n\nexport function DropdownMenuItem(props: DropdownMenuItemProps) {\n  const { children, onclick, href, disabled, variant = \"default\", class: className, ...rest } = props\n  const itemBase =\n    \"relative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none \" +\n    \"focus:bg-accent focus:text-accent-foreground \" +\n    \"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 \" +\n    \"[&_svg]:size-4 [&_svg]:shrink-0\"\n  const variantCls =\n    variant === \"destructive\"\n      ? \"text-destructive focus:bg-destructive/10 focus:text-destructive\"\n      : \"\"\n  const Tag: any = href ? \"a\" : \"button\"\n  return (\n    <Tag\n      role=\"menuitem\"\n      type={href ? undefined : \"button\"}\n      tabindex={-1}\n      href={href}\n      onclick={onclick}\n      data-slot=\"dropdown-menu-item\"\n      data-disabled={disabled ? \"true\" : undefined}\n      // menuitem_role: a disabled menuitem MUST set aria-disabled=\"true\"\n      // (data-disabled stays for the CSS/keyboard-skip selectors).\n      aria-disabled={disabled ? \"true\" : undefined}\n      class={cn(itemBase, variantCls, className)}\n      {...rest}\n    >\n      {children}\n    </Tag>\n  )\n}\n\nexport function DropdownMenuSeparator(props: { class?: ClassValue }) {\n  return (\n    <div\n      role=\"separator\"\n      data-slot=\"dropdown-menu-separator\"\n      class={cn(\"-mx-1 my-1 h-px bg-border\", props.class)}\n    />\n  )\n}\n\nexport function DropdownMenuLabel(\n  props: PropsWithChildren<{ class?: ClassValue }>,\n) {\n  return (\n    <div\n      data-slot=\"dropdown-menu-label\"\n      class={cn(\"px-2 py-1.5 text-xs font-semibold tracking-wider text-muted-foreground uppercase\", props.class)}\n    >\n      {props.children}\n    </div>\n  )\n}\n"
    },
    {
      "path": "registry/jinja2/dropdown-menu.html",
      "type": "registry:file",
      "target": "templates/components/dropdown-menu.html",
      "content": "{# DropdownMenu macros — shadcn-htmx, htmx v4 + Tailwind v4.\n   Native [popover] + APG menu keyboard contract via public/site.js. #}\n\n{% macro dropdown_trigger(label, menu_for, class_=\"\", id=none) %}\n{# menu-button pattern: aria-controls + aria-expanded advertise the menu and\n   its state. Initial state collapsed; site.js flips aria-expanded on toggle. #}\n<button {% if id %}id=\"{{ id }}\"{% endif %} type=\"button\"\n        popovertarget=\"{{ menu_for }}\" popovertargetaction=\"toggle\"\n        data-slot=\"dropdown-menu-trigger\" aria-haspopup=\"menu\"\n        aria-controls=\"{{ menu_for }}\" aria-expanded=\"false\"\n        class=\"{{ class_ }}\">{{ label }}</button>\n{% endmacro %}\n\n{% macro dropdown_open(id, side=\"bottom\", extra_class=\"\", aria_labelledby=none, aria_label=none) %}\n{%- set sides = {\n    \"top\":    \"anchor-popover-top\",\n    \"bottom\": \"anchor-popover-bottom\",\n    \"left\":   \"anchor-popover-left\",\n    \"right\":  \"anchor-popover-right\"\n} -%}\n{# role=\"menu\" REQUIRES an accessible name: aria-labelledby (canonical, points\n   at the trigger id) or aria-label for icon-only triggers. menu_role. #}\n<div id=\"{{ id }}\" popover=\"auto\" role=\"menu\"\n     {%- if aria_labelledby %} aria-labelledby=\"{{ aria_labelledby }}\"{% endif %}\n     {%- if aria_label %} aria-label=\"{{ aria_label }}\"{% endif %}\n     data-slot=\"dropdown-menu\" data-side=\"{{ side }}\"\n     class=\"z-50 m-0 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none [&:not(:popover-open)]:hidden [&:popover-open]:animate-[scn-popover-in_120ms_ease-out] {{ sides[side] }} {{ extra_class }}\">\n{% endmacro %}\n\n{% macro dropdown_close() %}</div>{% endmacro %}\n\n{% macro dropdown_item(label, href=none, onclick=none, disabled=false, variant=\"default\", extra_class=\"\", **attrs) %}\n{%- set base -%}\nrelative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0\n{%- endset -%}\n{%- set destructive -%}\n{% if variant == \"destructive\" %}text-destructive focus:bg-destructive/10 focus:text-destructive{% endif %}\n{%- endset -%}\n{% if href %}\n<a role=\"menuitem\" tabindex=\"-1\" href=\"{{ href }}\"\n   data-slot=\"dropdown-menu-item\"\n   {#- menuitem_role: a disabled menuitem MUST set aria-disabled=\"true\". #}\n   {%- if disabled %} data-disabled=\"true\" aria-disabled=\"true\"{% endif %}\n   class=\"{{ base }} {{ destructive }} {{ extra_class }}\"\n   {%- for k, v in attrs.items() %} {{ k|replace('_', '-') }}=\"{{ v }}\"{% endfor -%}\n>{{ label }}</a>\n{% else %}\n<button type=\"button\" role=\"menuitem\" tabindex=\"-1\"\n        {% if onclick %}onclick=\"{{ onclick }}\"{% endif %}\n        data-slot=\"dropdown-menu-item\"\n        {#- menuitem_role: a disabled menuitem MUST set aria-disabled=\"true\". #}\n        {%- if disabled %} data-disabled=\"true\" aria-disabled=\"true\"{% endif %}\n        class=\"{{ base }} {{ destructive }} {{ extra_class }}\"\n        {%- for k, v in attrs.items() %} {{ k|replace('_', '-') }}=\"{{ v }}\"{% endfor -%}\n>{{ label }}</button>\n{% endif %}\n{% endmacro %}\n\n{% macro dropdown_separator() %}\n<div role=\"separator\" data-slot=\"dropdown-menu-separator\" class=\"-mx-1 my-1 h-px bg-border\"></div>\n{% endmacro %}\n\n{% macro dropdown_label(text) %}\n<div data-slot=\"dropdown-menu-label\" class=\"px-2 py-1.5 text-xs font-semibold tracking-wider text-muted-foreground uppercase\">{{ text }}</div>\n{% endmacro %}\n"
    },
    {
      "path": "registry/go-templates/dropdown-menu.tmpl",
      "type": "registry:file",
      "target": "components/dropdown-menu.tmpl",
      "content": "{{/* DropdownMenu templates — shadcn-htmx, htmx v4 + Tailwind v4.\n     Native [popover] + APG menu keyboard contract via public/site.js. */}}\n\n{{define \"dropdown_trigger\"}}\n{{/* menu-button pattern: aria-controls + aria-expanded advertise the menu and\n     its state. Initial state collapsed; site.js flips aria-expanded on toggle. */}}\n<button {{if .ID}}id=\"{{.ID}}\"{{end}} type=\"button\"\n        popovertarget=\"{{.MenuFor}}\" popovertargetaction=\"toggle\"\n        data-slot=\"dropdown-menu-trigger\" aria-haspopup=\"menu\"\n        aria-controls=\"{{.MenuFor}}\" aria-expanded=\"false\"\n        class=\"{{.Class}}\">{{.Label}}</button>\n{{end}}\n\n{{define \"dropdown_menu\"}}\n{{/* role=\"menu\" REQUIRES an accessible name: AriaLabelledBy (canonical, points\n     at the trigger id) or AriaLabel for icon-only triggers. menu_role. */}}\n<div id=\"{{.ID}}\" popover=\"auto\" role=\"menu\"\n     {{- if .AriaLabelledBy}} aria-labelledby=\"{{.AriaLabelledBy}}\"{{end}}\n     {{- if .AriaLabel}} aria-label=\"{{.AriaLabel}}\"{{end}}\n     data-slot=\"dropdown-menu\"\n     class=\"z-50 m-0 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none [&:not(:popover-open)]:hidden [&:popover-open]:animate-[scn-popover-in_120ms_ease-out] anchor-popover-bottom\">\n  {{.Body}}\n</div>\n{{end}}\n\n{{define \"dropdown_item\"}}\n{{- $variant := or .Variant \"default\" -}}\n{{- $base := \"relative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0\" -}}\n{{- $destr := \"\" -}}{{- if eq $variant \"destructive\" -}}{{- $destr = \"text-destructive focus:bg-destructive/10 focus:text-destructive\" -}}{{- end -}}\n{{if .Href}}\n<a role=\"menuitem\" tabindex=\"-1\" href=\"{{.Href}}\" data-slot=\"dropdown-menu-item\"\n   {{/* menuitem_role: a disabled menuitem MUST set aria-disabled=\"true\". */}}\n   {{if .Disabled}}data-disabled=\"true\" aria-disabled=\"true\"{{end}}\n   class=\"{{$base}} {{$destr}}\"\n   {{- range $k, $v := .Attrs}} {{$k}}=\"{{$v}}\"{{end -}}\n>{{.Label}}</a>\n{{else}}\n<button type=\"button\" role=\"menuitem\" tabindex=\"-1\" data-slot=\"dropdown-menu-item\"\n        {{/* menuitem_role: a disabled menuitem MUST set aria-disabled=\"true\". */}}\n        {{if .Disabled}}data-disabled=\"true\" aria-disabled=\"true\"{{end}}\n        {{- if .Onclick}} onclick=\"{{.Onclick}}\"{{end}}\n        class=\"{{$base}} {{$destr}}\"\n        {{- range $k, $v := .Attrs}} {{$k}}=\"{{$v}}\"{{end -}}\n>{{.Label}}</button>\n{{end}}\n{{end}}\n\n{{define \"dropdown_separator\"}}\n<div role=\"separator\" data-slot=\"dropdown-menu-separator\" class=\"-mx-1 my-1 h-px bg-border\"></div>\n{{end}}\n\n{{define \"dropdown_label\"}}\n<div data-slot=\"dropdown-menu-label\" class=\"px-2 py-1.5 text-xs font-semibold tracking-wider text-muted-foreground uppercase\">{{.Text}}</div>\n{{end}}\n"
    },
    {
      "path": "registry/phoenix/dropdown_menu.ex",
      "type": "registry:file",
      "target": "lib/my_app_web/components/dropdown_menu.ex",
      "content": "defmodule ShadcnHtmx.Components.DropdownMenu do\n  @moduledoc \"\"\"\n  DropdownMenu — shadcn-htmx, htmx v4 + Tailwind v4 for Phoenix.\n\n  Built on the native Popover API (popover + popovertarget). The APG menu\n  keyboard contract (arrows, Home/End, type-to-find, Enter/Space activate)\n  is wired up in public/site.js.\n\n  ## Examples\n\n      <.dropdown_trigger menu_for=\"user-menu\" class=\"…btn…\">Account</.dropdown_trigger>\n\n      <.dropdown_menu id=\"user-menu\">\n        <.dropdown_label>My account</.dropdown_label>\n        <.dropdown_item>Profile</.dropdown_item>\n        <.dropdown_item>Settings</.dropdown_item>\n        <.dropdown_separator />\n        <.dropdown_item variant=\"destructive\">Log out</.dropdown_item>\n      </.dropdown_menu>\n  \"\"\"\n\n  use Phoenix.Component\n\n  attr :menu_for, :string, required: true\n  attr :class, :string, default: nil\n  attr :rest, :global\n  slot :inner_block, required: true\n\n  def dropdown_trigger(assigns) do\n    ~H\"\"\"\n    <%!-- menu-button pattern: aria-controls + aria-expanded advertise the menu\n          and its state. Initial state collapsed; site.js flips aria-expanded. --%>\n    <button\n      type=\"button\"\n      popovertarget={@menu_for}\n      popovertargetaction=\"toggle\"\n      data-slot=\"dropdown-menu-trigger\"\n      aria-haspopup=\"menu\"\n      aria-controls={@menu_for}\n      aria-expanded=\"false\"\n      class={@class}\n      {@rest}\n    >\n      {render_slot(@inner_block)}\n    </button>\n    \"\"\"\n  end\n\n  attr :id, :string, required: true\n  attr :class, :string, default: nil\n  # role=\"menu\" REQUIRES an accessible name: aria_labelledby (canonical, points\n  # at the trigger id) or aria_label for icon-only triggers. menu_role.\n  attr :aria_labelledby, :string, default: nil\n  attr :aria_label, :string, default: nil\n  slot :inner_block, required: true\n\n  def dropdown_menu(assigns) do\n    ~H\"\"\"\n    <div\n      id={@id}\n      popover=\"auto\"\n      role=\"menu\"\n      aria-labelledby={@aria_labelledby}\n      aria-label={@aria_label}\n      data-slot=\"dropdown-menu\"\n      class={[\n        \"z-50 m-0 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none\",\n        \"[&:not(:popover-open)]:hidden\",\n        \"[&:popover-open]:animate-[scn-popover-in_120ms_ease-out]\",\n        \"anchor-popover-bottom\",\n        @class\n      ]}\n    >\n      {render_slot(@inner_block)}\n    </div>\n    \"\"\"\n  end\n\n  attr :href, :string, default: nil\n  attr :disabled, :boolean, default: false\n  attr :variant, :string, default: \"default\", values: ~w(default destructive)\n  attr :class, :string, default: nil\n  attr :rest, :global\n  slot :inner_block, required: true\n\n  def dropdown_item(assigns) do\n    base =\n      \"relative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none \" <>\n        \"focus:bg-accent focus:text-accent-foreground \" <>\n        \"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 \" <>\n        \"[&_svg]:size-4 [&_svg]:shrink-0\"\n\n    destr =\n      if assigns.variant == \"destructive\",\n        do: \"text-destructive focus:bg-destructive/10 focus:text-destructive\",\n        else: \"\"\n\n    assigns = assign(assigns, base: base, destr: destr)\n\n    cond do\n      assigns.href ->\n        ~H\"\"\"\n        <%!-- menuitem_role: a disabled menuitem MUST set aria-disabled=\"true\". --%>\n        <a\n          role=\"menuitem\"\n          tabindex=\"-1\"\n          href={@href}\n          data-slot=\"dropdown-menu-item\"\n          data-disabled={@disabled && \"true\"}\n          aria-disabled={@disabled && \"true\"}\n          class={[@base, @destr, @class]}\n          {@rest}\n        >\n          {render_slot(@inner_block)}\n        </a>\n        \"\"\"\n\n      true ->\n        ~H\"\"\"\n        <%!-- menuitem_role: a disabled menuitem MUST set aria-disabled=\"true\". --%>\n        <button\n          type=\"button\"\n          role=\"menuitem\"\n          tabindex=\"-1\"\n          data-slot=\"dropdown-menu-item\"\n          data-disabled={@disabled && \"true\"}\n          aria-disabled={@disabled && \"true\"}\n          class={[@base, @destr, @class]}\n          {@rest}\n        >\n          {render_slot(@inner_block)}\n        </button>\n        \"\"\"\n    end\n  end\n\n  def dropdown_separator(assigns) do\n    ~H\"\"\"\n    <div role=\"separator\" data-slot=\"dropdown-menu-separator\" class=\"-mx-1 my-1 h-px bg-border\" />\n    \"\"\"\n  end\n\n  attr :class, :string, default: nil\n  slot :inner_block, required: true\n\n  def dropdown_label(assigns) do\n    ~H\"\"\"\n    <div\n      data-slot=\"dropdown-menu-label\"\n      class={[\n        \"px-2 py-1.5 text-xs font-semibold tracking-wider text-muted-foreground uppercase\",\n        @class\n      ]}\n    >\n      {render_slot(@inner_block)}\n    </div>\n    \"\"\"\n  end\nend\n"
    },
    {
      "path": "registry/html/dropdown-menu.html",
      "type": "registry:file",
      "target": "snippets/dropdown-menu.html",
      "content": "<!--\n  shadcn-htmx — raw HTML dropdown menu snippet.\n\n  Native [popover] for open/close + APG menu keyboard nav via the inline JS.\n-->\n\n<!-- menu-button pattern: aria-controls + aria-expanded advertise the menu and\n     its state. Initial state collapsed; the inline JS flips aria-expanded. -->\n<button id=\"user-menu-trigger\" type=\"button\" popovertarget=\"user-menu\" popovertargetaction=\"toggle\"\n        data-slot=\"dropdown-menu-trigger\" aria-haspopup=\"menu\"\n        aria-controls=\"user-menu\" aria-expanded=\"false\"\n        class=\"inline-flex h-9 items-center rounded-md border bg-background px-4 text-sm font-medium shadow-xs hover:bg-accent\">\n  Account\n</button>\n\n<!-- role=\"menu\" REQUIRES an accessible name: aria-labelledby points at the\n     trigger id (canonical menu-button wiring), or use aria-label. menu_role. -->\n<div id=\"user-menu\" popover=\"auto\" role=\"menu\" aria-labelledby=\"user-menu-trigger\" data-slot=\"dropdown-menu\"\n     class=\"z-50 m-0 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none [&:not(:popover-open)]:hidden [&:popover-open]:animate-[scn-popover-in_120ms_ease-out] anchor-popover-bottom\">\n  <div data-slot=\"dropdown-menu-label\" class=\"px-2 py-1.5 text-xs font-semibold tracking-wider text-muted-foreground uppercase\">My account</div>\n  <button type=\"button\" role=\"menuitem\" tabindex=\"-1\" class=\"relative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0\">Profile</button>\n  <button type=\"button\" role=\"menuitem\" tabindex=\"-1\" class=\"relative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0\">Settings</button>\n  <div role=\"separator\" class=\"-mx-1 my-1 h-px bg-border\"></div>\n  <button type=\"button\" role=\"menuitem\" tabindex=\"-1\" class=\"relative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 text-destructive focus:bg-destructive/10 focus:text-destructive\">Log out</button>\n</div>\n\n<!-- Keyboard contract — copy once per page -->\n<script>\n  document.querySelectorAll('[data-slot=\"dropdown-menu\"]').forEach(function (menu) {\n    menu.addEventListener('toggle', function (e) {\n      if (e.newState === 'open') {\n        var first = menu.querySelector('[role=\"menuitem\"]:not([data-disabled=\"true\"])')\n        if (first) setTimeout(function () { first.focus() }, 0)\n      }\n    })\n  })\n  document.addEventListener('keydown', function (e) {\n    var item = e.target.closest && e.target.closest('[role=\"menuitem\"]'); if (!item) return\n    var menu = item.closest('[data-slot=\"dropdown-menu\"]'); if (!menu) return\n    var items = [].slice.call(menu.querySelectorAll('[role=\"menuitem\"]:not([data-disabled=\"true\"])'))\n    var i = items.indexOf(item)\n    if (e.key === 'ArrowDown') { e.preventDefault(); items[(i + 1) % items.length].focus() }\n    else if (e.key === 'ArrowUp') { e.preventDefault(); items[(i - 1 + items.length) % items.length].focus() }\n    else if (e.key === 'Home') { e.preventDefault(); items[0].focus() }\n    else if (e.key === 'End') { e.preventDefault(); items[items.length - 1].focus() }\n    else if (e.key.length === 1 && /\\S/.test(e.key)) {\n      var ch = e.key.toLowerCase()\n      for (var k = 1; k <= items.length; k++) {\n        var c = items[(i + k) % items.length]\n        if ((c.textContent || '').trim().toLowerCase().startsWith(ch)) { c.focus(); break }\n      }\n    }\n  })\n</script>\n"
    }
  ]
}
