@bazza-ui/react 0.0.0 → 0.1.0-canary.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/ListboxStore-BtcTXpzi.d.cts +351 -0
  2. package/dist/ListboxStore-DPqpLlAL.d.ts +351 -0
  3. package/dist/adapters/index.cjs +2 -0
  4. package/dist/adapters/index.cjs.map +1 -0
  5. package/dist/adapters/index.d.cts +363 -0
  6. package/dist/adapters/index.d.ts +363 -0
  7. package/dist/adapters/index.js +2 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/chunk-4C666HHU.js +2 -0
  10. package/dist/chunk-4C666HHU.js.map +1 -0
  11. package/dist/chunk-AVZ64JQ3.js +2 -0
  12. package/dist/chunk-AVZ64JQ3.js.map +1 -0
  13. package/dist/chunk-BGJJC6GX.cjs +2 -0
  14. package/dist/chunk-BGJJC6GX.cjs.map +1 -0
  15. package/dist/chunk-FWWOE2SW.cjs +2 -0
  16. package/dist/chunk-FWWOE2SW.cjs.map +1 -0
  17. package/dist/chunk-JSPKF52O.cjs +2 -0
  18. package/dist/chunk-JSPKF52O.cjs.map +1 -0
  19. package/dist/chunk-KWGD24VS.js +2 -0
  20. package/dist/chunk-KWGD24VS.js.map +1 -0
  21. package/dist/chunk-M4G6J7DP.cjs +2 -0
  22. package/dist/chunk-M4G6J7DP.cjs.map +1 -0
  23. package/dist/chunk-WKAPAKUL.js +2 -0
  24. package/dist/chunk-WKAPAKUL.js.map +1 -0
  25. package/dist/combobox/index.cjs +2 -0
  26. package/dist/combobox/index.cjs.map +1 -0
  27. package/dist/combobox/index.d.cts +1039 -0
  28. package/dist/combobox/index.d.ts +1039 -0
  29. package/dist/combobox/index.js +2 -0
  30. package/dist/combobox/index.js.map +1 -0
  31. package/dist/command-score-Dgo3ZS3Z.d.ts +36 -0
  32. package/dist/command-score-YjNr3ZWi.d.cts +36 -0
  33. package/dist/context-menu/index.cjs +2 -0
  34. package/dist/context-menu/index.cjs.map +1 -0
  35. package/dist/context-menu/index.d.cts +658 -0
  36. package/dist/context-menu/index.d.ts +658 -0
  37. package/dist/context-menu/index.js +2 -0
  38. package/dist/context-menu/index.js.map +1 -0
  39. package/dist/data-surface-B-eIGTBi.d.cts +678 -0
  40. package/dist/data-surface-D1OilMDu.d.ts +678 -0
  41. package/dist/dropdown-menu/index.cjs +2 -0
  42. package/dist/dropdown-menu/index.cjs.map +1 -0
  43. package/dist/dropdown-menu/index.d.cts +700 -0
  44. package/dist/dropdown-menu/index.d.ts +700 -0
  45. package/dist/dropdown-menu/index.js +2 -0
  46. package/dist/dropdown-menu/index.js.map +1 -0
  47. package/dist/events-BPr8sRGH.d.cts +166 -0
  48. package/dist/events-BPr8sRGH.d.ts +166 -0
  49. package/dist/input-BoIK003I.d.cts +41 -0
  50. package/dist/input-DF7D8YzW.d.ts +41 -0
  51. package/dist/internal/listbox/index.cjs +2 -0
  52. package/dist/internal/listbox/index.cjs.map +1 -0
  53. package/dist/internal/listbox/index.d.cts +269 -0
  54. package/dist/internal/listbox/index.d.ts +269 -0
  55. package/dist/internal/listbox/index.js +2 -0
  56. package/dist/internal/listbox/index.js.map +1 -0
  57. package/dist/internal/popup-menu/index.cjs +2 -0
  58. package/dist/internal/popup-menu/index.cjs.map +1 -0
  59. package/dist/internal/popup-menu/index.d.cts +846 -0
  60. package/dist/internal/popup-menu/index.d.ts +846 -0
  61. package/dist/internal/popup-menu/index.js +2 -0
  62. package/dist/internal/popup-menu/index.js.map +1 -0
  63. package/dist/item-equality-B6TbXlBT.d.cts +7 -0
  64. package/dist/item-equality-B6TbXlBT.d.ts +7 -0
  65. package/dist/loading-DphSt8MY.d.cts +27 -0
  66. package/dist/loading-TsgH6v92.d.ts +27 -0
  67. package/dist/select/index.cjs +2 -0
  68. package/dist/select/index.cjs.map +1 -0
  69. package/dist/select/index.d.cts +927 -0
  70. package/dist/select/index.d.ts +927 -0
  71. package/dist/select/index.js +2 -0
  72. package/dist/select/index.js.map +1 -0
  73. package/dist/separator-B4Ot84B0.d.ts +748 -0
  74. package/dist/separator-BmbUeeaT.d.cts +748 -0
  75. package/dist/types-9vS1uLIK.d.cts +1557 -0
  76. package/dist/types-lQCIvWW8.d.ts +1557 -0
  77. package/dist/use-listbox-item-BIi4eRPI.d.cts +182 -0
  78. package/dist/use-listbox-item-BIi4eRPI.d.ts +182 -0
  79. package/package.json +50 -12
  80. package/dist/index.d.ts +0 -2
  81. package/dist/index.js +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/popup-menu/contexts/component-name-context.ts","../src/internal/popup-menu/contexts/focus-owner-context.ts","../src/internal/popup-menu/contexts/open-chain-context.ts","../src/internal/popup-menu/contexts/popup-menu-context.ts","../src/internal/popup-menu/contexts/popup-menu-debug-context.ts","../src/internal/popup-menu/contexts/popup-surface-id-context.ts","../src/internal/popup-menu/contexts/submenu-context.ts","../src/internal/popup-menu/contexts/subpage-context.ts","../src/internal/popup-menu/contexts/subpage-stack-context.ts","../src/internal/popup-menu/hooks/use-aim-guard.tsx","../src/internal/popup-menu/store/FocusOwnerStore.ts","../src/internal/popup-menu/store/OpenChainStore.ts","../src/internal/popup-menu/utils/aim-guard.ts","../src/internal/popup-menu/utils/use-mouse-trail.ts","../src/internal/popup-menu/hooks/use-popup-menu-root.ts","../src/internal/popup-menu/components/arrow/arrow.data-attrs.ts","../src/internal/popup-menu/components/arrow/arrow.tsx","../src/internal/popup-menu/components/backdrop/backdrop.data-attrs.ts","../src/internal/popup-menu/components/backdrop/backdrop.tsx","../src/internal/popup-menu/components/popup/popup.data-attrs.ts","../src/internal/popup-menu/components/popup/popup.tsx","../src/combobox/contexts/combobox-context.ts","../src/internal/popup-menu/deep-search/context.ts","../src/internal/popup-menu/components/portal/portal.tsx","../src/internal/popup-menu/components/positioner/positioner.css-vars.ts","../src/internal/popup-menu/components/positioner/positioner.data-attrs.ts","../src/internal/popup-menu/components/positioner/positioner.tsx","../src/internal/popup-menu/components/providers.tsx","../src/internal/popup-menu/hooks/use-popup-menu-item.ts","../src/internal/popup-menu/hooks/use-popup-menu-keyboard.ts","../src/internal/popup-menu/components/icon/icon.data-attrs.ts","../src/internal/popup-menu/components/icon/icon.tsx","../src/utils/resolve-value-label.ts","../src/internal/popup-menu/components/empty/empty.tsx","../src/internal/popup-menu/deep-search/async-coordinator.tsx","../src/internal/popup-menu/components/input/input.tsx","../src/internal/popup-menu/components/list/list.tsx","../src/internal/popup-menu/components/list/list.css-vars.ts","../src/internal/popup-menu/components/list/list.data-attrs.ts","../src/internal/popup-menu/components/loading/loading.tsx","../src/internal/popup-menu/components/scroll-arrow/scroll-arrow.data-attrs.ts","../src/internal/popup-menu/components/scroll-arrow/scroll-arrow.tsx","../src/internal/popup-menu/components/surface/surface.tsx","../src/internal/popup-menu/components/checkbox-item/checkbox-item.tsx","../src/internal/popup-menu/components/checkbox-item/checkbox-item.data-attrs.ts","../src/internal/popup-menu/components/checkbox-item/checkbox-item-context.ts","../src/internal/popup-menu/components/checkbox-item/checkbox-item-indicator.tsx","../src/internal/popup-menu/components/item/item.tsx","../src/internal/popup-menu/components/item/item.data-attrs.ts","../src/internal/popup-menu/components/radio-group/radio-group.tsx","../src/internal/popup-menu/components/radio-group/radio-group.data-attrs.ts","../src/internal/popup-menu/components/radio-group/radio-group-context.ts","../src/internal/popup-menu/components/radio-group/radio-group-value.tsx","../src/internal/popup-menu/components/radio-item/radio-item.tsx","../src/internal/popup-menu/components/radio-item/radio-item.data-attrs.ts","../src/internal/popup-menu/components/radio-item/radio-item-context.ts","../src/internal/popup-menu/components/radio-item/radio-item-indicator.tsx","../src/internal/popup-menu/components/group/group.tsx","../src/internal/popup-menu/components/group-label/group-label.tsx","../src/internal/popup-menu/components/separator/separator.tsx","../src/internal/popup-menu/components/shortcut/shortcut.tsx","../src/internal/popup-menu/components/shortcut/shortcut.data-attrs.ts","../src/internal/popup-menu/components/submenu-root/submenu-root.tsx","../src/internal/popup-menu/components/submenu-trigger/submenu-trigger.tsx","../src/internal/popup-menu/utils/is-mouse-like-pointer.ts","../src/internal/popup-menu/components/submenu-trigger/submenu-safe-triangle-area.tsx","../src/internal/popup-menu/utils/use-mouse-position.ts","../src/internal/popup-menu/components/submenu-trigger/submenu-trigger-indicator.tsx","../src/internal/popup-menu/components/submenu-trigger/submenu-trigger.data-attrs.ts","../src/internal/popup-menu/components/subpage/subpage.tsx","../src/internal/popup-menu/components/subpage-back/subpage-back.data-attrs.ts","../src/internal/popup-menu/components/subpage-back/subpage-back.tsx","../src/internal/popup-menu/components/subpage-back-item/subpage-back-item.data-attrs.ts","../src/internal/popup-menu/components/subpage-back-item/subpage-back-item.tsx","../src/internal/popup-menu/components/subpage-trigger/subpage-trigger.data-attrs.ts","../src/internal/popup-menu/components/subpage-trigger/subpage-trigger.tsx","../src/internal/popup-menu/deep-search/data-list.tsx","../src/internal/popup-menu/deep-search/types.ts","../src/internal/popup-menu/deep-search/utils.ts","../src/internal/popup-menu/deep-search/data-subpages.tsx","../src/internal/popup-menu/deep-search/data-surface.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\n\n/**\n * Component name used for generating bazzaui-* slot attributes.\n * E.g., 'dropdown-menu', 'context-menu', 'select', 'combobox'\n */\nexport type ComponentName =\n | 'dropdown-menu'\n | 'context-menu'\n | 'select'\n | 'combobox'\n\nexport const ComponentNameContext = React.createContext<ComponentName | null>(\n null,\n)\n\n/**\n * Returns the component name from context.\n * Throws if used outside of a component that provides the context.\n */\nexport function useComponentName(): ComponentName {\n const context = React.useContext(ComponentNameContext)\n if (context === null) {\n throw new Error(\n 'useComponentName must be used within a ComponentNameContext.Provider',\n )\n }\n return context\n}\n\n/**\n * Returns the component name from context, or null if not available.\n * Useful for internal components that may be used outside the popup-menu context.\n */\nexport function useMaybeComponentName(): ComponentName | null {\n return React.useContext(ComponentNameContext)\n}\n\n/**\n * Helper to generate a bazzaui slot attribute value.\n * @param componentName The component name (e.g., 'dropdown-menu')\n * @param partName The part name (e.g., 'trigger', 'item')\n * @returns The slot attribute value (e.g., 'bazzaui-dropdown-menu-trigger')\n */\nexport function getSlotAttribute(\n componentName: ComponentName | null,\n partName: string,\n): string | undefined {\n if (!componentName) return undefined\n return `bazzaui-${componentName}-${partName}`\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { FocusOwnerStore } from '../store/FocusOwnerStore.js'\n\n// ============================================================================\n// Focus Owner Context\n// ============================================================================\n\nconst FocusOwnerContext = React.createContext<FocusOwnerStore | null>(null)\n\nexport function useFocusOwner(): FocusOwnerStore {\n const context = React.useContext(FocusOwnerContext)\n if (!context) {\n throw new Error(\n 'FocusOwner components must be used within a FocusOwnerProvider',\n )\n }\n return context\n}\n\nexport function useMaybeFocusOwner(): FocusOwnerStore | null {\n return React.useContext(FocusOwnerContext)\n}\n\nexport { FocusOwnerContext }\n","'use client'\n\nimport * as React from 'react'\nimport type { OpenChainStore } from '../store/OpenChainStore.js'\n\n// ============================================================================\n// Open Chain Context\n// ============================================================================\n\nconst OpenChainContext = React.createContext<OpenChainStore | null>(null)\n\nexport function useOpenChain(): OpenChainStore {\n const context = React.useContext(OpenChainContext)\n if (!context) {\n throw new Error(\n 'OpenChain components must be used within an OpenChainProvider',\n )\n }\n return context\n}\n\nexport function useMaybeOpenChain(): OpenChainStore | null {\n return React.useContext(OpenChainContext)\n}\n\nexport { OpenChainContext }\n","'use client'\n\nimport * as React from 'react'\nimport type {\n ListboxStore,\n VirtualItem,\n} from '../../listbox/store/ListboxStore.js'\nimport type { GetQualifiedRowIdFn } from '../deep-search/types.js'\nimport type {\n HighlightChangeEventDetails,\n PopupMenuOpenChangeReason,\n} from '../events.js'\n\n// ============================================================================\n// Popup Menu Context\n// ============================================================================\n// Shared root-level context for popup menus (DropdownMenu, ContextMenu).\n// Provides core menu functionality to all child components.\n\n/**\n * Virtual anchor for positioning the menu at a specific point.\n * Used by ContextMenu to position at cursor location.\n */\nexport interface VirtualAnchor {\n getBoundingClientRect(): DOMRect\n}\n\n/**\n * Virtualization configuration passed from Root/Submenu to Surface.\n */\nexport interface VirtualizationConfig {\n /** Whether virtualization mode is enabled */\n virtualized: boolean\n /** Pre-registered items for virtualization */\n items: VirtualItem[]\n /**\n * Callback when highlighted item changes (for scroll sync).\n * The third parameter contains event details including the reason for the change.\n */\n onHighlightChange?: (\n id: string | null,\n index: number,\n eventDetails: HighlightChangeEventDetails,\n ) => void\n}\n\n/**\n * Shared context value for popup menus.\n * Both DropdownMenu.Root and ContextMenu.Root provide this context.\n */\nexport interface PopupMenuContextValue {\n /** The Listbox store instance */\n store: ListboxStore\n /** Whether this menu tree currently ignores user interaction. */\n disabled: boolean\n /** Nesting depth: 0 = root menu, 1+ = submenu */\n depth: number\n /** Close the entire menu tree (deepest submenu to root, sequentially) */\n closeAll: (reason?: PopupMenuOpenChangeReason, event?: Event) => void\n /** Register a surface (submenu) for closeAll tracking. Returns unregister function. */\n registerSurface: (\n depth: number,\n setOpen: (open: boolean) => void,\n ) => () => void\n /** Virtualization configuration (if enabled) */\n virtualization?: VirtualizationConfig\n /**\n * Virtual anchor for positioning.\n * Used by ContextMenu to position at cursor location.\n * DropdownMenu uses the Popover's anchor (trigger button) instead.\n */\n virtualAnchor?: VirtualAnchor\n /**\n * Type of menu for positioning logic.\n * - 'dropdown': positions relative to trigger button\n * - 'context': positions at cursor with fixed positioning\n */\n menuType: 'dropdown' | 'context'\n /**\n * When to close the menu on outside interactions.\n * - 'pointerdown': Close immediately when pointer is pressed outside (default)\n * - 'click': Close when a full click (pointerdown + pointerup) occurs outside\n * @default 'pointerdown'\n */\n closeOnOutsidePress: 'click' | 'pointerdown'\n /**\n * Function to generate qualified unique IDs for rows.\n * Defined once at the root level and applied to all surfaces (root and submenus).\n * If not provided, uses the default implementation.\n */\n getQualifiedRowId?: GetQualifiedRowIdFn\n}\n\nconst PopupMenuContext = React.createContext<PopupMenuContextValue | null>(null)\n\n/**\n * Hook to access the popup menu context.\n * Throws if used outside a popup menu.\n */\nexport function usePopupMenuContext(): PopupMenuContextValue {\n const context = React.useContext(PopupMenuContext)\n if (!context) {\n throw new Error(\n 'PopupMenu components must be used within a PopupMenu.Root or ContextMenu.Root',\n )\n }\n return context\n}\n\n/**\n * Hook to optionally access the popup menu context.\n * Returns null if used outside a popup menu.\n */\nexport function useMaybePopupMenuContext(): PopupMenuContextValue | null {\n return React.useContext(PopupMenuContext)\n}\n\nexport { PopupMenuContext }\n\n// Re-export for convenience\nexport type { VirtualItem }\n","'use client'\n\nimport * as React from 'react'\n\nfunction clampNumber(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\nfunction toNumberOrDefault(value: unknown, defaultValue: number): number {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n return defaultValue\n }\n return value\n}\n\nexport interface PopupMenuSafeTriangleAreaDebugSettings {\n enabled: boolean\n idleColor: string\n successColor: string\n missColor: string\n triangleFillOpacity: number\n overlayOpacity: number\n showStroke: boolean\n strokeWidth: number\n strokeDasharray: string\n showDots: boolean\n dotRadius: number\n freezeOnPointerLeave: boolean\n persistOnSuccess: boolean\n showMissState: boolean\n missFreezeDuration: number\n}\n\nexport interface PopupMenuSafeTriangleAreaDebugOptions {\n enabled?: boolean\n idleColor?: string\n successColor?: string\n missColor?: string\n triangleFillOpacity?: number\n overlayOpacity?: number\n showStroke?: boolean\n strokeWidth?: number\n strokeDasharray?: string\n showDots?: boolean\n dotRadius?: number\n freezeOnPointerLeave?: boolean\n persistOnSuccess?: boolean\n showMissState?: boolean\n missFreezeDuration?: number\n}\n\nexport type PopupMenuSafeTriangleAreaDebugConfig =\n | boolean\n | PopupMenuSafeTriangleAreaDebugOptions\n\nexport const defaultPopupMenuSafeTriangleAreaDebugSettings: PopupMenuSafeTriangleAreaDebugSettings =\n {\n enabled: false,\n idleColor: '#0088ff',\n successColor: '#00aa66',\n missColor: '#ff3b30',\n triangleFillOpacity: 0.2,\n overlayOpacity: 1,\n showStroke: true,\n strokeWidth: 1.5,\n strokeDasharray: '6 4',\n showDots: true,\n dotRadius: 4,\n freezeOnPointerLeave: true,\n persistOnSuccess: true,\n showMissState: false,\n missFreezeDuration: 220,\n }\n\nexport function resolvePopupMenuSafeTriangleAreaDebugConfig(\n config?: PopupMenuSafeTriangleAreaDebugConfig,\n legacyEnabled?: boolean,\n): PopupMenuSafeTriangleAreaDebugSettings {\n const defaults = defaultPopupMenuSafeTriangleAreaDebugSettings\n\n if (typeof config === 'boolean') {\n return {\n ...defaults,\n enabled: config,\n }\n }\n\n if (!config) {\n return {\n ...defaults,\n enabled: !!legacyEnabled,\n }\n }\n\n const triangleFillOpacity = clampNumber(\n toNumberOrDefault(config.triangleFillOpacity, defaults.triangleFillOpacity),\n 0,\n 1,\n )\n\n const overlayOpacity = clampNumber(\n toNumberOrDefault(config.overlayOpacity, defaults.overlayOpacity),\n 0,\n 1,\n )\n\n const strokeWidth = Math.max(\n 0,\n toNumberOrDefault(config.strokeWidth, defaults.strokeWidth),\n )\n\n const dotRadius = Math.max(\n 0,\n toNumberOrDefault(config.dotRadius, defaults.dotRadius),\n )\n\n const missFreezeDuration = Math.max(\n 0,\n toNumberOrDefault(config.missFreezeDuration, defaults.missFreezeDuration),\n )\n\n return {\n ...defaults,\n ...config,\n enabled: config.enabled ?? true,\n idleColor: config.idleColor ?? defaults.idleColor,\n successColor: config.successColor ?? defaults.successColor,\n missColor: config.missColor ?? defaults.missColor,\n triangleFillOpacity,\n overlayOpacity,\n showStroke: config.showStroke ?? defaults.showStroke,\n strokeWidth,\n strokeDasharray: config.strokeDasharray ?? defaults.strokeDasharray,\n showDots: config.showDots ?? defaults.showDots,\n dotRadius,\n freezeOnPointerLeave:\n config.freezeOnPointerLeave ?? defaults.freezeOnPointerLeave,\n persistOnSuccess: config.persistOnSuccess ?? defaults.persistOnSuccess,\n showMissState: config.showMissState ?? defaults.showMissState,\n missFreezeDuration,\n }\n}\n\n/**\n * Debug configuration available on popup-menu roots.\n */\nexport interface PopupMenuDebugOptions {\n /**\n * Shows/configures the safe triangle area used by submenu aim guard.\n * @default false\n */\n showSafeTriangleArea?: PopupMenuSafeTriangleAreaDebugConfig\n\n /**\n * @deprecated Use `showSafeTriangleArea` instead.\n */\n showSubmenuSafeTriangleArea?: boolean\n\n /**\n * Enables console logging for aim-guard diagnostics.\n * @default false\n */\n logAimGuardEvents?: boolean\n}\n\nexport interface PopupMenuDebugContextValue {\n showSafeTriangleArea: PopupMenuSafeTriangleAreaDebugSettings\n logAimGuardEvents: boolean\n}\n\nconst defaultPopupMenuDebugContextValue: PopupMenuDebugContextValue = {\n showSafeTriangleArea: defaultPopupMenuSafeTriangleAreaDebugSettings,\n logAimGuardEvents: false,\n}\n\nexport const PopupMenuDebugContext =\n React.createContext<PopupMenuDebugContextValue>(\n defaultPopupMenuDebugContextValue,\n )\n\nexport function usePopupMenuDebug(): PopupMenuDebugContextValue {\n return React.useContext(PopupMenuDebugContext)\n}\n","'use client'\n\nimport * as React from 'react'\n\n// ============================================================================\n// Popup Surface ID Context\n// ============================================================================\n\n/**\n * Context for passing surfaceId from Popup to Surface.\n * This ensures Popup and Surface share the same ID for data attribute tracking.\n *\n * For root menus, Popup generates the ID and provides it via this context.\n * For submenus, the ID comes from SubmenuContext.childSurfaceId instead.\n */\nconst PopupSurfaceIdContext = React.createContext<string | null>(null)\n\nexport function usePopupSurfaceId(): string | null {\n return React.useContext(PopupSurfaceIdContext)\n}\n\nexport { PopupSurfaceIdContext }\n","'use client'\n\nimport * as React from 'react'\n\nexport interface SubmenuContextValue {\n /** Whether the submenu is open */\n open: boolean\n /** Set the submenu open state */\n setOpen: (open: boolean) => void\n /** Reference to the trigger element */\n triggerRef: React.RefObject<HTMLElement | null>\n /** Reference to the submenu content element (for aim guard rect calculations) */\n contentRef: React.RefObject<HTMLElement | null>\n /** Surface ID of the parent menu (for keyboard navigation back) */\n parentSurfaceId: string\n /** Surface ID of this submenu (for keyboard navigation into) */\n childSurfaceId: string\n /**\n * Whether pressing Escape in this submenu closes the entire menu from the root.\n * When true, Escape closes the entire menu tree.\n * When false, Escape only closes this submenu and moves focus to the parent.\n * @default true\n */\n closeRootOnEsc: boolean\n}\n\nconst SubmenuContext = React.createContext<SubmenuContextValue | null>(null)\n\nexport function useSubmenuContext(): SubmenuContextValue {\n const context = React.useContext(SubmenuContext)\n if (!context) {\n throw new Error('SubmenuTrigger must be used within a Submenu')\n }\n return context\n}\n\nexport function useMaybeSubmenuContext(): SubmenuContextValue | null {\n return React.useContext(SubmenuContext)\n}\n\nexport { SubmenuContext }\n","'use client'\n\nimport * as React from 'react'\n\nexport interface SubpageContextValue {\n /** Current page ID. */\n pageId: string\n /** Surface ID for this page. */\n surfaceId: string\n /** Surface ID for the previous page, if available. */\n parentSurfaceId: string | null\n /** Whether this page is currently active. */\n isActive: boolean\n /** Whether Escape should close the entire menu tree from this page. */\n closeRootOnEsc: boolean\n /** Navigate back one page. Returns true when navigation happened. */\n goBack: () => boolean\n}\n\nconst SubpageContext = React.createContext<SubpageContextValue | null>(null)\n\nexport function useSubpageContext(): SubpageContextValue {\n const context = React.useContext(SubpageContext)\n if (!context) {\n throw new Error(\n 'Subpage components must be used within a PopupMenu.Subpage',\n )\n }\n return context\n}\n\nexport function useMaybeSubpageContext(): SubpageContextValue | null {\n return React.useContext(SubpageContext)\n}\n\nexport { SubpageContext }\n","'use client'\n\nimport * as React from 'react'\n\nexport const ROOT_SUBPAGE_ID = '__root__'\n\nexport interface SubpageRegistration {\n pageId: string\n surfaceId: string\n closeRootOnEsc: boolean\n}\n\nexport interface SubpageStackContextValue {\n /** Currently active page ID. */\n activePageId: string\n /** Surface ID for the currently active page. */\n activeSurfaceId: string\n /** Whether there is a previous page to navigate back to. */\n canGoBack: boolean\n /** Whether Escape in the active page should close the entire menu tree. */\n shouldCloseRootOnEsc: boolean\n /** Current page stack from root to active page. */\n stack: readonly string[]\n /** Register a page and return an unregister cleanup. */\n registerPage: (registration: SubpageRegistration) => () => void\n /** Push a page onto the stack. Returns true when navigation happened. */\n openPage: (pageId: string) => boolean\n /** Pop one page from the stack. Returns true when navigation happened. */\n goBack: () => boolean\n /** Resolve a surface ID for a page ID. */\n getSurfaceId: (pageId: string) => string | null\n}\n\nconst SubpageStackContext =\n React.createContext<SubpageStackContextValue | null>(null)\n\nexport function useSubpageStack(): SubpageStackContextValue {\n const context = React.useContext(SubpageStackContext)\n if (!context) {\n throw new Error('Subpage components must be used within a PopupMenu.Popup')\n }\n return context\n}\n\nexport function useMaybeSubpageStack(): SubpageStackContextValue | null {\n return React.useContext(SubpageStackContext)\n}\n\nexport { SubpageStackContext }\n","'use client'\n\nimport * as React from 'react'\nimport { usePopupMenuDebug } from '../contexts/popup-menu-debug-context.js'\n\nexport interface AimGuardContextValue {\n aimGuardActive: boolean\n guardedTriggerId: string | null\n guardedDepth: number | null\n guardedSubmenuSurfaceId: string | null\n activateAimGuard: (\n triggerId: string,\n depth: number,\n submenuSurfaceId: string,\n timeoutMs?: number,\n ) => void\n clearAimGuard: () => void\n aimGuardActiveRef: React.RefObject<boolean>\n guardedTriggerIdRef: React.RefObject<string | null>\n guardedDepthRef: React.RefObject<number | null>\n guardedSubmenuSurfaceIdRef: React.RefObject<string | null>\n isGuardBlocking: (rowId: string) => boolean\n}\n\nconst AimGuardCtx = React.createContext<AimGuardContextValue>({\n aimGuardActive: false,\n guardedTriggerId: null,\n guardedDepth: null,\n guardedSubmenuSurfaceId: null,\n activateAimGuard: () => {},\n clearAimGuard: () => {},\n aimGuardActiveRef: { current: false },\n guardedTriggerIdRef: { current: null },\n guardedDepthRef: { current: null },\n guardedSubmenuSurfaceIdRef: { current: null },\n isGuardBlocking: () => false,\n})\n\nexport const useAimGuard = () => React.useContext(AimGuardCtx)\n\nexport interface AimGuardProviderProps {\n children: React.ReactNode\n}\n\n/**\n * Provides aim guard for safe polygon navigation.\n * Prevents accidental submenu closures when users move diagonally toward an open submenu.\n */\nexport function AimGuardProvider({ children }: AimGuardProviderProps) {\n const { logAimGuardEvents } = usePopupMenuDebug()\n const [aimGuardActive, setAimGuardActive] = React.useState(false)\n const [guardedTriggerId, setGuardedTriggerId] = React.useState<string | null>(\n null,\n )\n const [guardedDepth, setGuardedDepth] = React.useState<number | null>(null)\n const [guardedSubmenuSurfaceId, setGuardedSubmenuSurfaceId] = React.useState<\n string | null\n >(null)\n const aimGuardActiveRef = React.useRef(false)\n const guardedTriggerIdRef = React.useRef<string | null>(null)\n const guardedDepthRef = React.useRef<number | null>(null)\n const guardedSubmenuSurfaceIdRef = React.useRef<string | null>(null)\n\n React.useEffect(() => {\n aimGuardActiveRef.current = aimGuardActive\n }, [aimGuardActive])\n\n React.useEffect(() => {\n guardedTriggerIdRef.current = guardedTriggerId\n }, [guardedTriggerId])\n\n React.useEffect(() => {\n guardedDepthRef.current = guardedDepth\n }, [guardedDepth])\n\n React.useEffect(() => {\n guardedSubmenuSurfaceIdRef.current = guardedSubmenuSurfaceId\n }, [guardedSubmenuSurfaceId])\n\n const guardTimerRef = React.useRef<number | null>(null)\n\n const logAimGuard = React.useCallback(\n (eventName: string, details?: Record<string, unknown>) => {\n if (!logAimGuardEvents || typeof window === 'undefined') {\n return\n }\n\n console.log(`[PopupMenu][AimGuardProvider] ${eventName}`, {\n aimGuardActive: aimGuardActiveRef.current,\n guardedTriggerId: guardedTriggerIdRef.current,\n guardedDepth: guardedDepthRef.current,\n guardedSubmenuSurfaceId: guardedSubmenuSurfaceIdRef.current,\n ...details,\n })\n },\n [\n logAimGuardEvents,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n guardedDepthRef,\n guardedSubmenuSurfaceIdRef,\n ],\n )\n\n const resetAimGuardState = React.useCallback(() => {\n aimGuardActiveRef.current = false\n guardedTriggerIdRef.current = null\n guardedDepthRef.current = null\n guardedSubmenuSurfaceIdRef.current = null\n setAimGuardActive(false)\n setGuardedTriggerId(null)\n setGuardedDepth(null)\n setGuardedSubmenuSurfaceId(null)\n }, [])\n\n const clearAimGuard = React.useCallback(() => {\n if (guardTimerRef.current !== null) {\n window.clearTimeout(guardTimerRef.current)\n guardTimerRef.current = null\n }\n logAimGuard('clear')\n resetAimGuardState()\n }, [resetAimGuardState, logAimGuard])\n\n const activateAimGuard = React.useCallback(\n (\n triggerId: string,\n depth: number,\n submenuSurfaceId: string,\n timeoutMs = 450,\n ) => {\n logAimGuard('activate', {\n triggerId,\n depth,\n submenuSurfaceId,\n timeoutMs,\n })\n aimGuardActiveRef.current = true\n guardedTriggerIdRef.current = triggerId\n guardedDepthRef.current = depth\n guardedSubmenuSurfaceIdRef.current = submenuSurfaceId\n setGuardedTriggerId(triggerId)\n setGuardedDepth(depth)\n setGuardedSubmenuSurfaceId(submenuSurfaceId)\n setAimGuardActive(true)\n if (guardTimerRef.current !== null) {\n window.clearTimeout(guardTimerRef.current)\n }\n guardTimerRef.current = window.setTimeout(() => {\n logAimGuard('timeout-expired', {\n triggerId,\n depth,\n submenuSurfaceId,\n })\n resetAimGuardState()\n guardTimerRef.current = null\n }, timeoutMs) as unknown as number\n },\n [resetAimGuardState, logAimGuard],\n )\n\n React.useEffect(() => {\n return () => {\n if (guardTimerRef.current !== null) {\n window.clearTimeout(guardTimerRef.current)\n guardTimerRef.current = null\n }\n\n logAimGuard('provider-unmount-clear')\n }\n }, [logAimGuard])\n\n const isGuardBlocking = React.useCallback(\n (rowId: string) =>\n aimGuardActiveRef.current && guardedTriggerIdRef.current !== rowId,\n [],\n )\n\n const value = React.useMemo(\n () => ({\n aimGuardActive,\n guardedTriggerId,\n guardedDepth,\n guardedSubmenuSurfaceId,\n activateAimGuard,\n clearAimGuard,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n guardedDepthRef,\n guardedSubmenuSurfaceIdRef,\n isGuardBlocking,\n }),\n [\n aimGuardActive,\n guardedTriggerId,\n guardedDepth,\n guardedSubmenuSurfaceId,\n activateAimGuard,\n clearAimGuard,\n isGuardBlocking,\n ],\n )\n\n return <AimGuardCtx.Provider value={value}>{children}</AimGuardCtx.Provider>\n}\n\nexport { AimGuardCtx }\n","import { createSelector, ReactStore } from '@base-ui/utils/store'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FocusOwnerState {\n /** Which surface currently owns focus (surfaceId or null) */\n ownerId: string | null\n}\n\n// ============================================================================\n// Selectors\n// ============================================================================\n\nconst selectors = {\n ownerId: createSelector((state: FocusOwnerState) => state.ownerId),\n isOwner: createSelector(\n (state: FocusOwnerState, surfaceId: string) => state.ownerId === surfaceId,\n ),\n}\n\n// ============================================================================\n// Store\n// ============================================================================\n\n/**\n * Tracks which menu surface owns DOM focus.\n * Single instance per menu tree (created at root, shared via context).\n *\n * Used by: DropdownMenu, ContextMenu\n * Not used by: Select, CommandMenu (single surface)\n */\nexport class FocusOwnerStore extends ReactStore<\n FocusOwnerState,\n {},\n typeof selectors\n> {\n constructor() {\n super({ ownerId: null }, {}, selectors)\n }\n\n /**\n * Set the owner surface ID.\n * Call this when focus should transfer to a new surface.\n */\n setOwnerId(id: string | null) {\n this.set('ownerId', id)\n }\n\n /**\n * Clear the owner (set to null).\n * Call this when the menu tree closes.\n */\n clearOwner() {\n this.set('ownerId', null)\n }\n}\n\nexport type { FocusOwnerState as State }\n","import { createSelector, ReactStore } from '@base-ui/utils/store'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface OpenChainState {\n /**\n * Ordered array of surface IDs for submenus that are currently open.\n * The last element is the most recently opened (deepest in chain).\n */\n chain: string[]\n}\n\n// ============================================================================\n// Selectors\n// ============================================================================\n\nconst selectors = {\n isOpen: createSelector((state: OpenChainState, surfaceId: string) =>\n state.chain.includes(surfaceId),\n ),\n isLast: createSelector(\n (state: OpenChainState, surfaceId: string) =>\n state.chain.length > 0 &&\n state.chain[state.chain.length - 1] === surfaceId,\n ),\n /**\n * Returns true if there's an open submenu below the given depth.\n * - Root (depth 0): true if any submenu is open\n * - Submenu at depth N: true if a deeper submenu is open\n */\n hasOpenSubmenu: createSelector(\n (state: OpenChainState, depth: number) => state.chain.length > depth,\n ),\n}\n\n// ============================================================================\n// Store\n// ============================================================================\n\n/**\n * Tracks which submenu surfaces are currently open in order.\n * Used to show backdrops for all open menus in the chain.\n * Single instance per menu tree (created at root, shared via context).\n *\n * Used by: DropdownMenu, ContextMenu\n * Not used by: Select, CommandMenu (no submenus)\n */\nexport class OpenChainStore extends ReactStore<\n OpenChainState,\n {},\n typeof selectors\n> {\n constructor() {\n super({ chain: [] }, {}, selectors)\n }\n\n /**\n * Mark a surface as open (adds to end of chain).\n */\n open(surfaceId: string) {\n // Don't add duplicates\n if (this.state.chain.includes(surfaceId)) return\n\n const newChain = [...this.state.chain, surfaceId]\n this.set('chain', newChain)\n }\n\n /**\n * Mark a surface as closed (removes from chain).\n */\n close(surfaceId: string) {\n const newChain = this.state.chain.filter((id) => id !== surfaceId)\n this.set('chain', newChain)\n }\n\n /**\n * Clear all open surfaces (menu tree closed).\n */\n clear() {\n this.set('chain', [])\n }\n}\n\nexport type { OpenChainState as State }\n","export type AnchorSide = 'left' | 'right' | 'top' | 'bottom'\n\nfunction resolveSideFromPoint(rect: DOMRect, x: number, y: number): AnchorSide {\n const outsideCandidates: Array<{ side: AnchorSide; gap: number }> = []\n\n const leftGap = rect.left - x\n if (leftGap > 0) {\n outsideCandidates.push({ side: 'left', gap: leftGap })\n }\n\n const rightGap = x - rect.right\n if (rightGap > 0) {\n outsideCandidates.push({ side: 'right', gap: rightGap })\n }\n\n const topGap = rect.top - y\n if (topGap > 0) {\n outsideCandidates.push({ side: 'top', gap: topGap })\n }\n\n const bottomGap = y - rect.bottom\n if (bottomGap > 0) {\n outsideCandidates.push({ side: 'bottom', gap: bottomGap })\n }\n\n if (outsideCandidates.length > 0) {\n outsideCandidates.sort((a, b) => b.gap - a.gap)\n return outsideCandidates[0]!.side\n }\n\n const insideDistances: Array<{ side: AnchorSide; value: number }> = [\n { side: 'left', value: Math.abs(x - rect.left) },\n { side: 'right', value: Math.abs(x - rect.right) },\n { side: 'top', value: Math.abs(y - rect.top) },\n { side: 'bottom', value: Math.abs(y - rect.bottom) },\n ]\n\n insideDistances.sort((a, b) => a.value - b.value)\n return insideDistances[0]!.side\n}\n\n/**\n * Determines which side of the submenu the trigger is anchored to.\n * Used to know which direction the user should be moving toward.\n */\nexport function resolveAnchorSide(\n rect: DOMRect,\n tRect: DOMRect | null,\n mx: number,\n my?: number,\n): AnchorSide {\n if (tRect) {\n const tx = (tRect.left + tRect.right) / 2\n const ty = (tRect.top + tRect.bottom) / 2\n\n return resolveSideFromPoint(rect, tx, ty)\n }\n\n if (my === undefined) {\n if (mx < rect.left) {\n return 'left'\n }\n if (mx > rect.right) {\n return 'right'\n }\n\n const centerX = (rect.left + rect.right) / 2\n return mx <= centerX ? 'left' : 'right'\n }\n\n return resolveSideFromPoint(rect, mx, my)\n}\n\n/**\n * Calculates a smoothed heading vector from the mouse trail.\n * If movement is too slow, infers direction toward the submenu center.\n */\nexport function getSmoothedHeading(\n trail: [number, number][],\n exitX: number,\n exitY: number,\n anchor: AnchorSide,\n tRect: DOMRect | null,\n rect: DOMRect,\n): { dx: number; dy: number } {\n let dx = 0\n let dy = 0\n const n = Math.min(Math.max(trail.length - 1, 0), 4)\n for (let i = trail.length - n - 1; i < trail.length - 1; i++) {\n if (i < 0) continue\n const [x1, y1] = trail[i]!\n const [x2, y2] = trail[i + 1]!\n dx += x2 - x1\n dy += y2 - y1\n }\n const mag = Math.hypot(dx, dy)\n if (mag < 0.5) {\n const tx = tRect ? (tRect.left + tRect.right) / 2 : exitX\n const ty = tRect ? (tRect.top + tRect.bottom) / 2 : exitY\n\n if (anchor === 'left' || anchor === 'right') {\n const edgeX = anchor === 'right' ? rect.right : rect.left\n const edgeCy = (rect.top + rect.bottom) / 2\n dx = edgeX - tx\n dy = edgeCy - ty\n } else {\n const edgeY = anchor === 'top' ? rect.top : rect.bottom\n const edgeCx = (rect.left + rect.right) / 2\n dx = edgeCx - tx\n dy = edgeY - ty\n }\n }\n return { dx, dy }\n}\n\n/**\n * Tests if the user's trajectory will intersect the submenu's safe zone.\n * Returns true if the user is aiming toward the submenu.\n */\nexport function willHitSubmenu(\n exitX: number,\n exitY: number,\n heading: { dx: number; dy: number },\n rect: DOMRect,\n anchor: AnchorSide,\n triggerRect: DOMRect | null,\n): boolean {\n const { dx, dy } = heading\n\n const isHorizontal = anchor === 'left' || anchor === 'right'\n const primary = isHorizontal ? dx : dy\n if (Math.abs(primary) < 0.01) {\n return false\n }\n\n if (\n (anchor === 'left' && dx <= 0) ||\n (anchor === 'right' && dx >= 0) ||\n (anchor === 'top' && dy <= 0) ||\n (anchor === 'bottom' && dy >= 0)\n ) {\n return false\n }\n\n const edge =\n anchor === 'left'\n ? rect.left\n : anchor === 'right'\n ? rect.right\n : anchor === 'top'\n ? rect.top\n : rect.bottom\n\n const t = (edge - (isHorizontal ? exitX : exitY)) / primary\n if (t <= 0) return false\n\n const projected = isHorizontal ? exitY + t * dy : exitX + t * dx\n\n const triggerCrossSize = triggerRect\n ? isHorizontal\n ? triggerRect.height\n : triggerRect.width\n : null\n const baseBand = triggerCrossSize ? triggerCrossSize * 0.75 : 28\n const extra = Math.max(12, Math.min(36, baseBand))\n\n const min = (isHorizontal ? rect.top : rect.left) - extra * 0.25\n const max = (isHorizontal ? rect.bottom : rect.right) + extra * 0.25\n\n return projected >= min && projected <= max\n}\n","import * as React from 'react'\n\ntype MousePoint = [number, number]\n\ninterface MouseTrailSubscriber {\n trailRef: React.MutableRefObject<MousePoint[]>\n limit: number\n}\n\nconst mouseTrailSubscribers = new Set<MouseTrailSubscriber>()\n\nlet removeMouseTrailListener: (() => void) | null = null\n\nfunction ensureMouseTrailListener() {\n if (removeMouseTrailListener !== null || typeof window === 'undefined') {\n return\n }\n\n const onMove = (event: PointerEvent) => {\n for (const subscriber of mouseTrailSubscribers) {\n const trail = subscriber.trailRef.current\n trail.push([event.clientX, event.clientY])\n if (trail.length > subscriber.limit) {\n trail.shift()\n }\n }\n }\n\n window.addEventListener('pointermove', onMove, { passive: true })\n\n removeMouseTrailListener = () => {\n window.removeEventListener('pointermove', onMove)\n removeMouseTrailListener = null\n }\n}\n\nfunction cleanupMouseTrailListenerIfIdle() {\n if (mouseTrailSubscribers.size === 0) {\n removeMouseTrailListener?.()\n }\n}\n\n/**\n * Keeps track of the last N mouse positions without causing re-renders.\n * Used for calculating mouse trajectory in aim guard.\n */\nexport function useMouseTrail(n = 4) {\n const trailRef = React.useRef<MousePoint[]>([])\n\n React.useEffect(() => {\n const subscriber: MouseTrailSubscriber = {\n trailRef,\n limit: n,\n }\n\n mouseTrailSubscribers.add(subscriber)\n ensureMouseTrailListener()\n\n return () => {\n mouseTrailSubscribers.delete(subscriber)\n trailRef.current = []\n cleanupMouseTrailListenerIfIdle()\n }\n }, [n])\n\n return trailRef\n}\n","'use client'\n\nimport * as React from 'react'\nimport type {\n ChangeEventDetails,\n GenericEventDetails,\n} from '../../../utils/events/index.js'\nimport {\n createChangeEventDetails,\n REASONS,\n} from '../../../utils/events/index.js'\nimport { ListboxStore, type VirtualItem } from '../../listbox/index.js'\nimport type { VirtualizationConfig } from '../contexts/popup-menu-context.js'\nimport type {\n HighlightChangeReason,\n PopupMenuOpenChangeReason,\n} from '../events.js'\nimport { FocusOwnerStore } from '../store/FocusOwnerStore.js'\nimport { OpenChainStore } from '../store/OpenChainStore.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface UsePopupMenuRootParams {\n /**\n * Callback when the open state changes.\n * The second parameter contains event details including the reason for the change.\n */\n onOpenChange?: (\n open: boolean,\n eventDetails: ChangeEventDetails<string>,\n ) => void\n\n /**\n * Whether the menu is initially open.\n * @default false\n */\n defaultOpen?: boolean\n\n /**\n * Whether virtualization mode is enabled.\n * @default false\n */\n virtualized?: boolean\n\n /**\n * Pre-registered items for virtualization.\n */\n items?: VirtualItem[]\n\n /**\n * Callback when the highlighted item changes.\n * The third parameter contains event details including the reason for the change.\n */\n onHighlightChange?: (\n id: string | null,\n index: number,\n eventDetails: GenericEventDetails<string, { index: number }>,\n ) => void\n\n /**\n * When to close the menu on outside interactions.\n * - 'pointerdown': Close immediately when pointer is pressed outside (default)\n * - 'click': Close when a full click (pointerdown + pointerup) occurs outside\n * @default 'pointerdown'\n */\n closeOnOutsidePress?: 'click' | 'pointerdown'\n\n /**\n * Whether the menu should ignore user interaction.\n * Can be controlled declaratively via this prop, or imperatively via actionsRef.setDisabled().\n * @default false\n */\n disabled?: boolean\n\n /**\n * Initial disabled state for imperative usage.\n * Ignored when `disabled` prop is true.\n * @default false\n */\n defaultDisabled?: boolean\n}\n\nexport interface PopupMenuRootActions {\n /** Close the menu tree imperatively. */\n close: () => void\n /** Unmount the popup imperatively (when keep-mounted mode is enabled). */\n unmount: () => void\n /** Enable/disable the menu tree imperatively. */\n setDisabled: (disabled: boolean) => void\n}\n\nexport interface UsePopupMenuRootReturn {\n /** The Listbox store instance */\n store: ListboxStore\n /** The FocusOwner store instance */\n focusOwnerStore: FocusOwnerStore\n /** The OpenChain store instance */\n openChainStore: OpenChainStore\n /** Register a surface (submenu) for closeAll tracking */\n registerSurface: (\n depth: number,\n setOpen: (open: boolean) => void,\n ) => () => void\n /** Close the entire menu tree */\n closeAll: (reason?: PopupMenuOpenChangeReason, event?: Event) => void\n /** Virtualization configuration (if enabled) */\n virtualization: VirtualizationConfig | undefined\n /** Handle open state change (updates store and clears stores on close) */\n handleOpenChange: (\n open: boolean,\n reason?: PopupMenuOpenChangeReason,\n event?: Event,\n ) => void\n /** Whether the menu currently ignores user interaction. */\n disabled: boolean\n /** Update imperative disabled state. */\n setDisabled: (disabled: boolean) => void\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * Hook that creates and manages the core stores and utilities for popup menus.\n * Used by both DropdownMenu.Root and ContextMenu.Root.\n *\n * Provides:\n * - ListboxStore for item management\n * - FocusOwnerStore for focus tracking across submenus\n * - OpenChainStore for tracking open submenu chain\n * - Surface registry for closeAll functionality\n */\nexport function usePopupMenuRoot(\n params: UsePopupMenuRootParams = {},\n): UsePopupMenuRootReturn {\n const {\n onOpenChange,\n defaultOpen = false,\n virtualized = false,\n items: itemsProp,\n onHighlightChange,\n closeOnOutsidePress = 'pointerdown',\n disabled: disabledProp = false,\n defaultDisabled = false,\n } = params\n\n const [imperativeDisabled, setImperativeDisabled] =\n React.useState(defaultDisabled)\n const disabled = disabledProp || imperativeDisabled\n\n const setDisabled = React.useCallback((nextDisabled: boolean) => {\n setImperativeDisabled(nextDisabled)\n }, [])\n\n // Track outside pointer events to distinguish outside-press from focus-out\n // When a pointerdown happens outside the menu, we store it so that if a\n // focus-out close happens immediately after, we can treat it as outside-press\n const outsidePointerEventRef = React.useRef<PointerEvent | null>(null)\n\n // Create stable callback wrapper for onOpenChange that converts focus-out to outside-press\n // when the close was triggered by a pointer event outside the menu\n const stableOnOpenChange = React.useCallback(\n (open: boolean, eventDetails: ChangeEventDetails<string>) => {\n // If closing due to focus-out but we have a stored outside pointer event,\n // convert the reason to outside-press for better cancel() support\n if (\n !open &&\n eventDetails.reason === REASONS.focusOut &&\n outsidePointerEventRef.current\n ) {\n const pointerEvent = outsidePointerEventRef.current\n outsidePointerEventRef.current = null\n\n // Create new event details with outside-press reason and the pointer event\n const convertedDetails = createChangeEventDetails(\n REASONS.outsidePress,\n pointerEvent,\n )\n\n onOpenChange?.(open, convertedDetails)\n\n // If the converted callback canceled, also cancel the original\n if (convertedDetails.isCanceled) {\n eventDetails.cancel()\n }\n return\n }\n\n // Clear the pointer event ref if we're not using it\n outsidePointerEventRef.current = null\n\n onOpenChange?.(open, eventDetails)\n },\n [onOpenChange],\n )\n\n // Create the store instance\n const store = ListboxStore.useStore(\n undefined,\n { open: defaultOpen },\n {\n onOpenChange: stableOnOpenChange,\n },\n )\n\n // Get current open state for the pointer event listener\n const isOpen = store.useState('open')\n\n // Create focus owner store (single instance for entire menu tree)\n const focusOwnerStoreRef = React.useRef<FocusOwnerStore | null>(null)\n if (!focusOwnerStoreRef.current) {\n focusOwnerStoreRef.current = new FocusOwnerStore()\n }\n const focusOwnerStore = focusOwnerStoreRef.current\n\n // Create open chain store (single instance for entire menu tree)\n const openChainStoreRef = React.useRef<OpenChainStore | null>(null)\n if (!openChainStoreRef.current) {\n openChainStoreRef.current = new OpenChainStore()\n }\n const openChainStore = openChainStoreRef.current\n\n // Registry for tracking open submenus (for closeAll)\n type SurfaceEntry = { depth: number; setOpen: (open: boolean) => void }\n const surfaceRegistryRef = React.useRef<Map<string, SurfaceEntry>>(new Map())\n\n // Register a surface (submenu) for closeAll tracking\n const registerSurface = React.useCallback(\n (depth: number, setOpen: (open: boolean) => void) => {\n const id = Math.random().toString(36).slice(2)\n surfaceRegistryRef.current.set(id, { depth, setOpen })\n return () => {\n surfaceRegistryRef.current.delete(id)\n }\n },\n [],\n )\n\n // Close the entire menu tree from deepest submenu to root\n const closeAll = React.useCallback(\n (reason: PopupMenuOpenChangeReason = REASONS.itemPress, event?: Event) => {\n // Sort surfaces by depth (deepest first)\n const surfaces = [...surfaceRegistryRef.current.values()].sort(\n (a, b) => b.depth - a.depth,\n )\n\n // Close each submenu from deepest to shallowest\n for (const surface of surfaces) {\n surface.setOpen(false)\n }\n\n // Finally close the root\n store.setOpen(false, reason, event)\n\n // Clear focus ownership and open chain\n focusOwnerStore.clearOwner()\n openChainStore.clear()\n },\n [store, focusOwnerStore, openChainStore],\n )\n\n // Ref to hold closeAll for use in the pointerdown effect\n const closeAllRef = React.useRef(closeAll)\n closeAllRef.current = closeAll\n\n // Listen for pointerdown events on document to detect outside clicks\n // This is a single listener at the root level that handles the entire menu tree.\n // Behavior depends on closeOnOutsidePress:\n // - 'pointerdown': Close immediately when pointer is pressed outside\n // - 'click': Store event and convert focus-out to outside-press reason\n React.useEffect(() => {\n if (!isOpen || disabled) {\n outsidePointerEventRef.current = null\n return\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Element | null\n if (!target) return\n\n // Check if the pointerdown is inside any part of the menu tree or its triggers\n // base-ui sets data-open on popups and data-popup-open on triggers\n const isInsidePopup = target.closest('[data-open]') !== null\n const isInsideTrigger = target.closest('[data-popup-open]') !== null\n const isInside = isInsidePopup || isInsideTrigger\n\n if (closeOnOutsidePress === 'pointerdown' && !isInside) {\n // Close entire menu tree immediately on pointerdown outside\n closeAllRef.current(REASONS.outsidePress, event)\n } else {\n // Store the event for focus-out-to-outside-press conversion\n outsidePointerEventRef.current = event\n }\n }\n\n // Use capture phase to see the event before any stopPropagation\n document.addEventListener('pointerdown', handlePointerDown, true)\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown, true)\n outsidePointerEventRef.current = null\n }\n }, [isOpen, closeOnOutsidePress, disabled])\n\n // Handle open state change\n const handleOpenChange = React.useCallback(\n (\n newOpen: boolean,\n reason: PopupMenuOpenChangeReason = REASONS.none,\n event?: Event,\n ) => {\n const isImperativeAction = reason === REASONS.imperativeAction\n\n // Ignore user-driven open/close interactions while disabled.\n if (disabled && !isImperativeAction) {\n return\n }\n\n store.setOpen(newOpen, reason, event)\n // Clear focus ownership and open chain when menu closes\n if (!newOpen) {\n focusOwnerStore.clearOwner()\n openChainStore.clear()\n }\n },\n [store, focusOwnerStore, openChainStore, disabled],\n )\n\n // Memoize listbox wiring config\n const virtualization = React.useMemo(() => {\n if (!virtualized && !onHighlightChange) {\n return undefined\n }\n\n return {\n virtualized,\n items: itemsProp ?? [],\n onHighlightChange,\n }\n }, [virtualized, itemsProp, onHighlightChange])\n\n return {\n store,\n focusOwnerStore,\n openChainStore,\n registerSurface,\n closeAll,\n virtualization,\n handleOpenChange,\n disabled,\n setDisabled,\n }\n}\n","export enum PopupMenuArrowDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-arrow' | 'bazzaui-context-menu-arrow' | 'bazzaui-select-arrow' | 'bazzaui-combobox-arrow'}\n */\n slot = 'bazzaui-[component]-arrow',\n /**\n * Present when the popup menu is open.\n */\n open = 'data-open',\n /**\n * Present when the popup menu is closed.\n */\n closed = 'data-closed',\n /**\n * Indicates which side the popup is positioned relative to the trigger.\n * @type {'top' | 'bottom' | 'left' | 'right' | 'inline-end' | 'inline-start'}\n */\n side = 'data-side',\n /**\n * Indicates how the popup is aligned relative to specified side.\n * @type {'start' | 'center' | 'end'}\n */\n align = 'data-align',\n /**\n * Present when the arrow is not centered due to collision avoidance.\n */\n uncentered = 'data-uncentered',\n}\n","'use client'\n\nimport { Popover, type PopoverArrowProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\n\nexport interface PopupMenuArrowProps extends PopoverArrowProps {}\n\n/**\n * An optional arrow element to render alongside the popup menu.\n * This can be used to help visually link the trigger with the popup.\n * Must be rendered inside `Popup`.\n * Renders a `<div>` element.\n */\nexport const PopupMenuArrow = React.forwardRef<\n HTMLDivElement,\n PopupMenuArrowProps\n>(function PopupMenuArrow(props, forwardedRef) {\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'arrow')\n\n return (\n <Popover.Arrow\n ref={forwardedRef}\n {...(slotAttr ? { [slotAttr]: '' } : {})}\n {...props}\n />\n )\n})\n\nexport namespace PopupMenuArrow {\n export type Props = PopupMenuArrowProps\n export type State = Popover.Arrow.State\n}\n","export enum PopupMenuBackdropDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-backdrop' | 'bazzaui-context-menu-backdrop' | 'bazzaui-select-backdrop' | 'bazzaui-combobox-backdrop'}\n */\n slot = 'bazzaui-[component]-backdrop',\n /**\n * Present when the popup menu is open.\n */\n open = 'data-open',\n /**\n * Present when the popup menu is closed.\n */\n closed = 'data-closed',\n /**\n * Present when the popup menu is animating in.\n */\n startingStyle = 'data-starting-style',\n /**\n * Present when the popup menu is animating out.\n */\n endingStyle = 'data-ending-style',\n}\n","'use client'\n\nimport { Popover, type PopoverBackdropProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport {\n useFocusOwner,\n useMaybeSubmenuContext,\n useOpenChain,\n} from '../../index.js'\n\nexport interface PopupMenuBackdropProps extends PopoverBackdropProps {\n /**\n * Controls when the backdrop becomes visible for submenus.\n * - `\"focus\"`: Show when the submenu becomes the focus owner (prevents flicker on hover).\n * If a deeper submenu is open, the backdrop remains visible.\n * - `\"open\"`: Show as soon as the submenu opens, regardless of focus.\n *\n * @default \"focus\" for submenus, \"open\" for root menu\n */\n showOn?: 'focus' | 'open'\n}\n\n/**\n * An overlay displayed beneath the popup menu.\n *\n * For submenus with `showOn=\"focus\"` (default), the backdrop visibility follows these rules:\n * - If this submenu is at the end of the open chain (deepest), it must be\n * the focus owner to show the backdrop (prevents flicker on hover)\n * - If this submenu is in the chain but not at the end (has a deeper submenu open),\n * the backdrop remains visible\n *\n * With `showOn=\"open\"`, the backdrop shows as soon as the submenu opens.\n *\n * Renders a `<div>` element with `pointer-events: none`.\n */\nexport const PopupMenuBackdrop = React.forwardRef<\n HTMLDivElement,\n PopupMenuBackdrop.Props\n>(function PopupMenuBackdrop(props, forwardedRef) {\n const { showOn: showOnProp, ...rest } = props\n\n const submenuContext = useMaybeSubmenuContext()\n const openChainStore = useOpenChain()\n const focusOwnerStore = useFocusOwner()\n\n const isSubmenu = submenuContext !== null\n const surfaceId = submenuContext?.childSurfaceId ?? ''\n\n // Default: \"focus\" for submenus, \"open\" for root\n const showOn = showOnProp ?? (isSubmenu ? 'focus' : 'open')\n\n // Check if this surface is in the open chain\n const isInOpenChain = openChainStore.useState('isOpen', surfaceId)\n\n // Check if this surface is the last (deepest) in the chain\n const isLastInChain = openChainStore.useState('isLast', surfaceId)\n\n // Check if this surface is the focus owner\n const isFocusOwner = focusOwnerStore.useState('isOwner', surfaceId)\n\n // Determine visibility\n let shouldShow = true\n if (isSubmenu) {\n if (showOn === 'open') {\n // Show as soon as submenu is open\n shouldShow = isInOpenChain\n } else {\n // showOn === 'focus'\n if (isLastInChain) {\n // Deepest submenu: only show if we're the focus owner\n shouldShow = isFocusOwner\n } else {\n // Not the deepest: show if we're in the chain (a deeper submenu is open)\n shouldShow = isInOpenChain\n }\n }\n }\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'backdrop')\n\n if (!shouldShow) {\n return null\n }\n\n // Merge pointer-events: none into style to prevent backdrop from\n // intercepting pointer events meant for the menu\n const style: React.CSSProperties = {\n pointerEvents: 'none',\n ...rest.style,\n }\n\n return (\n <Popover.Backdrop\n ref={forwardedRef}\n {...(slotAttr ? { [slotAttr]: '' } : {})}\n {...rest}\n style={style}\n />\n )\n})\n\nexport namespace PopupMenuBackdrop {\n export type Props = PopupMenuBackdropProps\n export type State = Popover.Backdrop.State\n}\n","export enum PopupMenuPopupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-popup' | 'bazzaui-context-menu-popup' | 'bazzaui-select-popup' | 'bazzaui-combobox-popup'}\n */\n slot = 'bazzaui-[component]-popup',\n /**\n * Present when the popup menu is open.\n */\n open = 'data-open',\n /**\n * Present when the popup menu is closed.\n */\n closed = 'data-closed',\n /**\n * Indicates which side the popup is positioned relative to the trigger.\n * @type {'top' | 'bottom' | 'left' | 'right'}\n */\n side = 'data-side',\n /**\n * Indicates how the popup is aligned relative to specified side.\n * @type {'start' | 'center' | 'end'}\n */\n align = 'data-align',\n /**\n * Present when the popup is animating in.\n */\n startingStyle = 'data-starting-style',\n /**\n * Present when the popup is animating out.\n */\n endingStyle = 'data-ending-style',\n /**\n * Present if animations should be instant.\n * @type {'click' | 'dismiss'}\n */\n instant = 'data-instant',\n /**\n * Present when this popup's surface is the focus owner.\n * Useful for styling the currently focused menu in a submenu chain.\n */\n focused = 'data-focused',\n /**\n * Present when this popup has an open submenu below it in the menu tree.\n * Useful for styling all parent menus in an open submenu chain.\n */\n hasOpenSubmenu = 'data-has-open-submenu',\n /**\n * Present when this popup is a submenu (not the root menu).\n * Useful for applying different styles to submenus vs root menus.\n */\n submenu = 'data-submenu',\n /**\n * Present while navigating between subpages in this popup.\n * Useful for temporary transition adjustments during subpage focus handoff.\n */\n navigating = 'data-navigating',\n}\n","'use client'\n\nimport { Popover, type PopoverPopupProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport { useMaybeComboboxContext } from '../../../../combobox/contexts/combobox-context.js'\nimport type { ComponentRenderFn } from '../../../../utils/types.js'\nimport { POINTER_EVENT_DEBOUNCE_MS } from '../../constants.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { useOpenChain } from '../../contexts/open-chain-context.js'\nimport { useMaybePopupMenuContext } from '../../contexts/popup-menu-context.js'\nimport { PopupSurfaceIdContext } from '../../contexts/popup-surface-id-context.js'\nimport { useMaybeSubmenuContext } from '../../contexts/submenu-context.js'\nimport {\n ROOT_SUBPAGE_ID,\n SubpageStackContext,\n} from '../../contexts/subpage-stack-context.js'\nimport {\n DataPopupContext,\n type DataSurfaceContextValue,\n} from '../../deep-search/context.js'\nimport { useAimGuard } from '../../hooks/use-aim-guard.js'\nimport { PopupMenuPopupDataAttributes } from './popup.data-attrs.js'\n\nconst SUBPAGE_NAVIGATING_MS = 140\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PopupMenuPopupState extends Popover.Popup.State {\n /**\n * Whether this popup is a submenu (not the root menu).\n */\n isSubmenu: boolean\n\n /**\n * Whether any non-root subpage is currently open.\n */\n hasOpenSubpage: boolean\n\n /**\n * Active subpage ID, or null when only the root page is open.\n */\n subpageId: string | null\n\n /**\n * Ordered stack of open non-root subpage IDs.\n * For nested subpages this includes each page in open order.\n */\n openSubpageIds: string[]\n}\n\nexport interface PopupMenuPopupProps\n extends Omit<PopoverPopupProps, 'className' | 'render'> {\n /**\n * CSS class applied to the element, or a function that\n * returns a class based on the component's state.\n */\n className?: string | ((state: PopupMenuPopupState) => string)\n\n /**\n * Allows replacing the popup element with a custom element.\n * The render state includes popup + subpage navigation state.\n */\n render?:\n | React.ReactElement\n | ComponentRenderFn<React.HTMLAttributes<HTMLElement>, PopupMenuPopupState>\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * A container for the popup menu contents.\n * Wraps Popover.Popup with:\n * - Aim guard clearing when pointer enters submenu\n * - Focus ownership transfer when pointer enters submenu\n * - Auto-focus disabled for submenus (focus managed by FocusOwner system)\n *\n * Renders a `<div>` element.\n */\nexport const PopupMenuPopup = React.forwardRef<\n HTMLDivElement,\n PopupMenuPopup.Props\n>(function PopupMenuPopup(props, forwardedRef) {\n const {\n children,\n className: classNameProp,\n render: renderProp,\n ...rest\n } = props\n\n // Get submenu context to set contentRef for aim guard and get childSurfaceId for focus transfer\n const submenuContext = useMaybeSubmenuContext()\n\n // Get aim guard to clear it when pointer enters submenu\n const { clearAimGuard, aimGuardActiveRef, guardedSubmenuSurfaceIdRef } =\n useAimGuard()\n\n // Get focus owner store for transferring ownership\n const focusOwnerStore = useFocusOwner()\n\n // Get open chain store for tracking submenu chain\n const openChainStore = useOpenChain()\n\n // Get popup menu context for depth\n const popupMenuContext = useMaybePopupMenuContext()\n const depth = popupMenuContext?.depth ?? 0\n\n // Get combobox context to detect if we're inside a combobox and for layout\n const comboboxContext = useMaybeComboboxContext()\n\n // Generate surfaceId for root menus, use submenu context for submenus\n const generatedSurfaceId = React.useId()\n const surfaceId = submenuContext?.childSurfaceId ?? generatedSurfaceId\n\n // Subpage stack state (per popup instance)\n const [subpageStack, setSubpageStack] = React.useState<string[]>([\n ROOT_SUBPAGE_ID,\n ])\n const [dataSurfaceContext, setDataSurfaceContext] =\n React.useState<DataSurfaceContextValue | null>(null)\n const subpageStackRef = React.useRef(subpageStack)\n React.useEffect(() => {\n subpageStackRef.current = subpageStack\n }, [subpageStack])\n\n const subpagesRef = React.useRef<\n Map<string, { surfaceId: string; closeRootOnEsc: boolean }>\n >(new Map())\n const [, setSubpageRegistryVersion] = React.useState(0)\n const [isSubpageNavigating, setIsSubpageNavigating] = React.useState(false)\n const subpageNavigatingTimerRef = React.useRef<ReturnType<\n typeof setTimeout\n > | null>(null)\n\n const clearSubpageNavigatingTimer = React.useCallback(() => {\n if (subpageNavigatingTimerRef.current !== null) {\n clearTimeout(subpageNavigatingTimerRef.current)\n subpageNavigatingTimerRef.current = null\n }\n }, [])\n\n const beginSubpageNavigation = React.useCallback(() => {\n setIsSubpageNavigating(true)\n clearSubpageNavigatingTimer()\n subpageNavigatingTimerRef.current = setTimeout(() => {\n subpageNavigatingTimerRef.current = null\n setIsSubpageNavigating(false)\n }, SUBPAGE_NAVIGATING_MS)\n }, [clearSubpageNavigatingTimer])\n\n React.useEffect(\n () => clearSubpageNavigatingTimer,\n [clearSubpageNavigatingTimer],\n )\n\n React.useEffect(() => {\n subpagesRef.current.set(ROOT_SUBPAGE_ID, {\n surfaceId,\n closeRootOnEsc: true,\n })\n setSubpageRegistryVersion((v) => v + 1)\n return () => {\n subpagesRef.current.delete(ROOT_SUBPAGE_ID)\n setSubpageRegistryVersion((v) => v + 1)\n }\n }, [surfaceId])\n\n const registerPage = React.useCallback(\n (registration: {\n pageId: string\n surfaceId: string\n closeRootOnEsc: boolean\n }) => {\n subpagesRef.current.set(registration.pageId, {\n surfaceId: registration.surfaceId,\n closeRootOnEsc: registration.closeRootOnEsc,\n })\n setSubpageRegistryVersion((v) => v + 1)\n\n return () => {\n subpagesRef.current.delete(registration.pageId)\n setSubpageRegistryVersion((v) => v + 1)\n\n setSubpageStack((prev) => {\n if (!prev.includes(registration.pageId)) {\n return prev\n }\n const next = prev.filter((id) => id !== registration.pageId)\n return next.length > 0 ? next : [ROOT_SUBPAGE_ID]\n })\n }\n },\n [],\n )\n\n const openPage = React.useCallback(\n (pageId: string) => {\n if (!subpagesRef.current.has(pageId)) {\n return false\n }\n\n const currentStack = subpageStackRef.current\n const currentPageId = currentStack[currentStack.length - 1]\n if (currentPageId === pageId) {\n return false\n }\n\n setSubpageStack((prev) => [...prev, pageId])\n beginSubpageNavigation()\n return true\n },\n [beginSubpageNavigation],\n )\n\n const goBack = React.useCallback(() => {\n const currentStack = subpageStackRef.current\n if (currentStack.length <= 1) {\n return false\n }\n\n setSubpageStack((prev) => prev.slice(0, -1))\n beginSubpageNavigation()\n return true\n }, [beginSubpageNavigation])\n\n const getSurfaceId = React.useCallback(\n (pageId: string) => subpagesRef.current.get(pageId)?.surfaceId ?? null,\n [],\n )\n\n const resetSubpageNavigationState = React.useCallback(() => {\n setSubpageStack([ROOT_SUBPAGE_ID])\n setIsSubpageNavigating(false)\n clearSubpageNavigatingTimer()\n }, [clearSubpageNavigatingTimer])\n\n React.useEffect(() => {\n const store = popupMenuContext?.store\n if (!store) {\n return\n }\n\n const previous = store.context.onPopupCloseComplete\n const handlePopupCloseComplete = () => {\n previous?.()\n resetSubpageNavigationState()\n }\n\n store.context.onPopupCloseComplete = handlePopupCloseComplete\n\n return () => {\n if (store.context.onPopupCloseComplete === handlePopupCloseComplete) {\n store.context.onPopupCloseComplete = previous\n }\n clearSubpageNavigatingTimer()\n }\n }, [\n popupMenuContext?.store,\n resetSubpageNavigationState,\n clearSubpageNavigatingTimer,\n ])\n\n const activePageId = subpageStack[subpageStack.length - 1] ?? ROOT_SUBPAGE_ID\n const activePageRegistration = subpagesRef.current.get(activePageId)\n const activeSurfaceId = activePageRegistration?.surfaceId ?? surfaceId\n const shouldCloseRootOnEsc = activePageRegistration?.closeRootOnEsc ?? true\n const canGoBack = subpageStack.length > 1\n const openSubpageIds = React.useMemo(\n () => subpageStack.filter((pageId) => pageId !== ROOT_SUBPAGE_ID),\n [subpageStack],\n )\n const subpageId = openSubpageIds[openSubpageIds.length - 1] ?? null\n const hasOpenSubpage = subpageId !== null\n\n // Track when popup opened to ignore initial pointer events\n // This prevents focus transfer when the popup appears under a stationary cursor\n const openTimeRef = React.useRef<number>(0)\n\n // Record open time when popup opens\n React.useEffect(() => {\n if (submenuContext?.open) {\n openTimeRef.current = Date.now()\n }\n }, [submenuContext?.open])\n\n // Subscribe to focus ownership for data-focused attribute\n const isFocused = focusOwnerStore.useState('isOwner', activeSurfaceId)\n\n // Subscribe to open chain for data-has-open-submenu attribute\n const hasOpenSubmenu = openChainStore.useState('hasOpenSubmenu', depth)\n\n // Local ref for the popup element\n const popupRef = React.useRef<HTMLDivElement>(null)\n\n // Combine refs\n const combinedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n // Update local ref\n popupRef.current = node\n\n // Update forwarded ref\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n\n // Update submenu context contentRef for aim guard\n if (submenuContext?.contentRef) {\n ;(\n submenuContext.contentRef as React.MutableRefObject<HTMLElement | null>\n ).current = node\n }\n },\n [forwardedRef, submenuContext],\n )\n\n // Clear aim guard when pointer moves inside this submenu popup\n // Only clear if aim guard is actually active AND this is the target submenu\n const handlePointerMove = React.useCallback(() => {\n // Only handle if this is a submenu popup (not the root popup) and aim guard is active\n // Also verify this is the specific submenu the user was aiming for\n if (\n submenuContext &&\n aimGuardActiveRef.current &&\n guardedSubmenuSurfaceIdRef.current === surfaceId\n ) {\n clearAimGuard()\n }\n }, [\n submenuContext,\n aimGuardActiveRef,\n guardedSubmenuSurfaceIdRef,\n surfaceId,\n clearAimGuard,\n ])\n\n React.useEffect(() => {\n if (\n submenuContext?.open !== false ||\n !aimGuardActiveRef.current ||\n guardedSubmenuSurfaceIdRef.current !== surfaceId\n ) {\n return\n }\n\n clearAimGuard()\n }, [\n submenuContext?.open,\n aimGuardActiveRef,\n guardedSubmenuSurfaceIdRef,\n surfaceId,\n clearAimGuard,\n ])\n\n React.useEffect(() => {\n return () => {\n if (\n aimGuardActiveRef.current &&\n guardedSubmenuSurfaceIdRef.current === surfaceId\n ) {\n clearAimGuard()\n }\n }\n }, [aimGuardActiveRef, guardedSubmenuSurfaceIdRef, surfaceId, clearAimGuard])\n\n // Transfer focus ownership when pointer moves inside this submenu popup\n // We ignore events shortly after open to prevent focus transfer when\n // the popup appears under a stationary cursor\n const handleFocusTransferOnMove = React.useCallback(\n (event: React.PointerEvent) => {\n // Ignore pointer events briefly after popup opens\n // This prevents focus transfer when popup appears under stationary cursor\n const timeSinceOpen = Date.now() - openTimeRef.current\n if (timeSinceOpen < POINTER_EVENT_DEBOUNCE_MS) {\n return\n }\n\n // Only transfer focus if this is a submenu popup (not the root popup)\n // Use childSurfaceId from SubmenuContext since Popup is outside Surface in the component tree\n if (!submenuContext) {\n return\n }\n\n // Check if the event target is actually within this popup's DOM\n // This prevents parent popups from claiming ownership when events\n // bubble through React portals from child submenus\n const target = event.target as Node\n if (!popupRef.current?.contains(target)) {\n return\n }\n\n // Check if the target is inside a nested submenu popup\n // If so, don't claim ownership - let the nested popup handle it\n const targetElement =\n target instanceof Element ? target : target.parentElement\n if (targetElement) {\n // Find the closest popup ancestor of the target\n const closestPopup = targetElement.closest('[data-base-ui-focusable]')\n // If the closest popup is not this popup, don't claim ownership\n if (closestPopup && closestPopup !== popupRef.current) {\n return\n }\n }\n\n // Only claim ownership if we're not already the owner\n if (focusOwnerStore.state.ownerId !== submenuContext.childSurfaceId) {\n focusOwnerStore.setOwnerId(submenuContext.childSurfaceId)\n }\n },\n [submenuContext, focusOwnerStore],\n )\n\n // Disable Base UI's auto-focus behavior for:\n // - Submenus: Focus is managed by our FocusOwner system\n // - Combobox: Focus should stay on the input element (which is outside the popup)\n const initialFocus = submenuContext || comboboxContext ? false : undefined\n\n // Disable returning focus to trigger when popup closes for:\n // - Submenus: Focus is managed by our FocusOwner system (we transfer to parent surface's input/list)\n // - Combobox: When clicking outside, we want focus to go to whatever was clicked, not back to input\n const finalFocus = submenuContext || comboboxContext ? false : undefined\n\n // Add data-input-embedded attribute when layout is input-embedded\n const isInputEmbedded = comboboxContext?.layout === 'input-embedded'\n\n // Determine if this popup is a submenu (not the root menu)\n const isSubmenu = !!submenuContext\n\n const toPopupState = React.useCallback(\n (baseState: Popover.Popup.State): PopupMenuPopupState => ({\n ...baseState,\n isSubmenu,\n hasOpenSubpage,\n subpageId,\n openSubpageIds,\n }),\n [hasOpenSubpage, isSubmenu, openSubpageIds, subpageId],\n )\n\n // Wrap className to include isSubmenu in the state\n const className = React.useMemo(() => {\n if (typeof classNameProp === 'function') {\n return (baseState: Popover.Popup.State) => {\n return classNameProp(toPopupState(baseState))\n }\n }\n return classNameProp\n }, [classNameProp, toPopupState])\n\n const render = React.useMemo(() => {\n if (typeof renderProp === 'function') {\n return (\n popupProps: React.HTMLAttributes<HTMLElement>,\n baseState: Popover.Popup.State,\n ) => renderProp(popupProps, toPopupState(baseState))\n }\n\n return renderProp\n }, [renderProp, toPopupState])\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'popup')\n\n const subpageStackContextValue = React.useMemo(\n () => ({\n activePageId,\n activeSurfaceId,\n canGoBack,\n shouldCloseRootOnEsc,\n stack: subpageStack,\n registerPage,\n openPage,\n goBack,\n getSurfaceId,\n }),\n [\n activePageId,\n activeSurfaceId,\n canGoBack,\n shouldCloseRootOnEsc,\n subpageStack,\n registerPage,\n openPage,\n goBack,\n getSurfaceId,\n ],\n )\n\n const dataPopupContextValue = React.useMemo(\n () => ({\n dataSurfaceContext,\n setDataSurfaceContext,\n }),\n [dataSurfaceContext],\n )\n\n return (\n <PopupSurfaceIdContext.Provider value={surfaceId}>\n <SubpageStackContext.Provider value={subpageStackContextValue}>\n <DataPopupContext.Provider value={dataPopupContextValue}>\n <Popover.Popup\n ref={combinedRef}\n initialFocus={initialFocus}\n finalFocus={finalFocus}\n className={className}\n render={render}\n data-input-embedded={isInputEmbedded ? '' : undefined}\n {...(slotAttr ? { [slotAttr]: '' } : {})}\n {...{\n [PopupMenuPopupDataAttributes.focused]: isFocused\n ? ''\n : undefined,\n [PopupMenuPopupDataAttributes.hasOpenSubmenu]: hasOpenSubmenu\n ? ''\n : undefined,\n [PopupMenuPopupDataAttributes.submenu]: isSubmenu\n ? ''\n : undefined,\n [PopupMenuPopupDataAttributes.navigating]: isSubpageNavigating\n ? ''\n : undefined,\n }}\n onPointerMove={(event) => {\n handlePointerMove()\n handleFocusTransferOnMove(event)\n rest.onPointerMove?.(event)\n }}\n {...rest}\n >\n {children}\n </Popover.Popup>\n </DataPopupContext.Provider>\n </SubpageStackContext.Provider>\n </PopupSurfaceIdContext.Provider>\n )\n})\n\nexport namespace PopupMenuPopup {\n export type Props = PopupMenuPopupProps\n export type State = PopupMenuPopupState\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ItemEqualityComparer } from '../../utils/item-equality.js'\nimport type { ComboboxOpenChangeReason } from '../events.js'\nimport type { ComboboxLayout } from './combobox-positioner-context.js'\n\n// ============================================================================\n// Combobox Context\n// ============================================================================\n// Provides value management, input state, and form integration for Combobox.\n\n/**\n * Filter mode for the combobox.\n * Controls how the search/filter value is determined.\n *\n * State transitions:\n * - Closed → open (no value) → { type: 'active' }\n * - Closed → open (with value) → { type: 'showAll' }\n * - Open + user types → { type: 'active' }\n * - Open → close → { type: 'frozen', search: <current> }\n */\nexport type ComboboxFilterMode =\n | { type: 'active' } // Normal: use inputValue for filtering\n | { type: 'showAll' } // Opened with selected value, user hasn't typed yet\n | { type: 'frozen'; search: string } // Closing: freeze to this value during exit animation\n\n/**\n * Item text registry for displaying selected values.\n * Maps serialized item value to its text content.\n */\nexport type ItemTextRegistry = Map<string, string>\n\n/**\n * Context value for Combobox components.\n * Provides value state, input state, callbacks, and form integration.\n *\n * @template Value - The type of the combobox value (can be a primitive or object)\n */\nexport interface ComboboxContextValue<Value = unknown> {\n // ===== Selection State =====\n /** Whether multi-select mode is enabled */\n multiple: boolean\n /** Current selected value (single-select mode) */\n value: Value | null\n /** Current selected values (multi-select mode) */\n values: Value[]\n /** Callback when value changes (single-select mode) */\n onValueChange: (value: Value) => void\n /** Callback when values change (multi-select mode) */\n onValuesChange: (values: Value[]) => void\n\n // ===== Object Value Support =====\n /**\n * Custom comparison logic used to determine if a combobox item value\n * matches the current selected value.\n * Useful when item values are objects without matching referentially.\n * Defaults to Object.is comparison.\n */\n isItemEqualToValue: ItemEqualityComparer<Value>\n /**\n * When the item values are objects, this function converts the object\n * value to a string representation for display in the input.\n * If the shape of the object is { value, label }, the label will be\n * used automatically without needing to specify this prop.\n */\n itemToStringLabel?: (itemValue: Value) => string\n /**\n * When the item values are objects, this function converts the object\n * value to a string representation for form submission.\n * If the shape of the object is { value, label }, the value will be\n * used automatically without needing to specify this prop.\n */\n itemToStringValue?: (itemValue: Value) => string\n\n // ===== Input State =====\n /** Current input value */\n inputValue: string\n /** Callback when input value changes */\n onInputValueChange: (value: string) => void\n\n // ===== Form Integration =====\n /** Form field name for submission */\n name?: string\n /** Associate with a form by ID */\n form?: string\n /** Whether this field is required */\n required?: boolean\n /** Whether the combobox is disabled */\n disabled: boolean\n /** Placeholder text for the input */\n placeholder: string\n\n // ===== Item Text Registry =====\n /** Registry of item values to their text content */\n itemTextRegistry: ItemTextRegistry\n /** Register an item's text content */\n registerItemText: (value: string, text: string) => () => void\n /**\n * Data structure of the items for label resolution.\n * Used to display labels before items mount (e.g., on initial render with defaultValue).\n * Can be a record mapping values to labels, or an array of { value, label } objects.\n */\n items?:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n\n // ===== List ID for ARIA =====\n /** ID for the listbox element */\n listId: string\n\n // ===== Element Refs for Positioning =====\n /** Ref to the input element (also serves as anchor) */\n inputRef: React.RefObject<HTMLInputElement | null>\n /** Callback to set the input element */\n setInputElement: (element: HTMLInputElement | null) => void\n /** Ref to the input wrapper element (used as anchor when present) */\n inputWrapperRef: React.RefObject<HTMLElement | null>\n /** Callback to set the input wrapper element */\n setInputWrapperElement: (element: HTMLElement | null) => void\n\n // ===== Behavior =====\n /** Whether to close on selection (default: true for single, false for multiple) */\n closeOnSelect: boolean\n /** Whether to open on focus */\n openOnFocus: boolean\n /** Open the combobox */\n openCombobox: () => void\n /** Close the combobox with an optional reason and event */\n closeCombobox: (reason?: ComboboxOpenChangeReason, event?: Event) => void\n\n // ===== Filter Mode =====\n /**\n * Current filter mode for the combobox.\n * Controls how the search/filter value is determined.\n */\n filterMode: ComboboxFilterMode\n /** Set the filter mode to 'active' (normal filtering using inputValue) */\n setFilterActive: () => void\n\n // ===== Input Dimensions =====\n /**\n * Height of the input element in pixels.\n * Used by the positioner for input-embedded layout calculations.\n */\n inputHeight: number\n /**\n * Width of the input element in pixels.\n * Used by the positioner for input-embedded layout calculations.\n */\n inputWidth: number\n\n // ===== Layout =====\n /**\n * The layout mode for the combobox popup.\n * - `'floating'` - Standard dropdown positioning\n * - `'input-embedded'` - Popup wraps around the input (macOS-style)\n */\n layout: ComboboxLayout\n}\n\nconst ComboboxContext =\n React.createContext<ComboboxContextValue<unknown> | null>(null)\n\n/**\n * Hook to access the Combobox context.\n * Throws if used outside a Combobox.Root.\n */\nexport function useComboboxContext<\n Value = unknown,\n>(): ComboboxContextValue<Value> {\n const context = React.useContext(ComboboxContext)\n if (!context) {\n throw new Error('Combobox components must be used within a Combobox.Root')\n }\n return context as ComboboxContextValue<Value>\n}\n\n/**\n * Hook to optionally access the Combobox context.\n * Returns null if used outside a Combobox.Root.\n */\nexport function useMaybeComboboxContext<\n Value = unknown,\n>(): ComboboxContextValue<Value> | null {\n return React.useContext(ComboboxContext) as ComboboxContextValue<Value> | null\n}\n\nexport { ComboboxContext }\n","'use client'\n\nimport * as React from 'react'\nimport type {\n AsyncLoaderConfig,\n DeepSearchConfig,\n DisplayNode,\n GetQualifiedRowIdFn,\n IncludeInDeepSearch,\n NodeDef,\n} from './types.js'\n\n// ============================================================================\n// Data Surface Context\n// ============================================================================\n\nexport interface DataSurfaceContextValue {\n /** The original node definitions */\n content: NodeDef[]\n\n /** Async content configuration for root-level async loading */\n asyncContent?: AsyncLoaderConfig\n\n /** Deep search configuration */\n deepSearchConfig: DeepSearchConfig\n\n /** Default submenu inclusion mode for deep search */\n includeInDeepSearch: IncludeInDeepSearch\n\n /** List element ID for aria-activedescendant */\n listId: string\n\n /** Function to generate qualified IDs for row items */\n getQualifiedRowId: GetQualifiedRowIdFn\n}\n\nexport const DataSurfaceContext =\n React.createContext<DataSurfaceContextValue | null>(null)\n\n// ============================================================================\n// Popup-level Data Context (shared across sibling DataSurface/DataSubpages)\n// ============================================================================\n\nexport interface DataPopupContextValue {\n /** Latest DataSurface context registered within this popup. */\n dataSurfaceContext: DataSurfaceContextValue | null\n /** Registers/clears DataSurface context for sibling consumers. */\n setDataSurfaceContext: React.Dispatch<\n React.SetStateAction<DataSurfaceContextValue | null>\n >\n}\n\nexport const DataPopupContext =\n React.createContext<DataPopupContextValue | null>(null)\n\nexport function useDataSurfaceContext(): DataSurfaceContextValue {\n const context = React.useContext(DataSurfaceContext)\n if (!context) {\n throw new Error(\n 'useDataSurfaceContext must be used within a DataSurface component',\n )\n }\n return context\n}\n\nexport function useMaybeDataSurfaceContext(): DataSurfaceContextValue | null {\n return React.useContext(DataSurfaceContext)\n}\n\nexport function useDataPopupContext(): DataPopupContextValue {\n const context = React.useContext(DataPopupContext)\n if (!context) {\n throw new Error('Data components must be used within PopupMenu.Popup')\n }\n return context\n}\n\nexport function useMaybeDataPopupContext(): DataPopupContextValue | null {\n return React.useContext(DataPopupContext)\n}\n\n// ============================================================================\n// Render Node Function Type\n// ============================================================================\n\nexport type RenderNodeFn = (displayNode: DisplayNode) => React.ReactNode\n","'use client'\n\nimport { Popover, type PopoverPortalProps } from '@base-ui/react/popover'\n\nexport interface PopupMenuPortalProps extends PopoverPortalProps {}\n\n/**\n * A portal element that moves the popup to a different part of the DOM.\n * By default, the portal element is appended to `<body>`.\n */\nexport const PopupMenuPortal = Popover.Portal\n\nexport namespace PopupMenuPortal {\n export type Props = PopoverPortalProps\n export type State = Popover.Portal.State\n}\n","export enum PopupMenuPositionerCssVars {\n /**\n * The available width between the trigger and the edge of the viewport.\n * @type {number}\n */\n availableWidth = '--available-width',\n /**\n * The available height between the trigger and the edge of the viewport.\n * @type {number}\n */\n availableHeight = '--available-height',\n /**\n * The anchor's width.\n * @type {number}\n */\n anchorWidth = '--anchor-width',\n /**\n * The anchor's height.\n * @type {number}\n */\n anchorHeight = '--anchor-height',\n /**\n * The coordinates that this element is anchored to. Used for animations and transitions.\n * @type {string}\n */\n transformOrigin = '--transform-origin',\n /**\n * The width of the positioner element.\n * @type {number}\n */\n positionerWidth = '--positioner-width',\n /**\n * The height of the positioner element.\n * @type {number}\n */\n positionerHeight = '--positioner-height',\n}\n","export enum PopupMenuPositionerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-positioner' | 'bazzaui-context-menu-positioner' | 'bazzaui-select-positioner' | 'bazzaui-combobox-positioner'}\n */\n slot = 'bazzaui-[component]-positioner',\n /**\n * Present when the popup menu is open.\n */\n open = 'data-open',\n /**\n * Present when the popup menu is closed.\n */\n closed = 'data-closed',\n /**\n * Present when the anchor is hidden.\n */\n anchorHidden = 'data-anchor-hidden',\n /**\n * Indicates which side the popup is positioned relative to the trigger.\n * @type {'top' | 'bottom' | 'left' | 'right' | 'inline-end' | 'inline-start'}\n */\n side = 'data-side',\n /**\n * Indicates how the popup is aligned relative to specified side.\n * @type {'start' | 'center' | 'end' | 'list-start'}\n */\n align = 'data-align',\n}\n","'use client'\n\nimport { Popover, type PopoverPositionerProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { usePopupMenuContext } from '../../contexts/popup-menu-context.js'\nimport { useMaybeSubmenuContext } from '../../contexts/submenu-context.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ntype Side = 'top' | 'bottom' | 'left' | 'right' | 'inline-end' | 'inline-start'\n\nconst LIST_START_OFFSET_EPSILON = 0.5\n\n/**\n * Extended align options for popup menus.\n * - 'start' | 'center' | 'end': Standard Base UI alignment\n * - 'list-start': Align trigger top with the top of the List component (horizontal sides only)\n */\nexport type PopupMenuPositionerAlign =\n | PopoverPositionerProps['align']\n | 'list-start'\n\nexport interface PopupMenuPositionerProps\n extends Omit<PopoverPositionerProps, 'align' | 'style'> {\n /**\n * Override the virtual anchor from context.\n * Useful for nested menus that need different positioning.\n */\n virtualAnchor?: { getBoundingClientRect(): DOMRect }\n\n /**\n * How to align the popup relative to the specified side.\n * - 'start': align to start of anchor\n * - 'center': align to center of anchor\n * - 'end': align to end of anchor\n * - 'list-start': align the List component's top with the anchor top (horizontal sides only)\n * @default 'start' for submenus, 'center' for root dropdowns\n */\n align?: PopupMenuPositionerAlign\n\n /**\n * Custom styles for the positioner.\n * Note: During list-start alignment measurement, `transition: 'none'` is\n * temporarily applied to prevent visual flash.\n */\n style?: React.CSSProperties\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Returns the default collision avoidance strategy based on the side.\n *\n * - For horizontal sides (left/right): use shift to keep submenus visible\n * without flipping to the opposite side, which can be disorienting\n * - For vertical sides (top/bottom): use flip as the standard behavior\n */\nfunction getDefaultCollisionAvoidance(\n side: Side,\n): PopoverPositionerProps['collisionAvoidance'] {\n if (isHorizontalSide(side)) {\n return {\n side: 'shift',\n align: 'shift',\n }\n }\n\n // Vertical sides use flip (default Base UI behavior)\n return undefined\n}\n\n/**\n * Check if the side is horizontal (for list-start alignment).\n */\nfunction isHorizontalSide(side: Side): boolean {\n return (\n side === 'left' ||\n side === 'right' ||\n side === 'inline-start' ||\n side === 'inline-end'\n )\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Positions the popup menu against its anchor.\n * Wraps Popover.Positioner with:\n * - Automatic virtualAnchor from PopupMenuContext (for context menus)\n * - Smart default positioning based on depth and menu type\n * - Smart collision avoidance: shift for horizontal menus, flip for vertical\n * - 'list-start' alignment for horizontal submenus\n *\n * Renders a `<div>` element.\n */\nexport const PopupMenuPositioner = React.forwardRef<\n HTMLDivElement,\n PopupMenuPositioner.Props\n>(function PopupMenuPositioner(props, ref) {\n const {\n side: sideProp,\n align: alignProp,\n alignOffset: alignOffsetProp,\n collisionAvoidance: collisionAvoidanceProp,\n virtualAnchor: virtualAnchorProp,\n style: styleProp,\n ...rest\n } = props\n\n const {\n store,\n depth,\n virtualAnchor: contextVirtualAnchor,\n menuType,\n } = usePopupMenuContext()\n\n // Get submenu context to access contentRef for list-start measurement\n const submenuContext = useMaybeSubmenuContext()\n\n // Ref for calculated list-start offset\n // Using a ref instead of state to avoid re-renders that cause visual flash\n const listStartOffsetRef = React.useRef(0)\n\n // Track if the initial measurement has completed for this open cycle\n const hasMeasuredRef = React.useRef(false)\n\n // Counter to force re-render after measurement\n const [, forceUpdate] = React.useReducer((x) => x + 1, 0)\n\n // Suppress resize-driven re-measurements during hideUntilActive activation.\n // We intentionally avoid repositioning when the input appears.\n const suppressResizeMeasurementRef = React.useRef(false)\n const suppressionRafIdsRef = React.useRef<{\n first: number | null\n second: number | null\n }>({\n first: null,\n second: null,\n })\n\n const clearSuppressionRafs = React.useCallback(() => {\n if (typeof window === 'undefined') {\n suppressionRafIdsRef.current.first = null\n suppressionRafIdsRef.current.second = null\n return\n }\n\n if (suppressionRafIdsRef.current.first !== null) {\n window.cancelAnimationFrame(suppressionRafIdsRef.current.first)\n suppressionRafIdsRef.current.first = null\n }\n\n if (suppressionRafIdsRef.current.second !== null) {\n window.cancelAnimationFrame(suppressionRafIdsRef.current.second)\n suppressionRafIdsRef.current.second = null\n }\n }, [])\n\n const clearInputActivationSuppression = React.useCallback(() => {\n clearSuppressionRafs()\n suppressResizeMeasurementRef.current = false\n }, [clearSuppressionRafs])\n\n const suppressResizeForInputActivation = React.useCallback(() => {\n clearSuppressionRafs()\n suppressResizeMeasurementRef.current = true\n\n if (typeof window === 'undefined') {\n return\n }\n\n suppressionRafIdsRef.current.first = window.requestAnimationFrame(() => {\n suppressionRafIdsRef.current.first = null\n\n suppressionRafIdsRef.current.second = window.requestAnimationFrame(() => {\n suppressionRafIdsRef.current.second = null\n suppressResizeMeasurementRef.current = false\n })\n })\n }, [clearSuppressionRafs])\n\n // For submenus (depth > 0), we should NOT use the context's virtualAnchor\n // because the submenu should anchor to its trigger element, not the cursor position.\n // Only the root menu (depth 0) should use the virtual anchor for context menus.\n const isSubmenu = depth > 0\n const virtualAnchor = isSubmenu\n ? virtualAnchorProp // Only use explicit prop for submenus (usually undefined)\n : (virtualAnchorProp ?? contextVirtualAnchor)\n\n // Default side based on depth:\n // - Root menu (depth 0): bottom for dropdown, start for context\n // - Submenu (depth > 0): right\n const defaultSide = isSubmenu ? 'right' : 'bottom'\n const side = sideProp ?? defaultSide\n\n // Align defaults to start for submenus, center for root dropdown, start for context\n const defaultAlign = isSubmenu\n ? 'start'\n : menuType === 'context'\n ? 'start'\n : 'center'\n const align = alignProp ?? defaultAlign\n\n // Determine if list-start alignment should be used\n // Only for horizontal sides\n const useListStartAlign = align === 'list-start' && isHorizontalSide(side)\n\n // Map to Base UI align (list-start -> start)\n const baseUIAlign = align === 'list-start' ? 'start' : align\n\n // Get open state from submenu context\n const isOpen = submenuContext?.open ?? false\n\n // Track hideUntilActive activation to suppress its size-change repositioning.\n const inputActive = store.useState('inputActive')\n const hideUntilActive = store.context.hideUntilActive\n const prevInputActiveRef = React.useRef(inputActive)\n\n // Measurement function for list-start offset.\n // Returns true when the offset changed enough to require repositioning.\n const measureListStartOffset = React.useCallback(() => {\n if (!useListStartAlign) return false\n\n const contentEl = submenuContext?.contentRef.current\n if (!contentEl) return false\n\n const contentRect = contentEl.getBoundingClientRect()\n\n // Find the List component by role=\"listbox\"\n const listEl = contentEl.querySelector<HTMLElement>('[role=\"listbox\"]')\n if (!listEl) {\n const previousOffset = listStartOffsetRef.current\n listStartOffsetRef.current = 0\n return Math.abs(previousOffset) > LIST_START_OFFSET_EPSILON\n }\n\n const listRect = listEl.getBoundingClientRect()\n\n // Get the list's padding-top to align to content start\n const listStyles = getComputedStyle(listEl)\n const listPaddingTop = Number.parseFloat(listStyles.paddingTop) || 0\n\n // Calculate offset: negative distance from popup top to list content top\n const nextOffset = -(listRect.top + listPaddingTop - contentRect.top)\n const previousOffset = listStartOffsetRef.current\n\n listStartOffsetRef.current = nextOffset\n\n return Math.abs(nextOffset - previousOffset) > LIST_START_OFFSET_EPSILON\n }, [useListStartAlign, submenuContext])\n\n // Measure on open before paint.\n React.useLayoutEffect(() => {\n if (!useListStartAlign || !isOpen) {\n return\n }\n\n if (hasMeasuredRef.current) return\n\n // Measure synchronously - by this point, all children have rendered\n // and contentRef should be populated\n measureListStartOffset()\n hasMeasuredRef.current = true\n\n // Force a synchronous re-render to apply the measured offset\n // This happens within useLayoutEffect, so it completes before browser paint\n forceUpdate()\n }, [useListStartAlign, isOpen, measureListStartOffset])\n\n // Re-measure when popup content size changes while open.\n React.useLayoutEffect(() => {\n if (!useListStartAlign || !isOpen) {\n return\n }\n\n const contentEl = submenuContext?.contentRef.current\n if (!contentEl || typeof ResizeObserver === 'undefined') {\n return\n }\n\n const resizeObserver = new ResizeObserver(() => {\n if (suppressResizeMeasurementRef.current) {\n return\n }\n\n if (!measureListStartOffset()) {\n return\n }\n\n // Keep list-start alignment visually stable in the same frame as size changes.\n // Using flushSync here prevents a one-frame jump when content updates.\n flushSync(() => {\n forceUpdate()\n })\n })\n\n resizeObserver.observe(contentEl)\n\n const listEl = contentEl.querySelector<HTMLElement>('[role=\"listbox\"]')\n if (listEl) {\n resizeObserver.observe(listEl)\n }\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [useListStartAlign, isOpen, submenuContext, measureListStartOffset])\n\n // Suppress repositioning for hideUntilActive input activation only.\n React.useLayoutEffect(() => {\n const wasInputActive = prevInputActiveRef.current\n prevInputActiveRef.current = inputActive\n\n if (!useListStartAlign || !isOpen) {\n return\n }\n\n if (hideUntilActive && !wasInputActive && inputActive) {\n suppressResizeForInputActivation()\n }\n }, [\n useListStartAlign,\n isOpen,\n hideUntilActive,\n inputActive,\n suppressResizeForInputActivation,\n ])\n\n // Reset measurement state when menu closes.\n React.useEffect(() => {\n if (!isOpen) {\n hasMeasuredRef.current = false\n listStartOffsetRef.current = 0\n clearInputActivationSuppression()\n }\n }, [isOpen, clearInputActivationSuppression])\n\n React.useEffect(() => {\n return clearInputActivationSuppression\n }, [clearInputActivationSuppression])\n\n // Calculate effective alignOffset\n // User's alignOffset is additive to the calculated offset (only if it's a number)\n const effectiveAlignOffset = useListStartAlign\n ? listStartOffsetRef.current +\n (typeof alignOffsetProp === 'number' ? alignOffsetProp : 0)\n : alignOffsetProp\n\n // Default collision avoidance based on side:\n // - Horizontal (left/right): shift to avoid disorienting flip\n // - Vertical (top/bottom): flip (standard behavior)\n const collisionAvoidance =\n collisionAvoidanceProp ?? getDefaultCollisionAvoidance(side)\n\n // Only pass anchor if we have one - otherwise let Popover use its default (Trigger element)\n const anchorProps = virtualAnchor ? { anchor: virtualAnchor } : {}\n\n // Disable transitions during measurement to prevent visual flash.\n // When using list-start alignment, the first render positions at 'start',\n // then measurement occurs and we re-render with the correct offset.\n // By disabling transitions during this phase, both renders happen\n // synchronously without any visible movement.\n const isMeasuring = useListStartAlign && !hasMeasuredRef.current && isOpen\n const style: React.CSSProperties | undefined = isMeasuring\n ? { ...styleProp, transition: 'none' }\n : styleProp\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'positioner')\n\n return (\n <Popover.Positioner\n ref={ref}\n side={side}\n align={baseUIAlign}\n alignOffset={effectiveAlignOffset}\n collisionAvoidance={collisionAvoidance}\n style={style}\n {...(slotAttr ? { [slotAttr]: '' } : {})}\n // Override data-align to show 'list-start' when using list-start alignment\n data-align={useListStartAlign ? 'list-start' : undefined}\n {...anchorProps}\n {...rest}\n />\n )\n})\n\nexport namespace PopupMenuPositioner {\n export type Props = PopupMenuPositionerProps\n export type State = Popover.Positioner.State\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ListboxContextValue } from '../../listbox/contexts/listbox-context.js'\nimport { ListboxContext as ListboxContextProvider } from '../../listbox/contexts/listbox-context.js'\nimport type { ListboxStore, VirtualItem } from '../../listbox/index.js'\nimport {\n type ComponentName,\n ComponentNameContext,\n} from '../contexts/component-name-context.js'\nimport { FocusOwnerContext } from '../contexts/focus-owner-context.js'\nimport { OpenChainContext } from '../contexts/open-chain-context.js'\nimport {\n PopupMenuContext,\n type PopupMenuContextValue,\n type VirtualAnchor,\n type VirtualizationConfig,\n} from '../contexts/popup-menu-context.js'\nimport {\n PopupMenuDebugContext,\n type PopupMenuDebugContextValue,\n type PopupMenuDebugOptions,\n resolvePopupMenuSafeTriangleAreaDebugConfig,\n} from '../contexts/popup-menu-debug-context.js'\nimport type { GetQualifiedRowIdFn } from '../deep-search/types.js'\nimport { AimGuardProvider } from '../hooks/use-aim-guard.js'\nimport type { FocusOwnerStore } from '../store/FocusOwnerStore.js'\nimport type { OpenChainStore } from '../store/OpenChainStore.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PopupMenuProvidersProps {\n /** The Listbox store instance */\n store: ListboxStore\n /** The FocusOwner store instance */\n focusOwnerStore: FocusOwnerStore\n /** The OpenChain store instance */\n openChainStore: OpenChainStore\n /** Whether this menu tree currently ignores user interaction */\n disabled: boolean\n /** Nesting depth: 0 = root menu */\n depth: number\n /** Close the entire menu tree */\n closeAll: () => void\n /** Register a surface for closeAll tracking */\n registerSurface: (\n depth: number,\n setOpen: (open: boolean) => void,\n ) => () => void\n /** Virtualization configuration */\n virtualization?: VirtualizationConfig\n /** Debug visualization flags. */\n debug?: PopupMenuDebugOptions\n /**\n * Virtual anchor for positioning (used by ContextMenu).\n * DropdownMenu uses Popover's anchor (trigger button) instead.\n */\n virtualAnchor?: VirtualAnchor\n /**\n * Type of menu for positioning logic.\n * @default 'dropdown'\n */\n menuType?: 'dropdown' | 'context'\n /**\n * When to close the menu on outside interactions.\n * @default 'pointerdown'\n */\n closeOnOutsidePress?: 'click' | 'pointerdown'\n /**\n * Function to generate qualified unique IDs for rows.\n * Defined once at the root level and applied to all surfaces (root and submenus).\n */\n getQualifiedRowId?: GetQualifiedRowIdFn\n /**\n * Component name for generating bazzaui-* slot attributes.\n * E.g., 'dropdown-menu', 'context-menu', 'select', 'combobox'\n */\n componentName: ComponentName\n children: React.ReactNode\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Provides all shared context providers for popup menus.\n * Wraps children with:\n * - PopupMenuDebugContext (debug visualization flags)\n * - PopupMenuContext (menu-specific state)\n * - ListboxContextProvider (for compatibility with listbox components)\n * - AimGuardProvider (for submenu aim detection)\n * - FocusOwnerContext (for focus tracking across submenus)\n * - OpenChainContext (for tracking open submenu chain)\n */\nexport function PopupMenuProviders(props: PopupMenuProvidersProps) {\n const {\n store,\n focusOwnerStore,\n openChainStore,\n disabled,\n depth,\n closeAll,\n registerSurface,\n virtualization,\n debug,\n virtualAnchor,\n menuType = 'dropdown',\n closeOnOutsidePress = 'pointerdown',\n getQualifiedRowId,\n componentName,\n children,\n } = props\n\n // PopupMenu context value\n const popupMenuContextValue: PopupMenuContextValue = React.useMemo(\n () => ({\n store,\n disabled,\n depth,\n closeAll,\n registerSurface,\n virtualization,\n virtualAnchor,\n menuType,\n closeOnOutsidePress,\n getQualifiedRowId,\n }),\n [\n store,\n disabled,\n depth,\n closeAll,\n registerSurface,\n virtualization,\n virtualAnchor,\n menuType,\n closeOnOutsidePress,\n getQualifiedRowId,\n ],\n )\n\n // Listbox context value (for compatibility with dropdown-menu components)\n const listboxContextValue: ListboxContextValue = React.useMemo(\n () => ({\n store,\n depth,\n closeAll,\n registerSurface,\n virtualization,\n }),\n [store, depth, closeAll, registerSurface, virtualization],\n )\n\n const popupMenuDebugContextValue: PopupMenuDebugContextValue = React.useMemo(\n () => ({\n showSafeTriangleArea: resolvePopupMenuSafeTriangleAreaDebugConfig(\n debug?.showSafeTriangleArea,\n debug?.showSubmenuSafeTriangleArea,\n ),\n logAimGuardEvents: debug?.logAimGuardEvents ?? false,\n }),\n [\n debug?.showSafeTriangleArea,\n debug?.showSubmenuSafeTriangleArea,\n debug?.logAimGuardEvents,\n ],\n )\n\n return (\n <ComponentNameContext.Provider value={componentName}>\n <PopupMenuDebugContext.Provider value={popupMenuDebugContextValue}>\n <PopupMenuContext.Provider value={popupMenuContextValue}>\n <ListboxContextProvider.Provider value={listboxContextValue}>\n <AimGuardProvider>\n <FocusOwnerContext.Provider value={focusOwnerStore}>\n <OpenChainContext.Provider value={openChainStore}>\n {children}\n </OpenChainContext.Provider>\n </FocusOwnerContext.Provider>\n </AimGuardProvider>\n </ListboxContextProvider.Provider>\n </PopupMenuContext.Provider>\n </PopupMenuDebugContext.Provider>\n </ComponentNameContext.Provider>\n )\n}\n","'use client'\n\n// ============================================================================\n// usePopupMenuItem Hook - Wrapper around internal/listbox useListboxItem\n// ============================================================================\n// This wrapper adds aim-guard support and close-on-click behavior for popup menus\n\nimport * as React from 'react'\nimport {\n type UseListboxItemParams,\n type UseListboxItemReturn,\n useListboxContext,\n useListboxItem,\n} from '../../listbox/index.js'\nimport { useMaybePopupMenuContext } from '../contexts/popup-menu-context.js'\nimport { useAimGuard } from './use-aim-guard.js'\n\nexport interface UsePopupMenuItemParams\n extends Omit<UseListboxItemParams, 'aimGuard' | 'onAfterSelect'> {\n /**\n * Whether clicking this item should close the menu.\n * @default true\n */\n closeOnClick?: boolean\n}\n\nexport interface UsePopupMenuItemReturn extends UseListboxItemReturn {\n /** Whether this item is effectively disabled (item disabled OR menu disabled). */\n disabled: boolean\n}\n\n/**\n * Hook that provides all shared logic for navigatable/highlightable popup menu items.\n * This is a thin wrapper around useListboxItem that automatically adds aim-guard\n * support and handles close-on-click behavior.\n *\n * @see useListboxItem for full documentation\n */\nexport function usePopupMenuItem(\n params: UsePopupMenuItemParams,\n): UsePopupMenuItemReturn {\n const { closeOnClick = true, disabled = false, ...rest } = params\n const { aimGuardActiveRef, guardedDepthRef } = useAimGuard()\n const { closeAll } = useListboxContext()\n const popupMenuContext = useMaybePopupMenuContext()\n\n const menuDisabled = popupMenuContext?.disabled ?? false\n const effectiveDisabled = disabled || menuDisabled\n\n // Create aim guard refs object for the listbox hook\n const aimGuard = React.useMemo(\n () => ({\n aimGuardActiveRef,\n guardedDepthRef,\n }),\n [aimGuardActiveRef, guardedDepthRef],\n )\n\n // Handle after-select behavior (close menu if closeOnClick is true)\n const handleAfterSelect = React.useCallback(\n (itemId: string) => {\n if (closeOnClick) {\n closeAll()\n }\n },\n [closeOnClick, closeAll],\n )\n\n const item = useListboxItem({\n ...rest,\n disabled: effectiveDisabled,\n aimGuard,\n closeOnClick,\n onAfterSelect: handleAfterSelect,\n })\n\n return React.useMemo(\n () => ({\n ...item,\n disabled: effectiveDisabled,\n }),\n [item, effectiveDisabled],\n )\n}\n","'use client'\n\n// ============================================================================\n// usePopupMenuKeyboard Hook - Wrapper around internal/listbox useListboxKeyboard\n// ============================================================================\n// This wrapper integrates the focus owner and submenu contexts from popup-menu\n\nimport * as React from 'react'\nimport { type ListboxStore, useListboxKeyboard } from '../../listbox/index.js'\nimport type { SubmenuContextValue } from '../contexts/submenu-context.js'\nimport type { SubpageContextValue } from '../contexts/subpage-context.js'\nimport type { FocusOwnerStore } from '../store/FocusOwnerStore.js'\n\nexport interface UsePopupMenuKeyboardParams {\n /** The Listbox store instance */\n store: ListboxStore\n /** Unique identifier for this surface */\n surfaceId: string\n /** The FocusOwner store for managing focus ownership */\n focusOwnerStore: FocusOwnerStore\n /** Menu depth (0 for root, >0 for submenus) */\n depth: number\n /** Submenu context for ArrowLeft navigation back to parent */\n submenuContext: SubmenuContextValue | null\n /** Subpage context for back-stack navigation */\n subpageContext?: SubpageContextValue | null\n /** Whether keyboard handling is enabled */\n enabled: boolean\n /** Whether the menu currently ignores user interaction. */\n disabled?: boolean\n /**\n * Whether to enable type-to-search behavior.\n * When true, printable characters will activate the input and set pending search.\n * Used by List when hideUntilActive is enabled and input is not yet active.\n * @default false\n */\n enableTypeToSearch?: boolean\n /** User's onKeyDown handler to compose with */\n onKeyDown?: React.KeyboardEventHandler\n /**\n * Callback to close the entire menu tree from the root.\n * Used when Escape is pressed and closeRootOnEsc is true (default).\n */\n closeAll: () => void\n /**\n * Whether to skip the focus owner check.\n * When true, keyboard handling will work based on `enabled` prop alone,\n * ignoring focus ownership. Useful for Combobox where the input is outside\n * the Surface but should still handle keyboard navigation.\n * @default false\n */\n skipFocusOwnerCheck?: boolean\n}\n\nexport interface UsePopupMenuKeyboardReturn {\n /** Keyboard event handler to attach to the element */\n handleKeyDown: React.KeyboardEventHandler\n}\n\n/**\n * Centralized keyboard navigation hook for popup menus.\n * Handles arrow navigation, vim bindings, submenu open/close, and selection.\n */\nexport function usePopupMenuKeyboard(\n params: UsePopupMenuKeyboardParams,\n): UsePopupMenuKeyboardReturn {\n const {\n store,\n surfaceId,\n focusOwnerStore,\n depth,\n submenuContext,\n subpageContext = null,\n enabled,\n disabled = false,\n enableTypeToSearch = false,\n onKeyDown,\n closeAll,\n skipFocusOwnerCheck = false,\n } = params\n\n // Convert submenu context to the interface expected by the listbox hook\n const submenuInterface = React.useMemo(() => {\n if (!submenuContext) return null\n return {\n setOpen: submenuContext.setOpen,\n parentSurfaceId: submenuContext.parentSurfaceId,\n closeRootOnEsc: submenuContext.closeRootOnEsc,\n }\n }, [submenuContext])\n\n const subpageInterface = React.useMemo(() => {\n if (!subpageContext) return null\n return {\n goBack: subpageContext.goBack,\n parentSurfaceId: subpageContext.parentSurfaceId,\n closeRootOnEsc: subpageContext.closeRootOnEsc,\n }\n }, [subpageContext])\n\n // Handle selection via keyboard (Enter or shortcut)\n const handleSelect = React.useCallback(\n (details: { itemId: string | null; closeOnClick: boolean }) => {\n if (details.itemId && details.closeOnClick) {\n closeAll()\n }\n },\n [closeAll],\n )\n\n return useListboxKeyboard({\n store,\n surfaceId,\n enabled: enabled && !disabled,\n onKeyDown,\n onSelect: handleSelect,\n closeAll,\n focusOwner: focusOwnerStore,\n depth,\n submenuContext: submenuInterface,\n subpageContext: subpageInterface,\n enableTypeToSearch,\n skipFocusOwnerCheck,\n })\n}\n","export const PopupMenuIconDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-icon' | 'bazzaui-context-menu-icon' | 'bazzaui-select-icon' | 'bazzaui-combobox-icon'}\n */\n slot: 'bazzaui-[component]-icon',\n /** Present when the popup is open. */\n open: 'data-popup-open',\n} as const\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { useMaybeComboboxContext } from '../../../../combobox/contexts/combobox-context.js'\nimport {\n resolveLabel,\n stringifyAsValue,\n} from '../../../../utils/resolve-value-label.js'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { usePopupMenuContext } from '../../contexts/popup-menu-context.js'\nimport { PopupMenuIconDataAttributes } from './icon.data-attrs.js'\n\nexport { PopupMenuIconDataAttributes }\n\nexport interface PopupMenuIconState extends Record<string, unknown> {\n /**\n * Whether the popup is currently open.\n */\n open: boolean\n}\n\nexport interface PopupMenuIconProps\n extends ComponentProps<'span', PopupMenuIcon.State> {}\n\nconst stateAttributesMapping = {\n open: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuIconDataAttributes.open]: '' } : null,\n}\n\n/**\n * An icon that indicates the trigger opens a popup.\n * Typically used inside the trigger to show a chevron or dropdown arrow.\n * Renders a `<span>` element.\n */\nexport const PopupMenuIcon = React.forwardRef<\n HTMLSpanElement,\n PopupMenuIcon.Props\n>(function PopupMenuIcon(props, forwardedRef) {\n const {\n render,\n className,\n style,\n children,\n onPointerDown,\n onClick,\n ...rest\n } = props\n\n const { store } = usePopupMenuContext()\n const open = store.useState('open')\n\n // Check if inside a Combobox to apply special focus handling\n const comboboxContext = useMaybeComboboxContext()\n\n const state: PopupMenuIcon.State = React.useMemo(() => ({ open }), [open])\n\n // Prevent pointer down from stealing focus from the input (Combobox only)\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLSpanElement>) => {\n if (comboboxContext) {\n event.preventDefault()\n }\n onPointerDown?.(event)\n },\n [comboboxContext, onPointerDown],\n )\n\n // Handle click to toggle the combobox (Combobox only)\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLSpanElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n\n if (comboboxContext) {\n if (open) {\n comboboxContext.closeCombobox()\n } else {\n // Pre-set the input value BEFORE opening to avoid the empty intermediate state\n // This mirrors what the input click handler does\n const hasValue = comboboxContext.multiple\n ? comboboxContext.values.length > 0\n : comboboxContext.value != null\n\n if (hasValue && !comboboxContext.multiple) {\n // Serialize the value to a string key for registry lookup\n const valueKey = stringifyAsValue(\n comboboxContext.value,\n comboboxContext.itemToStringValue,\n )\n // Get the label from the registry or resolve from the value\n const registryText = comboboxContext.itemTextRegistry.get(valueKey)\n const labelValue =\n registryText ??\n resolveLabel(\n comboboxContext.value,\n comboboxContext.itemToStringLabel,\n )\n comboboxContext.onInputValueChange(labelValue)\n }\n\n comboboxContext.openCombobox()\n }\n }\n },\n [onClick, comboboxContext, open],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'icon')\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n className,\n style,\n children,\n onPointerDown: handlePointerDown,\n onClick: handleClick,\n },\n defaultTagName: 'span',\n })\n})\n\nexport namespace PopupMenuIcon {\n export type State = PopupMenuIconState\n export interface Props extends PopupMenuIconProps {}\n}\n","/**\n * Resolve a display label from an object value.\n * Auto-detects { label } shape if no custom function is provided.\n *\n * @param value - The value to convert to a label\n * @param itemToStringLabel - Optional custom function to extract the label\n * @returns The string label for display\n */\nexport function resolveLabel<Value>(\n value: Value,\n itemToStringLabel?: (value: Value) => string,\n): string {\n if (value == null) return ''\n if (itemToStringLabel) return itemToStringLabel(value)\n\n // Auto-detect { label } shape\n if (typeof value === 'object' && 'label' in value) {\n const label = (value as Record<string, unknown>).label\n if (typeof label === 'string') return label\n }\n\n return String(value)\n}\n\n/**\n * Serialize an object value for form submission.\n * Auto-detects { value } shape if no custom function is provided.\n *\n * @param value - The value to serialize\n * @param itemToStringValue - Optional custom function to serialize the value\n * @returns The string value for form submission\n */\nexport function stringifyAsValue<Value>(\n value: Value,\n itemToStringValue?: (value: Value) => string,\n): string {\n if (value == null) return ''\n if (itemToStringValue) return itemToStringValue(value)\n\n // Auto-detect { value } shape\n if (typeof value === 'object' && 'value' in value) {\n return String((value as Record<string, unknown>).value)\n }\n\n return String(value)\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { useSurfaceContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useMaybeAsyncMenuCoordinator } from '../../deep-search/async-coordinator.js'\n\n// Empty doesn't have any state - using an empty object type\nexport interface PopupMenuEmptyState extends Record<string, unknown> {}\n\nexport interface PopupMenuEmptyProps\n extends ComponentProps<'div', PopupMenuEmpty.State> {\n children: React.ReactNode\n}\n\n/**\n * Renders when no items match the current search query.\n * Only visible when there's an active search with zero results.\n * Renders a `<div>` element.\n */\nexport const PopupMenuEmpty = React.forwardRef<\n HTMLDivElement,\n PopupMenuEmpty.Props\n>(function PopupMenuEmpty(props, forwardedRef) {\n const { render, className, style, children, ...rest } = props\n\n const { store } = useSurfaceContext()\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'empty')\n\n const element = useRender({\n render,\n ref: forwardedRef,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n role: 'presentation',\n className,\n style,\n children,\n },\n defaultTagName: 'div',\n })\n\n // Don't show empty state while async loaders are still in initial loading.\n // Same logic as Loading: suppress when __root__ is initially loading OR when\n // any loader is initially loading during an active search.\n const asyncCoordinator = useMaybeAsyncMenuCoordinator()\n const isLoading = asyncCoordinator\n ? asyncCoordinator.isRootLoading ||\n (asyncCoordinator.isAnyLoading && asyncCoordinator.searchQuery.length > 0)\n : false\n\n // Use dedicated selector for this check\n const hasNoResults = store.useState('hasSearchWithNoResults')\n const shouldRender = !isLoading && hasNoResults\n\n if (!shouldRender) {\n return null\n }\n\n return element\n})\n\nexport namespace PopupMenuEmpty {\n export type State = PopupMenuEmptyState\n export interface Props extends PopupMenuEmptyProps {}\n}\n","'use client'\n\nimport * as React from 'react'\nimport type {\n AsyncLoaderConfig,\n AsyncLoaderResult,\n AsyncState,\n NodeDef,\n} from './types.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * State for a registered async loader.\n */\nexport interface AsyncMenuState {\n /** Unique identifier for this async menu */\n id: string\n /** Breadcrumbs path to this menu (for merging into tree) */\n breadcrumbs: string[]\n /** The loader configuration */\n config: AsyncLoaderConfig\n /** Current loader result */\n result: AsyncLoaderResult<NodeDef[]>\n}\n\n/**\n * Context value for the async menu coordinator.\n */\nexport interface AsyncMenuCoordinatorValue {\n // ---- Registration ----\n /** Register a new async loader */\n registerLoader: (state: AsyncMenuState) => void\n /** Unregister an async loader */\n unregisterLoader: (id: string) => void\n /** Update loader result */\n updateLoaderResult: (id: string, result: AsyncLoaderResult<NodeDef[]>) => void\n\n // ---- Search Query ----\n /** Current search query from the store */\n searchQuery: string\n\n // ---- Loader State ----\n /** All registered loaders */\n loaders: Map<string, AsyncMenuState>\n\n // ---- Computed State ----\n /** Any loader is currently in initial loading phase */\n isAnyLoading: boolean\n /** Any loader is currently fetching (initial or background) */\n isAnyFetching: boolean\n /** Any loader is currently in first-load phase */\n isAnyInitialLoading: boolean\n /** Any loader is currently in background refetch phase */\n isAnyRefetching: boolean\n /** All registered loaders are currently in background refetch phase */\n isAllRefetching: boolean\n /** The root (__root__) loader is currently in initial loading phase */\n isRootLoading: boolean\n /** Static loaders are currently in initial loading phase */\n isStaticLoading: boolean\n /** Static loaders are currently fetching */\n isStaticFetching: boolean\n /** Static loaders in first-load phase */\n isStaticInitialLoading: boolean\n /** Static loaders in background refetch phase */\n isStaticRefetching: boolean\n /** Query loaders are currently in initial loading phase */\n isQueryLoading: boolean\n /** Query loaders are currently fetching */\n isQueryFetching: boolean\n /** Query loaders in first-load phase */\n isQueryInitialLoading: boolean\n /** Query loaders in background refetch phase */\n isQueryRefetching: boolean\n /** All loaders have resolved (not fetching) */\n allResolved: boolean\n\n // ---- Async Nodes ----\n /** Get all resolved async nodes with their breadcrumbs */\n getAsyncNodes: () => Array<{\n id: string\n breadcrumbs: string[]\n nodes: NodeDef[]\n }>\n\n // ---- Error Tracking ----\n /** Loaders that errored */\n erroredLoaders: Map<string, Error>\n\n // ---- Aggregated State ----\n /** Get the aggregate async state for DataList */\n getAsyncState: () => AsyncState\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nexport const AsyncMenuCoordinatorContext =\n React.createContext<AsyncMenuCoordinatorValue | null>(null)\n\nexport function useAsyncMenuCoordinator(): AsyncMenuCoordinatorValue | null {\n return React.useContext(AsyncMenuCoordinatorContext)\n}\n\nexport function useMaybeAsyncMenuCoordinator(): AsyncMenuCoordinatorValue | null {\n return React.useContext(AsyncMenuCoordinatorContext)\n}\n\n// ============================================================================\n// Provider Props\n// ============================================================================\n\nexport interface AsyncMenuCoordinatorProviderProps {\n /** Children to render */\n children: React.ReactNode\n /** Current search query from the store */\n searchQuery: string\n}\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\nexport function AsyncMenuCoordinatorProvider(\n props: AsyncMenuCoordinatorProviderProps,\n) {\n const { children, searchQuery } = props\n\n // Registered loaders\n const [loaders, setLoaders] = React.useState<Map<string, AsyncMenuState>>(\n () => new Map(),\n )\n\n // Track errored loaders\n const [erroredLoaders, setErroredLoaders] = React.useState<\n Map<string, Error>\n >(() => new Map())\n\n // Register a loader\n const registerLoader = React.useCallback((state: AsyncMenuState) => {\n setLoaders((prev) => {\n const next = new Map(prev)\n next.set(state.id, state)\n return next\n })\n }, [])\n\n // Unregister a loader\n const unregisterLoader = React.useCallback((id: string) => {\n setLoaders((prev) => {\n const next = new Map(prev)\n next.delete(id)\n return next\n })\n\n // Clear error state\n setErroredLoaders((prev) => {\n const next = new Map(prev)\n next.delete(id)\n return next\n })\n }, [])\n\n // Update loader result\n const updateLoaderResult = React.useCallback(\n (id: string, result: AsyncLoaderResult<NodeDef[]>) => {\n setLoaders((prev) => {\n const existing = prev.get(id)\n if (!existing) return prev\n\n const next = new Map(prev)\n next.set(id, { ...existing, result })\n return next\n })\n\n // Track errors\n if (result.isError && result.error) {\n setErroredLoaders((prev) => {\n const next = new Map(prev)\n next.set(id, result.error!)\n return next\n })\n } else if (!result.isError) {\n setErroredLoaders((prev) => {\n if (!prev.has(id)) return prev\n const next = new Map(prev)\n next.delete(id)\n return next\n })\n }\n },\n [],\n )\n\n // Computed loading states\n const isStaticFetching = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'static' && state.result.isFetching) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isStaticLoading = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'static' && state.result.isLoading) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isStaticInitialLoading = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'static' && state.result.isInitialLoading) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isStaticRefetching = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'static' && state.result.isRefetching) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isQueryFetching = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'query' && state.result.isFetching) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isQueryLoading = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'query' && state.result.isLoading) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isQueryInitialLoading = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'query' && state.result.isInitialLoading) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isQueryRefetching = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.config.type === 'query' && state.result.isRefetching) {\n return true\n }\n }\n return false\n }, [loaders])\n\n const isAnyFetching = isStaticFetching || isQueryFetching\n const isAnyLoading = isStaticLoading || isQueryLoading\n const isAnyInitialLoading = isStaticInitialLoading || isQueryInitialLoading\n const isAnyRefetching = isStaticRefetching || isQueryRefetching\n const isAllRefetching = React.useMemo(() => {\n if (loaders.size === 0) {\n return false\n }\n\n for (const [, state] of loaders) {\n if (!state.result.isRefetching) {\n return false\n }\n }\n\n return true\n }, [loaders])\n\n // Only the root loader (__root__) — i.e. the DataSurface's own asyncContent.\n // Child submenu loaders are not included; they show loading on their own triggers.\n const isRootLoading = React.useMemo(() => {\n const rootLoader = loaders.get('__root__')\n return rootLoader?.result.isLoading ?? false\n }, [loaders])\n\n const allResolved = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.result.isFetching) {\n return false\n }\n }\n return true\n }, [loaders])\n\n // Get all resolved async nodes\n const getAsyncNodes = React.useCallback(() => {\n const result: Array<{\n id: string\n breadcrumbs: string[]\n nodes: NodeDef[]\n }> = []\n\n for (const [id, state] of loaders) {\n // Skip errored loaders\n if (erroredLoaders.has(id)) {\n continue\n }\n\n // Add resolved data\n if (state.result.data) {\n result.push({\n id,\n breadcrumbs: state.breadcrumbs,\n nodes: state.result.data,\n })\n }\n }\n\n return result\n }, [loaders, erroredLoaders])\n\n // Get aggregate async state\n const getAsyncState = React.useCallback((): AsyncState => {\n const skippedMenus: Array<{ id: string; reason: 'error' }> = []\n\n for (const [id] of erroredLoaders) {\n skippedMenus.push({ id, reason: 'error' })\n }\n\n return {\n isLoading: isAnyLoading,\n isFetching: isAnyFetching,\n isInitialLoading: isAnyInitialLoading,\n isRefetching: isAnyRefetching,\n isAllRefetching,\n isStaticLoading,\n isStaticInitialLoading,\n isStaticRefetching,\n isQueryLoading,\n isQueryInitialLoading,\n isQueryRefetching,\n skippedMenus,\n }\n }, [\n isAnyFetching,\n isAnyLoading,\n isAnyInitialLoading,\n isAnyRefetching,\n isAllRefetching,\n isStaticLoading,\n isStaticInitialLoading,\n isStaticRefetching,\n isQueryLoading,\n isQueryInitialLoading,\n isQueryRefetching,\n erroredLoaders,\n ])\n\n // Context value\n const contextValue: AsyncMenuCoordinatorValue = React.useMemo(\n () => ({\n registerLoader,\n unregisterLoader,\n updateLoaderResult,\n searchQuery,\n loaders,\n isAnyLoading,\n isAnyFetching,\n isAnyInitialLoading,\n isAnyRefetching,\n isAllRefetching,\n isRootLoading,\n isStaticLoading,\n isStaticFetching,\n isStaticInitialLoading,\n isStaticRefetching,\n isQueryLoading,\n isQueryFetching,\n isQueryInitialLoading,\n isQueryRefetching,\n allResolved,\n getAsyncNodes,\n erroredLoaders,\n getAsyncState,\n }),\n [\n registerLoader,\n unregisterLoader,\n updateLoaderResult,\n searchQuery,\n loaders,\n isAnyLoading,\n isAnyFetching,\n isAnyInitialLoading,\n isAnyRefetching,\n isAllRefetching,\n isRootLoading,\n isStaticLoading,\n isStaticFetching,\n isStaticInitialLoading,\n isStaticRefetching,\n isQueryLoading,\n isQueryFetching,\n isQueryInitialLoading,\n isQueryRefetching,\n allResolved,\n getAsyncNodes,\n erroredLoaders,\n getAsyncState,\n ],\n )\n\n return (\n <AsyncMenuCoordinatorContext.Provider value={contextValue}>\n {children}\n </AsyncMenuCoordinatorContext.Provider>\n )\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { useListboxContext, useSurfaceContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { usePopupMenuContext } from '../../contexts/popup-menu-context.js'\nimport { useMaybeSubmenuContext } from '../../contexts/submenu-context.js'\nimport { useMaybeSubpageContext } from '../../contexts/subpage-context.js'\nimport { usePopupMenuKeyboard } from '../../hooks/use-popup-menu-keyboard.js'\n\nexport interface PopupMenuInputState extends Record<string, unknown> {\n /**\n * Whether the input is active (visible).\n * Only relevant when `hideUntilActive` is true.\n */\n active: boolean\n}\n\nexport interface PopupMenuInputProps\n extends Omit<\n ComponentProps<'input', PopupMenuInput.State>,\n 'value' | 'onChange' | 'type'\n > {\n /**\n * Controlled value for the search input.\n * If provided, this takes precedence over the Surface's search state.\n */\n value?: string\n\n /**\n * Callback when the input value changes.\n */\n onValueChange?: (value: string) => void\n\n /**\n * When true, the input is not rendered until the user starts typing.\n * The List receives focus initially, and typing a character activates the input.\n * Once activated, the input stays visible until the menu closes.\n * @default false\n */\n hideUntilActive?: boolean\n}\n\n/**\n * Search input for filtering popup menu items.\n * Handles keyboard navigation (Arrow keys, Ctrl+N/P, Enter).\n * Renders an `<input>` element.\n */\nexport const PopupMenuInput = React.forwardRef<\n HTMLInputElement,\n PopupMenuInput.Props\n>(function PopupMenuInput(props, forwardedRef) {\n const {\n value: controlledValue,\n onValueChange,\n hideUntilActive = false,\n disabled: disabledProp = false,\n render,\n className,\n style,\n onKeyDown,\n ...rest\n } = props\n\n const { store, surfaceId } = useSurfaceContext()\n const { depth, closeAll } = useListboxContext()\n const submenuContext = useMaybeSubmenuContext()\n const subpageContext = useMaybeSubpageContext()\n const { disabled: popupMenuDisabled } = usePopupMenuContext()\n const disabled = popupMenuDisabled || disabledProp\n const focusOwnerStore = useFocusOwner()\n const internalRef = React.useRef<HTMLInputElement>(null)\n\n // Get values from store\n const search = store.useState('search')\n const highlightedId = store.useState('highlightedId')\n const listId = store.context.listId\n const inputId = store.context.inputId\n\n // Register hideUntilActive mode\n React.useEffect(() => {\n store.setHideUntilActive(hideUntilActive)\n return () => store.setHideUntilActive(false)\n }, [store, hideUntilActive])\n\n // Subscribe to inputActive and pendingSearch state\n const inputActive = store.useState('inputActive')\n const pendingSearch = store.useState('pendingSearch')\n\n // Determine if we should render\n const shouldRender = !hideUntilActive || inputActive\n\n // Register that an Input is present - ONLY when actually rendering\n // This ensures List handles keyboard when Input is hidden\n React.useEffect(() => {\n if (!shouldRender) {\n return // Don't register when hidden\n }\n store.setHasInput(true)\n return () => store.setHasInput(false)\n }, [store, shouldRender])\n\n // Determine the actual value (controlled input prop > controlled surface > uncontrolled)\n const isInputControlled = controlledValue !== undefined\n const displayValue = isInputControlled ? controlledValue : search\n\n // Consume pending search on activation\n React.useEffect(() => {\n if (pendingSearch && internalRef.current) {\n // Always sync to store for filtering/highlighting, even in controlled mode\n store.setSearch(pendingSearch)\n onValueChange?.(pendingSearch)\n // Clear pending search\n store.setPendingSearch('')\n // Focus the input\n internalRef.current.focus()\n }\n }, [pendingSearch, store, onValueChange])\n\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = event.target.value\n\n // Always sync to store for filtering/highlighting, even in controlled mode\n store.setSearch(newValue)\n onValueChange?.(newValue)\n },\n [onValueChange, store],\n )\n\n // Use centralized keyboard navigation hook\n const { handleKeyDown } = usePopupMenuKeyboard({\n store,\n surfaceId,\n focusOwnerStore,\n depth,\n submenuContext,\n subpageContext,\n enabled: true,\n disabled,\n enableTypeToSearch: false,\n onKeyDown,\n closeAll,\n })\n\n const state: PopupMenuInput.State = React.useMemo(\n () => ({\n active: inputActive,\n }),\n [inputActive],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'input')\n\n const element = useRender({\n render,\n ref: [internalRef, forwardedRef],\n state,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: inputId,\n type: 'text',\n role: 'combobox',\n 'aria-autocomplete': 'list',\n 'aria-expanded': true,\n 'aria-controls': listId,\n 'aria-activedescendant': highlightedId ?? undefined,\n autoComplete: 'off',\n autoCorrect: 'off',\n spellCheck: false,\n disabled,\n className,\n style,\n value: displayValue,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n },\n defaultTagName: 'input',\n })\n\n // Don't render if hideUntilActive is enabled and not yet active\n if (!shouldRender) {\n return null\n }\n\n return element\n})\n\nexport namespace PopupMenuInput {\n export type State = PopupMenuInputState\n export interface Props extends PopupMenuInputProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { useMaybeComboboxContext } from '../../../../combobox/contexts/combobox-context.js'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n RowWidthContext,\n useListboxContext,\n useStickyRowWidth,\n useSurfaceContext,\n} from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { usePopupMenuContext } from '../../contexts/popup-menu-context.js'\nimport { useMaybeSubmenuContext } from '../../contexts/submenu-context.js'\nimport { useMaybeSubpageContext } from '../../contexts/subpage-context.js'\nimport { usePopupMenuKeyboard } from '../../hooks/use-popup-menu-keyboard.js'\nimport { PopupMenuListCssVars } from './list.css-vars.js'\nimport { PopupMenuListDataAttributes } from './list.data-attrs.js'\n\nexport { PopupMenuListCssVars, PopupMenuListDataAttributes }\n\n/**\n * State passed to children render function.\n */\nexport interface PopupMenuListChildrenState {\n /** Current search query */\n search: string\n /** Number of items matching the current filter */\n filteredCount: number\n}\n\n// List doesn't expose data attributes - using empty state\nexport interface PopupMenuListState extends Record<string, unknown> {}\n\nexport interface PopupMenuListProps\n extends Omit<ComponentProps<'div', PopupMenuList.State>, 'children'> {\n /**\n * Content to render inside the list.\n * Can be a render function that receives the current search state.\n */\n children:\n | React.ReactNode\n | ((state: PopupMenuListChildrenState) => React.ReactNode)\n\n /**\n * Accessible label for the listbox.\n * @default 'Suggestions'\n */\n label?: string\n\n /**\n * When true, measures row widths and applies `--row-width` CSS variable.\n * Keeps the list at the maximum width seen while scrolling.\n * Useful for virtualized lists where content width varies.\n * @default true\n */\n measureRowWidth?: boolean\n\n /**\n * Maximum width cap for row measurement (in pixels).\n * Only used when `measureRowWidth` is true.\n */\n maxRowWidth?: number\n}\n\n/**\n * Container for popup menu items.\n * Supports render props for accessing search state.\n * Renders a `<div>` element with role=\"listbox\".\n */\nexport const PopupMenuList = React.forwardRef<\n HTMLDivElement,\n PopupMenuList.Props\n>(function PopupMenuList(props, forwardedRef) {\n const {\n children,\n label = 'Suggestions',\n measureRowWidth = true,\n maxRowWidth,\n render,\n className,\n style,\n onKeyDown,\n onPointerDown,\n ...rest\n } = props\n\n const { store, surfaceId } = useSurfaceContext()\n const { depth, closeAll } = useListboxContext()\n const submenuContext = useMaybeSubmenuContext()\n const subpageContext = useMaybeSubpageContext()\n const { disabled: popupMenuDisabled } = usePopupMenuContext()\n const focusOwnerStore = useFocusOwner()\n const comboboxContext = useMaybeComboboxContext()\n const internalRef = React.useRef<HTMLDivElement>(null)\n\n // Ref to the popup element (found via closest) for applying --row-width CSS var\n const popupRef = React.useRef<HTMLElement | null>(null)\n\n // Register list ref with store for scroll behavior\n React.useEffect(() => {\n store.setListRef(internalRef)\n }, [store])\n\n // Find popup element on mount for row width measurement target\n React.useLayoutEffect(() => {\n if (!measureRowWidth || !internalRef.current) return\n // Find the closest popup element (Base UI's Popover.Popup adds data-open)\n const popup = internalRef.current.closest(\n '[data-open]',\n ) as HTMLElement | null\n popupRef.current = popup\n }, [measureRowWidth])\n\n // Row width measurement - apply CSS var to popup instead of list\n const { queueMeasurement, resetMeasurements } = useStickyRowWidth({\n listRef: internalRef,\n targetRef: popupRef,\n maxWidth: maxRowWidth,\n enabled: measureRowWidth,\n })\n\n // Register resetMeasurements callback with store for close completion\n React.useEffect(() => {\n if (measureRowWidth) {\n store.context.onCloseComplete = resetMeasurements\n return () => {\n store.context.onCloseComplete = undefined\n }\n }\n }, [measureRowWidth, resetMeasurements, store])\n\n // Row width context value\n const rowWidthContextValue = React.useMemo(\n () => (measureRowWidth ? { queueMeasurement } : null),\n [measureRowWidth, queueMeasurement],\n )\n\n // Get values from store\n const search = store.useState('search')\n const filteredCount = store.useState('filteredCount')\n const hasInput = store.useState('hasInput')\n const highlightedId = store.useState('highlightedId')\n const listId = store.context.listId\n\n // When there's no Input, the List should receive focus and handle keyboard nav\n // Note: Auto-focus is handled by Surface when it becomes the focus owner\n const shouldHandleKeyboard = !hasInput && !popupMenuDisabled\n\n // Use centralized keyboard navigation hook\n const { handleKeyDown } = usePopupMenuKeyboard({\n store,\n surfaceId,\n focusOwnerStore,\n depth,\n submenuContext,\n subpageContext,\n enabled: shouldHandleKeyboard,\n disabled: popupMenuDisabled,\n enableTypeToSearch: true,\n onKeyDown,\n closeAll,\n })\n\n // Prevent pointer down from stealing focus from Input\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault()\n onPointerDown?.(event)\n },\n [onPointerDown],\n )\n\n const childrenState: PopupMenuList.ChildrenState = React.useMemo(\n () => ({\n search,\n filteredCount,\n }),\n [search, filteredCount],\n )\n\n const renderedChildren =\n typeof children === 'function' ? children(childrenState) : children\n\n // Wrap children with RowWidthContext if measurement is enabled\n const wrappedChildren = rowWidthContextValue ? (\n <RowWidthContext.Provider value={rowWidthContextValue}>\n {renderedChildren}\n </RowWidthContext.Provider>\n ) : (\n renderedChildren\n )\n\n // Add data-input-embedded attribute when layout is input-embedded\n const isInputEmbedded = comboboxContext?.layout === 'input-embedded'\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'list')\n\n return useRender({\n render,\n ref: [internalRef, forwardedRef],\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: listId,\n role: 'listbox',\n 'aria-label': label,\n 'aria-activedescendant': shouldHandleKeyboard\n ? (highlightedId ?? undefined)\n : undefined,\n tabIndex: shouldHandleKeyboard ? 0 : -1,\n [PopupMenuListDataAttributes.list]: '',\n 'data-input-embedded': isInputEmbedded ? '' : undefined,\n className,\n style,\n onKeyDown: handleKeyDown,\n onPointerDown: handlePointerDown,\n children: wrappedChildren,\n },\n defaultTagName: 'div',\n })\n})\n\nexport namespace PopupMenuList {\n export type State = PopupMenuListState\n export type ChildrenState = PopupMenuListChildrenState\n export interface Props extends PopupMenuListProps {}\n}\n","/**\n * CSS custom properties applied to the List component.\n */\nexport enum PopupMenuListCssVars {\n /**\n * The maximum measured row width.\n * Applied when `measureRowWidth` is true.\n * Useful for keeping virtualized lists at a consistent width.\n * @type {number}\n */\n rowWidth = '--row-width',\n}\n","export enum PopupMenuListDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-list' | 'bazzaui-context-menu-list' | 'bazzaui-select-list' | 'bazzaui-combobox-list'}\n */\n slot = 'bazzaui-[component]-list',\n /**\n * Always present on the list element.\n * Used for styling and by useStickyRowWidth to find the list container.\n */\n list = 'data-popup-menu-list',\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useMaybeAsyncMenuCoordinator } from '../../deep-search/async-coordinator.js'\n\n// Loading doesn't have any state - using an empty object type\nexport interface PopupMenuLoadingState extends Record<string, unknown> {}\n\nexport interface PopupMenuLoadingProps\n extends ComponentProps<'div', PopupMenuLoading.State> {\n children: React.ReactNode\n\n /**\n * Whether to force render the loading indicator regardless of async loading state.\n * When true, the component always renders, allowing you to control visibility externally.\n * @default false\n */\n forceMount?: boolean\n}\n\n/**\n * Renders when async content is in initial loading.\n * Only visible during first-load phases (unless `forceMount` is true).\n * Renders a `<div>` element.\n */\nexport const PopupMenuLoading = React.forwardRef<\n HTMLDivElement,\n PopupMenuLoading.Props\n>(function PopupMenuLoading(props, forwardedRef) {\n const {\n forceMount = false,\n render,\n className,\n style,\n children,\n ...rest\n } = props\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'loading')\n\n const element = useRender({\n render,\n ref: forwardedRef,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n role: 'presentation',\n className,\n style,\n children,\n },\n defaultTagName: 'div',\n })\n\n // Check async loading state.\n // Two cases where we show the loading indicator:\n // 1. The __root__ loader (DataSurface's own asyncContent) is loading\n // 2. ANY loader is in initial loading AND the user has typed a search query\n //\n // Case 2 distinguishes between:\n // - Root menu deep search (\"se\") → user is waiting for results → show spinner\n // - Submenu opened with minLength=0 → just preloading child loaders → no spinner (Bug #6)\n const asyncCoordinator = useMaybeAsyncMenuCoordinator()\n const isLoading = asyncCoordinator\n ? asyncCoordinator.isRootLoading ||\n (asyncCoordinator.isAnyLoading && asyncCoordinator.searchQuery.length > 0)\n : false\n const shouldRender = forceMount || isLoading\n\n if (!shouldRender) {\n return null\n }\n\n return element\n})\n\nexport namespace PopupMenuLoading {\n export type State = PopupMenuLoadingState\n export interface Props extends PopupMenuLoadingProps {}\n}\n","export const PopupMenuScrollArrowDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-scroll-up-arrow' | 'bazzaui-dropdown-menu-scroll-down-arrow' | 'bazzaui-context-menu-scroll-up-arrow' | 'bazzaui-context-menu-scroll-down-arrow' | 'bazzaui-select-scroll-up-arrow' | 'bazzaui-select-scroll-down-arrow' | 'bazzaui-combobox-scroll-up-arrow' | 'bazzaui-combobox-scroll-down-arrow'}\n */\n slot: 'bazzaui-[component]-scroll-[up|down]-arrow',\n /** @type {'up' | 'down'} */\n direction: 'data-direction',\n /** @type {'top' | 'bottom' | 'left' | 'right'} */\n side: 'data-side',\n} as const\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { useSurfaceContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { PopupMenuScrollArrowDataAttributes } from './scroll-arrow.data-attrs.js'\n\nexport { PopupMenuScrollArrowDataAttributes }\n\ntype Direction = 'up' | 'down'\n\nexport interface PopupMenuScrollArrowState extends Record<string, unknown> {\n /**\n * The scroll direction this arrow controls.\n */\n direction: Direction\n /**\n * Whether there is content to scroll in this direction.\n */\n visible: boolean\n}\n\nexport interface PopupMenuScrollArrowProps\n extends ComponentProps<'div', PopupMenuScrollArrow.State> {\n /**\n * The direction to scroll when hovering over this arrow.\n */\n direction: Direction\n /**\n * Whether to keep the element mounted when there's nothing to scroll.\n * When false (default), the element is not rendered.\n * When true, the element is rendered but can be styled via `data-visible=\"false\"`.\n * @default false\n */\n keepMounted?: boolean\n /**\n * Scroll speed in pixels per frame.\n * @default 10\n */\n scrollSpeed?: number\n}\n\nconst stateAttributesMapping = {\n direction: (value: unknown): Record<string, string> | null =>\n value\n ? { [PopupMenuScrollArrowDataAttributes.direction]: String(value) }\n : null,\n visible: (value: unknown): Record<string, string> | null => ({\n 'data-visible': value ? 'true' : 'false',\n }),\n}\n\n/**\n * Base scroll arrow component used by ScrollUpArrow and ScrollDownArrow.\n * Shows when there is content to scroll in the specified direction.\n * Scrolls the list continuously while pointer is over it.\n * Renders a `<div>` element.\n */\nexport const PopupMenuScrollArrow = React.forwardRef<\n HTMLDivElement,\n PopupMenuScrollArrow.Props\n>(function PopupMenuScrollArrow(props, forwardedRef) {\n const {\n direction,\n keepMounted = false,\n scrollSpeed = 10,\n render,\n className,\n style,\n children,\n ...rest\n } = props\n\n const { store } = useSurfaceContext()\n const [visible, setVisible] = React.useState(false)\n const scrollingRef = React.useRef(false)\n const rafRef = React.useRef<number | null>(null)\n\n // Check if there's content to scroll in this direction\n const checkVisibility = React.useCallback(() => {\n const listRef = store.context.refs.listRef\n const list = listRef?.current\n if (!list) {\n setVisible(false)\n return\n }\n\n if (direction === 'up') {\n // Visible when not at top\n setVisible(list.scrollTop > 0)\n } else {\n // Visible when not at bottom\n const atBottom =\n list.scrollTop + list.clientHeight >= list.scrollHeight - 1\n setVisible(!atBottom)\n }\n }, [store, direction])\n\n // Set up scroll listener on the list\n React.useEffect(() => {\n const listRef = store.context.refs.listRef\n const list = listRef?.current\n if (!list) return\n\n // Initial check\n checkVisibility()\n\n // Listen for scroll events\n list.addEventListener('scroll', checkVisibility, { passive: true })\n\n // Also check on resize (content might change)\n const resizeObserver = new ResizeObserver(checkVisibility)\n resizeObserver.observe(list)\n\n return () => {\n list.removeEventListener('scroll', checkVisibility)\n resizeObserver.disconnect()\n }\n }, [store, checkVisibility])\n\n // Also recheck when items change (filteredCount changes)\n const filteredCount = store.useState('filteredCount')\n React.useEffect(() => {\n // Delay to allow DOM to update\n requestAnimationFrame(checkVisibility)\n }, [filteredCount, checkVisibility])\n\n // Continuous scrolling while pointer is over\n const startScrolling = React.useCallback(() => {\n scrollingRef.current = true\n\n const scroll = () => {\n if (!scrollingRef.current) return\n\n const listRef = store.context.refs.listRef\n const list = listRef?.current\n if (list) {\n const delta = direction === 'up' ? -scrollSpeed : scrollSpeed\n list.scrollTop += delta\n }\n\n rafRef.current = requestAnimationFrame(scroll)\n }\n\n rafRef.current = requestAnimationFrame(scroll)\n }, [store, direction, scrollSpeed])\n\n const stopScrolling = React.useCallback(() => {\n scrollingRef.current = false\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n }, [])\n\n // Clean up on unmount\n React.useEffect(() => {\n return () => {\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current)\n }\n }\n }, [])\n\n const state: PopupMenuScrollArrow.State = React.useMemo(\n () => ({ direction, visible }),\n [direction, visible],\n )\n\n // Determine if we should render\n const shouldRender = visible || keepMounted\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(\n componentName,\n direction === 'up' ? 'scroll-up-arrow' : 'scroll-down-arrow',\n )\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n className,\n style,\n onPointerEnter: (event: React.PointerEvent<HTMLDivElement>) => {\n startScrolling()\n rest.onPointerEnter?.(event)\n },\n onPointerLeave: (event: React.PointerEvent<HTMLDivElement>) => {\n stopScrolling()\n rest.onPointerLeave?.(event)\n },\n children,\n },\n defaultTagName: 'div',\n enabled: shouldRender,\n })\n})\n\nexport namespace PopupMenuScrollArrow {\n export type State = PopupMenuScrollArrowState\n export interface Props extends PopupMenuScrollArrowProps {}\n}\n\n// ============================================================================\n// Convenience Components\n// ============================================================================\n\nexport interface PopupMenuScrollUpArrowProps\n extends Omit<PopupMenuScrollArrowProps, 'direction'> {}\n\n/**\n * A scroll indicator that appears when there's content above.\n * Scrolls the list up continuously while pointer is over it.\n * Renders a `<div>` element.\n */\nexport const PopupMenuScrollUpArrow = React.forwardRef<\n HTMLDivElement,\n PopupMenuScrollUpArrow.Props\n>(function PopupMenuScrollUpArrow(props, forwardedRef) {\n return <PopupMenuScrollArrow ref={forwardedRef} direction=\"up\" {...props} />\n})\n\nexport namespace PopupMenuScrollUpArrow {\n export type State = PopupMenuScrollArrowState\n export interface Props extends PopupMenuScrollUpArrowProps {}\n}\n\nexport interface PopupMenuScrollDownArrowProps\n extends Omit<PopupMenuScrollArrowProps, 'direction'> {}\n\n/**\n * A scroll indicator that appears when there's content below.\n * Scrolls the list down continuously while pointer is over it.\n * Renders a `<div>` element.\n */\nexport const PopupMenuScrollDownArrow = React.forwardRef<\n HTMLDivElement,\n PopupMenuScrollDownArrow.Props\n>(function PopupMenuScrollDownArrow(props, forwardedRef) {\n return <PopupMenuScrollArrow ref={forwardedRef} direction=\"down\" {...props} />\n})\n\nexport namespace PopupMenuScrollDownArrow {\n export type State = PopupMenuScrollArrowState\n export interface Props extends PopupMenuScrollDownArrowProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport { useStableCallback } from '@base-ui/utils/useStableCallback'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n defaultFilter,\n type FilterFn,\n normalizeValue,\n type SearchNormalizer,\n SurfaceContext,\n useListboxContext,\n} from '../../../listbox/index.js'\nimport { POINTER_EVENT_DEBOUNCE_MS } from '../../constants.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { usePopupSurfaceId } from '../../contexts/popup-surface-id-context.js'\nimport { useMaybeSubmenuContext } from '../../contexts/submenu-context.js'\nimport { useMaybeSubpageContext } from '../../contexts/subpage-context.js'\nimport {\n ROOT_SUBPAGE_ID,\n useMaybeSubpageStack,\n} from '../../contexts/subpage-stack-context.js'\n\n// Surface doesn't expose data attributes - using empty state\nexport interface PopupMenuSurfaceState extends Record<string, unknown> {}\n\nexport interface PopupMenuSurfaceProps\n extends ComponentProps<'div', PopupMenuSurface.State> {\n /**\n * Filter function for matching items against search query.\n * Returns a score between 0 and 1 (0 = no match, > 0 = match).\n * Pass `false` to disable filtering entirely.\n * @default commandScore (fuzzy matching)\n */\n filter?: FilterFn | false\n\n /**\n * Transforms search input before filtering and visibility logic.\n * @default trim whitespace (`search.trim()`)\n */\n normalizeSearch?: SearchNormalizer\n\n /**\n * Controlled search value.\n */\n search?: string\n\n /**\n * Callback when search value changes.\n */\n onSearchChange?: (search: string) => void\n\n /**\n * Default search value for uncontrolled usage.\n * @default ''\n */\n defaultSearch?: string\n\n /**\n * Whether navigation should loop from last to first item and vice versa.\n * @default true\n */\n loop?: boolean\n\n /**\n * Controls auto-highlighting behavior when the menu opens.\n * - `true`: highlight the first item (default)\n * - `false`: don't auto-highlight any item\n * - `string`: highlight the item with this specific value\n * @default true\n */\n autoHighlightFirst?: boolean | string\n\n /**\n * Whether to clear the search query when the menu closes.\n * - `true`: clear immediately when menu closes (default)\n * - `false`: preserve search when menu closes\n * - `'after-exit'`: clear after exit animation completes\n * @default true\n */\n clearSearchOnClose?: boolean | 'after-exit'\n\n /**\n * Whether to skip auto-focusing the input/list when this surface becomes the focus owner.\n * Useful for Combobox where the input is outside the popup and should retain focus.\n * @default false\n */\n skipAutoFocus?: boolean\n\n /**\n * Ordered list of item values when using `filter={false}`.\n * This tells the store the intended display order for navigation/highlighting.\n * Required when `filter={false}` - must always be provided with the current visible items.\n */\n orderedItems?: string[]\n\n children: React.ReactNode\n}\n\n/**\n * Provides search context and manages item registration for popup menu.\n * Place inside PopupMenu.Popup to enable search functionality.\n * Renders a `<div>` element.\n */\nexport const PopupMenuSurface = React.forwardRef<\n HTMLDivElement,\n PopupMenuSurface.Props\n>(function PopupMenuSurface(props, forwardedRef) {\n const {\n filter = defaultFilter,\n normalizeSearch = normalizeValue,\n search: searchProp,\n onSearchChange,\n defaultSearch = '',\n loop = true,\n autoHighlightFirst = true,\n clearSearchOnClose = true,\n skipAutoFocus = false,\n orderedItems,\n render,\n className,\n style,\n onPointerDown,\n onPointerMove,\n children,\n ...rest\n } = props\n\n // Get store and depth from Listbox context\n const { store, depth, virtualization } = useListboxContext()\n\n // Get submenu context (if inside a submenu)\n const submenuContext = useMaybeSubmenuContext()\n\n // Get subpage context/stack (if inside a popup with subpage navigation)\n const subpageContext = useMaybeSubpageContext()\n const subpageStack = useMaybeSubpageStack()\n\n // Get focus owner store\n const focusOwnerStore = useFocusOwner()\n\n // Track when surface opened to ignore initial pointer events\n // This prevents focus transfer when a popup appears under a stationary cursor\n const openTimeRef = React.useRef<number>(0)\n\n // Generate stable IDs\n const listId = React.useId()\n const inputId = React.useId()\n const generatedSurfaceId = React.useId()\n\n // Get surfaceId from Popup context (if available) to ensure Popup and Surface share the same ID\n const popupSurfaceId = usePopupSurfaceId()\n\n // Priority: PopupSurfaceIdContext > SubmenuContext > generated\n // This ensures Popup and Surface share the same ID for data attribute tracking\n const surfaceId =\n popupSurfaceId ?? submenuContext?.childSurfaceId ?? generatedSurfaceId\n\n // Only render/activate the surface for the currently active page.\n const isSurfaceActive = React.useMemo(() => {\n if (!subpageStack) {\n return true\n }\n\n if (subpageContext) {\n // If this page is registered in the current popup stack, use it.\n // Otherwise (e.g., nested submenu popup), treat this surface as root page.\n const registeredSurfaceId = subpageStack.getSurfaceId(\n subpageContext.pageId,\n )\n if (registeredSurfaceId) {\n return subpageStack.activePageId === subpageContext.pageId\n }\n }\n\n return subpageStack.activePageId === ROOT_SUBPAGE_ID\n }, [subpageStack, subpageContext])\n\n // Subscribe to focus ownership\n const isOwner = focusOwnerStore.useState('isOwner', surfaceId)\n\n // Create stable callback for onSearchChange\n const handleSearchChange = useStableCallback((search: string) => {\n onSearchChange?.(search)\n })\n\n // Update store context with surface configuration\n React.useEffect(() => {\n store.context.filter = filter\n store.setSearchNormalizer(normalizeSearch)\n store.context.loop = loop\n store.context.autoHighlightFirst = autoHighlightFirst\n store.context.clearSearchOnClose = clearSearchOnClose\n store.context.listId = listId\n store.context.inputId = inputId\n store.context.onSearchChange = handleSearchChange\n\n // Configure virtualization if enabled via props\n // Note: We only manage virtualization when explicitly provided via props.\n // When virtualization is undefined, we don't clear it - this allows child\n // components (like VirtualizedDataListContent) to manage virtualization\n // independently without being overwritten by Surface.\n if (virtualization) {\n store.setVirtualized(virtualization.virtualized)\n store.setVirtualItems(virtualization.items)\n store.setOnHighlightChange(virtualization.onHighlightChange)\n }\n\n // Apply auto-highlight after context is updated\n // This handles the case where autoHighlightFirst is a string value\n // (the open observer only handles boolean true for backwards compatibility)\n if (typeof autoHighlightFirst === 'string') {\n store.applyAutoHighlight()\n }\n }, [\n store,\n filter,\n normalizeSearch,\n loop,\n autoHighlightFirst,\n clearSearchOnClose,\n listId,\n inputId,\n handleSearchChange,\n virtualization,\n ])\n\n // Sync consumer-provided ordered items to store\n // This is separate from the config effect since orderedItems changes on each search\n React.useEffect(() => {\n if (orderedItems) {\n store.setOrderedItems(orderedItems)\n }\n }, [store, orderedItems])\n\n // Sync controlled search prop to store\n store.useControlledProp('search', searchProp, defaultSearch)\n\n // Track the open state\n const open = store.useState('open')\n\n // Ref to the surface element for finding focusable elements\n const surfaceRef = React.useRef<HTMLDivElement | null>(null)\n\n // Record open time when surface opens\n React.useEffect(() => {\n if (open) {\n openTimeRef.current = Date.now()\n }\n }, [open])\n\n // Claim focus ownership when root menu opens\n React.useEffect(() => {\n if (!isSurfaceActive) {\n return\n }\n\n if (depth === 0 && open) {\n focusOwnerStore.setOwnerId(surfaceId)\n }\n }, [depth, open, surfaceId, focusOwnerStore, isSurfaceActive])\n\n // Auto-focus when becoming owner\n // Skip for Combobox where the input is outside the popup and should retain focus\n React.useEffect(() => {\n if (!isSurfaceActive || !isOwner || skipAutoFocus) {\n return\n }\n\n // Use setTimeout(0) to push focus to the next macrotask\n // This allows FloatingFocusManager's cleanup to complete before we focus\n const timeoutId = setTimeout(() => {\n requestAnimationFrame(() => {\n if (!surfaceRef.current) {\n return\n }\n\n // Find input or list within this surface\n const input = surfaceRef.current.querySelector('input')\n const list = surfaceRef.current.querySelector('[role=\"listbox\"]')\n const focusTarget = input ?? list\n\n if (focusTarget && focusTarget instanceof HTMLElement) {\n focusTarget.focus()\n }\n })\n }, 0)\n\n return () => clearTimeout(timeoutId)\n }, [isSurfaceActive, isOwner, skipAutoFocus])\n\n const contextValue = React.useMemo(\n () => ({\n store,\n surfaceId,\n }),\n [store, surfaceId],\n )\n\n // Prevent pointer down from stealing focus from Input\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault()\n onPointerDown?.(event)\n },\n [onPointerDown],\n )\n\n // Claim focus ownership when pointer moves inside this surface\n // This handles the case when moving from a submenu back to parent\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event)\n\n // Ignore pointer events briefly after surface opens\n // This prevents focus transfer when popup appears under stationary cursor\n const timeSinceOpen = Date.now() - openTimeRef.current\n if (timeSinceOpen < POINTER_EVENT_DEBOUNCE_MS) {\n return\n }\n\n // Check if the event target is actually within this surface's DOM\n // This prevents parent surfaces from claiming ownership when events\n // bubble through React portals from child surfaces\n const target = event.target as Node\n if (!surfaceRef.current?.contains(target)) {\n return\n }\n\n // Check store directly to avoid stale reactive state issues\n // Only claim ownership if we're not already the owner\n if (focusOwnerStore.state.ownerId !== surfaceId) {\n focusOwnerStore.setOwnerId(surfaceId)\n }\n },\n [onPointerMove, surfaceId, focusOwnerStore],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'surface')\n\n const element = useRender({\n render,\n ref: [surfaceRef, forwardedRef],\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n className,\n style,\n onPointerDown: handlePointerDown,\n onPointerMove: handlePointerMove,\n children,\n },\n enabled: isSurfaceActive,\n defaultTagName: 'div',\n })\n\n return (\n <SurfaceContext.Provider value={contextValue}>\n {element}\n </SurfaceContext.Provider>\n )\n})\n\nexport namespace PopupMenuSurface {\n export type State = PopupMenuSurfaceState\n export interface Props extends PopupMenuSurfaceProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport {\n createChangeEventDetails,\n REASONS,\n} from '../../../../utils/events/index.js'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { ItemContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport type {\n CheckedChangeEventDetails,\n CheckedChangeReason,\n} from '../../events.js'\nimport { usePopupMenuItem } from '../../hooks/use-popup-menu-item.js'\nimport { PopupMenuCheckboxItemDataAttributes } from './checkbox-item.data-attrs.js'\nimport {\n CheckboxItemContext,\n type CheckboxItemContextValue,\n} from './checkbox-item-context.js'\n\nexport { PopupMenuCheckboxItemDataAttributes }\n\nexport interface PopupMenuCheckboxItemState extends Record<string, unknown> {\n /**\n * Whether the item is highlighted (via keyboard or pointer).\n */\n highlighted: boolean\n /**\n * Whether the item is disabled.\n */\n disabled: boolean\n /**\n * Whether the item is currently checked.\n */\n checked: boolean\n}\n\nexport interface PopupMenuCheckboxItemProps\n extends ComponentProps<'div', PopupMenuCheckboxItem.State> {\n /**\n * The controlled checked state.\n */\n checked?: boolean\n\n /**\n * The default checked state for uncontrolled mode.\n * @default false\n */\n defaultChecked?: boolean\n\n /**\n * Callback fired when the checked state changes.\n * The second parameter contains event details including the reason for the change.\n */\n onCheckedChange?: (\n checked: boolean,\n eventDetails: CheckedChangeEventDetails,\n ) => void\n\n /**\n * Additional keywords to match against when filtering.\n * Useful for aliases or synonyms.\n */\n keywords?: string[]\n\n /**\n * Whether this item is disabled.\n * Disabled items are not selectable and are skipped during keyboard navigation.\n * @default false\n */\n disabled?: boolean\n\n /**\n * Callback when this item is selected (via click or Enter key).\n */\n onSelect?: () => void\n\n /**\n * Whether to force render this item regardless of filter results.\n * @default false\n */\n forceMount?: boolean\n\n /**\n * Whether clicking this item should close the menu.\n * @default false\n */\n closeOnClick?: boolean\n\n /**\n * Keyboard shortcut to trigger this item.\n * When the menu is focused and the user presses this key, the item will be selected.\n * Should be a single character (e.g., \"1\", \"a\", etc.).\n */\n shortcut?: string\n\n /**\n * Forces this row's relative order during score-based sorting.\n * Lower values appear earlier.\n * @default 0\n */\n forceOrder?: number\n\n /**\n * Overrides this row's computed fuzzy-match score.\n */\n forceScore?: number\n}\n\nconst stateAttributesMapping = {\n checked: (value: unknown): Record<string, string> | null =>\n value\n ? { [PopupMenuCheckboxItemDataAttributes.checked]: '' }\n : { [PopupMenuCheckboxItemDataAttributes.unchecked]: '' },\n highlighted: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuCheckboxItemDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuCheckboxItemDataAttributes.disabled]: '' } : null,\n}\n\n/**\n * A selectable checkbox item within a popup menu.\n * Manages its own checked state independently.\n * Renders a `<div>` element with role=\"menuitemcheckbox\".\n */\nexport const PopupMenuCheckboxItem = React.forwardRef<\n HTMLDivElement,\n PopupMenuCheckboxItem.Props\n>(function PopupMenuCheckboxItem(props, forwardedRef) {\n const {\n id,\n checked: checkedProp,\n defaultChecked = false,\n onCheckedChange,\n keywords,\n disabled: disabledProp = false,\n onSelect,\n forceMount = false,\n closeOnClick = false,\n shortcut,\n forceOrder,\n forceScore,\n render,\n className,\n style,\n onClick,\n onPointerDown,\n onPointerMove,\n children,\n ...rest\n } = props\n\n // Controlled/uncontrolled state management\n const [internalChecked, setInternalChecked] =\n React.useState<boolean>(defaultChecked)\n const isControlled = checkedProp !== undefined\n const checked = isControlled ? checkedProp : internalChecked\n\n const toggleChecked = React.useCallback(\n (reason: CheckedChangeReason = REASONS.itemPress, event?: Event) => {\n const newChecked = !checked\n const eventDetails = createChangeEventDetails(reason, event)\n\n // Call user's callback first\n onCheckedChange?.(newChecked, eventDetails)\n\n // If canceled, don't update internal state\n if (eventDetails.isCanceled) return\n\n if (!isControlled) {\n setInternalChecked(newChecked)\n }\n },\n [checked, isControlled, onCheckedChange],\n )\n\n const item = usePopupMenuItem({\n id,\n keywords,\n disabled: disabledProp,\n forceMount,\n shortcut,\n forceOrder,\n forceScore,\n closeOnClick,\n children,\n })\n\n const disabled = item.disabled\n\n // Register the select handler that toggles checked state\n // Note: closeOnClick is handled by usePopupMenuItem's onAfterSelect\n React.useEffect(() => {\n const handleSelect = () => {\n if (disabled) return\n toggleChecked()\n onSelect?.()\n }\n return item.registerSelect(handleSelect)\n }, [disabled, toggleChecked, onSelect, item])\n\n const state: PopupMenuCheckboxItem.State = React.useMemo(\n () => ({ highlighted: item.isHighlighted, disabled, checked }),\n [item.isHighlighted, disabled, checked],\n )\n\n const checkboxItemContextValue: CheckboxItemContextValue = React.useMemo(\n () => ({\n ...item.contextValue,\n checked,\n toggle: toggleChecked,\n }),\n [item.contextValue, checked, toggleChecked],\n )\n\n // Merge user-provided handlers with item handlers\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onClick(event)\n }\n },\n [onClick, item.handlers],\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n item.handlers.onPointerDown(event)\n onPointerDown?.(event)\n },\n [item.handlers, onPointerDown],\n )\n\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onPointerMove(event)\n }\n },\n [onPointerMove, item.handlers],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'checkbox-item')\n\n const element = useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: item.id,\n role: 'menuitemcheckbox',\n tabIndex: -1,\n 'aria-checked': checked,\n 'aria-disabled': disabled || undefined,\n className,\n style,\n onClick: handleClick,\n onPointerMove: handlePointerMove,\n onPointerDown: handlePointerDown,\n children,\n },\n enabled: item.isVisible,\n defaultTagName: 'div',\n })\n\n if (!item.isVisible) {\n return null\n }\n\n return (\n <ItemContext.Provider value={item.contextValue}>\n <CheckboxItemContext.Provider value={checkboxItemContextValue}>\n {element}\n </CheckboxItemContext.Provider>\n </ItemContext.Provider>\n )\n})\n\nexport namespace PopupMenuCheckboxItem {\n export type State = PopupMenuCheckboxItemState\n export interface Props extends PopupMenuCheckboxItemProps {}\n}\n","export enum PopupMenuCheckboxItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-checkbox-item' | 'bazzaui-context-menu-checkbox-item'}\n */\n slot = 'bazzaui-[component]-checkbox-item',\n /**\n * Present when the checkbox item is checked.\n */\n checked = 'data-checked',\n /**\n * Present when the checkbox item is unchecked.\n */\n unchecked = 'data-unchecked',\n /**\n * Present when the item is highlighted (via keyboard or pointer).\n */\n highlighted = 'data-highlighted',\n /**\n * Present when the item is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ItemContextValue } from '../../../listbox/index.js'\nimport type { CheckedChangeReason } from '../../events.js'\n\n/**\n * Context value for checkbox menu items.\n * Extends ItemContextValue with checkbox-specific state.\n */\nexport interface CheckboxItemContextValue extends ItemContextValue {\n /** Whether this checkbox item is currently checked */\n checked: boolean\n /**\n * Toggle the checked state.\n * @param reason - The reason for the change (default: 'item-press')\n * @param event - The native DOM event that triggered the change\n */\n toggle: (reason?: CheckedChangeReason, event?: Event) => void\n}\n\nconst CheckboxItemContext =\n React.createContext<CheckboxItemContextValue | null>(null)\n\nexport function useCheckboxItemContext(): CheckboxItemContextValue {\n const context = React.useContext(CheckboxItemContext)\n if (!context) {\n throw new Error(\n 'PopupMenu.CheckboxItemIndicator must be used within PopupMenu.CheckboxItem',\n )\n }\n return context\n}\n\nexport { CheckboxItemContext }\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { PopupMenuCheckboxItemDataAttributes } from './checkbox-item.data-attrs.js'\nimport { useCheckboxItemContext } from './checkbox-item-context.js'\n\nexport interface PopupMenuCheckboxItemIndicatorState\n extends Record<string, unknown> {\n /**\n * Whether the parent checkbox item is currently checked.\n */\n checked: boolean\n /**\n * Whether the parent checkbox item is currently highlighted.\n */\n highlighted: boolean\n /**\n * Whether the parent checkbox item is disabled.\n */\n disabled: boolean\n /**\n * Toggle the checked state without triggering closeOnClick.\n * Useful when you want clicking directly on the indicator to toggle\n * without closing the menu.\n */\n toggle: () => void\n}\n\nexport interface PopupMenuCheckboxItemIndicatorProps\n extends ComponentProps<'span', PopupMenuCheckboxItemIndicator.State> {\n /**\n * Whether to keep the indicator mounted in the DOM when unchecked.\n * Useful for animations.\n * @default false\n */\n keepMounted?: boolean\n}\n\nconst stateAttributesMapping = {\n checked: (value: unknown): Record<string, string> | null =>\n value\n ? { [PopupMenuCheckboxItemDataAttributes.checked]: '' }\n : { [PopupMenuCheckboxItemDataAttributes.unchecked]: '' },\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuCheckboxItemDataAttributes.disabled]: '' } : null,\n}\n\n/**\n * A visual indicator that shows when a CheckboxItem is checked.\n * Must be used within a CheckboxItem component.\n * Renders a `<span>` element with aria-hidden=\"true\".\n */\nexport const PopupMenuCheckboxItemIndicator = React.forwardRef<\n HTMLSpanElement,\n PopupMenuCheckboxItemIndicator.Props\n>(function PopupMenuCheckboxItemIndicator(props, forwardedRef) {\n const {\n keepMounted = false,\n render,\n className,\n style,\n children,\n ...rest\n } = props\n\n const { checked, highlighted, disabled, toggle } = useCheckboxItemContext()\n\n const state: PopupMenuCheckboxItemIndicator.State = React.useMemo(\n () => ({ checked, highlighted, disabled, toggle }),\n [checked, highlighted, disabled, toggle],\n )\n\n const shouldRender = keepMounted || checked\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'checkbox-item-indicator')\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n 'aria-hidden': true,\n className,\n style,\n children,\n },\n enabled: shouldRender,\n defaultTagName: 'span',\n })\n})\n\nexport namespace PopupMenuCheckboxItemIndicator {\n export type State = PopupMenuCheckboxItemIndicatorState\n export interface Props extends PopupMenuCheckboxItemIndicatorProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { ItemContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { usePopupMenuItem } from '../../hooks/use-popup-menu-item.js'\nimport { PopupMenuItemDataAttributes } from './item.data-attrs.js'\n\nexport { PopupMenuItemDataAttributes }\n\nexport interface PopupMenuItemState extends Record<string, unknown> {\n /**\n * Whether the item is highlighted (via keyboard or pointer).\n */\n highlighted: boolean\n /**\n * Whether the item is disabled.\n */\n disabled: boolean\n}\n\nexport interface PopupMenuItemProps\n extends ComponentProps<'div', PopupMenuItem.State> {\n /**\n * Unique value for this item used for filtering.\n * If not provided, will be inferred from textContent.\n */\n value?: string\n\n /**\n * Additional keywords to match against when filtering.\n * Useful for aliases or synonyms.\n */\n keywords?: string[]\n\n /**\n * Whether this item is disabled.\n * Disabled items are not selectable and are skipped during keyboard navigation.\n */\n disabled?: boolean\n\n /**\n * Callback when this item is selected (via click or Enter key).\n */\n onSelect?: () => void\n\n /**\n * Whether to force render this item regardless of filter results.\n * @default false\n */\n forceMount?: boolean\n\n /**\n * Whether clicking this item should close the menu.\n * @default true\n */\n closeOnClick?: boolean\n\n /**\n * Keyboard shortcut to trigger this item.\n * When the menu is focused and the user presses this key, the item will be selected.\n * Should be a single character (e.g., \"1\", \"a\", etc.).\n */\n shortcut?: string\n\n /**\n * Forces this row's relative order during score-based sorting.\n * Lower values appear earlier.\n * @default 0\n */\n forceOrder?: number\n\n /**\n * Overrides this row's computed fuzzy-match score.\n */\n forceScore?: number\n}\n\nconst stateAttributesMapping = {\n highlighted: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuItemDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuItemDataAttributes.disabled]: '' } : null,\n}\n\n/**\n * A selectable item in the popup menu.\n * Renders a `<div>` element with role=\"option\".\n */\nexport const PopupMenuItem = React.forwardRef<\n HTMLDivElement,\n PopupMenuItem.Props\n>(function PopupMenuItem(props, forwardedRef) {\n const {\n id,\n value,\n keywords,\n disabled: disabledProp = false,\n onSelect,\n forceMount = false,\n closeOnClick = true,\n shortcut,\n forceOrder,\n forceScore,\n render,\n className,\n style,\n onClick,\n onPointerDown,\n onPointerMove,\n children,\n ...rest\n } = props\n\n const item = usePopupMenuItem({\n id,\n value,\n keywords,\n disabled: disabledProp,\n forceMount,\n shortcut,\n forceOrder,\n forceScore,\n onSelect,\n closeOnClick,\n children,\n })\n\n const disabled = item.disabled\n\n const state: PopupMenuItem.State = React.useMemo(\n () => ({\n highlighted: item.isHighlighted,\n disabled,\n }),\n [item.isHighlighted, disabled],\n )\n\n // Merge user-provided handlers with item handlers\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onClick(event)\n }\n },\n [onClick, item.handlers],\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n item.handlers.onPointerDown(event)\n onPointerDown?.(event)\n },\n [item.handlers, onPointerDown],\n )\n\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onPointerMove(event)\n }\n },\n [onPointerMove, item.handlers],\n )\n\n // Wrap children with ItemContext.Provider so child components can access item state\n const wrappedChildren = (\n <ItemContext.Provider value={item.contextValue}>\n {children}\n </ItemContext.Provider>\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'item')\n\n return useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: item.id,\n role: 'option',\n tabIndex: -1,\n 'aria-selected': item.isHighlighted,\n 'aria-disabled': disabled || undefined,\n className,\n style,\n onClick: handleClick,\n onPointerMove: handlePointerMove,\n onPointerDown: handlePointerDown,\n children: wrappedChildren,\n },\n enabled: item.isVisible,\n defaultTagName: 'div',\n })\n})\n\nexport namespace PopupMenuItem {\n export type State = PopupMenuItemState\n export interface Props extends PopupMenuItemProps {}\n}\n","export enum PopupMenuItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-item' | 'bazzaui-context-menu-item' | 'bazzaui-select-item' | 'bazzaui-combobox-item'}\n */\n slot = 'bazzaui-[component]-item',\n /**\n * Present when the item is highlighted (via keyboard or pointer).\n */\n highlighted = 'data-highlighted',\n /**\n * Present when the item is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport {\n createChangeEventDetails,\n REASONS,\n} from '../../../../utils/events/index.js'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { GroupContext, useSurfaceContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { usePopupMenuContext } from '../../contexts/popup-menu-context.js'\nimport type {\n RadioValueChangeEventDetails,\n RadioValueChangeReason,\n} from '../../events.js'\nimport { PopupMenuRadioGroupDataAttributes } from './radio-group.data-attrs.js'\nimport {\n RadioGroupContext,\n type RadioGroupContextValue,\n} from './radio-group-context.js'\n\nexport { PopupMenuRadioGroupDataAttributes }\n\nexport interface PopupMenuRadioGroupState extends Record<string, unknown> {\n /**\n * Whether the radio group is disabled.\n */\n disabled: boolean\n}\n\nexport interface PopupMenuRadioGroupProps\n extends ComponentProps<'div', PopupMenuRadioGroup.State> {\n /**\n * The controlled selected value.\n */\n value?: string\n\n /**\n * The default value for uncontrolled mode.\n */\n defaultValue?: string\n\n /**\n * Callback fired when the selected value changes.\n * The second parameter contains event details including the reason for the change.\n */\n onValueChange?: (\n value: string,\n eventDetails: RadioValueChangeEventDetails,\n ) => void\n\n /**\n * Whether all items in this group are disabled.\n * @default false\n */\n disabled?: boolean\n\n /**\n * Whether to force render this group regardless of filter results.\n * @default false\n */\n forceMount?: boolean\n\n children: React.ReactNode\n}\n\nconst stateAttributesMapping = {\n disabled: (value: unknown) =>\n value ? { [PopupMenuRadioGroupDataAttributes.disabled]: '' } : null,\n}\n\n/**\n * Groups radio items together and manages the selected value.\n * Only one item can be selected at a time within a radio group.\n * Renders a `<div>` element with role=\"group\".\n */\nexport const PopupMenuRadioGroup = React.forwardRef(\n function PopupMenuRadioGroup(\n props: PopupMenuRadioGroupProps,\n forwardedRef: React.ForwardedRef<HTMLDivElement>,\n ) {\n const {\n value: valueProp,\n defaultValue,\n onValueChange,\n disabled: disabledProp = false,\n forceMount = false,\n render,\n className,\n style,\n children,\n ...rest\n } = props\n\n const { store } = useSurfaceContext()\n const popupMenuContext = usePopupMenuContext()\n const groupId = React.useId()\n\n const disabled = disabledProp || popupMenuContext.disabled\n\n // Controlled/uncontrolled state management\n const [internalValue, setInternalValue] = React.useState<\n string | undefined\n >(defaultValue)\n const isControlled = valueProp !== undefined\n const value = isControlled ? valueProp : internalValue\n\n const setValue = React.useCallback(\n (\n newValue: string,\n reason: RadioValueChangeReason = REASONS.itemPress,\n event?: Event,\n ) => {\n const eventDetails = createChangeEventDetails(reason, event)\n\n // Call user's callback first\n onValueChange?.(newValue, eventDetails)\n\n // If canceled, don't update internal state\n if (eventDetails.isCanceled) return\n\n if (!isControlled) {\n setInternalValue(newValue)\n }\n },\n [isControlled, onValueChange],\n )\n\n // Register group with store for filtering visibility\n React.useEffect(() => {\n const unregister = store.registerGroup(groupId)\n return unregister\n }, [groupId, store])\n\n // Check visibility using selector\n const isGroupVisible = store.useState('isGroupVisible', groupId)\n const isVisible = forceMount || isGroupVisible\n\n // Context values\n const radioGroupContextValue: RadioGroupContextValue = React.useMemo(\n () => ({ value, setValue, disabled }),\n [value, setValue, disabled],\n )\n\n const groupContextValue = React.useMemo(() => ({ groupId }), [groupId])\n\n const state: PopupMenuRadioGroup.State = React.useMemo(\n () => ({ disabled }),\n [disabled],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'radio-group')\n\n const element = useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n role: 'group',\n 'aria-disabled': disabled || undefined,\n className,\n style,\n children,\n },\n enabled: isVisible,\n defaultTagName: 'div',\n })\n\n if (!isVisible) {\n return null\n }\n\n return (\n <RadioGroupContext.Provider value={radioGroupContextValue}>\n <GroupContext.Provider value={groupContextValue}>\n {element}\n </GroupContext.Provider>\n </RadioGroupContext.Provider>\n )\n },\n)\n\nexport namespace PopupMenuRadioGroup {\n export type State = PopupMenuRadioGroupState\n export interface Props extends PopupMenuRadioGroupProps {}\n}\n","export enum PopupMenuRadioGroupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-radio-group' | 'bazzaui-context-menu-radio-group'}\n */\n slot = 'bazzaui-[component]-radio-group',\n /**\n * Present when the radio group is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { RadioValueChangeReason } from '../../events.js'\n\nexport interface RadioGroupContextValue {\n /** Current selected value */\n value: string | undefined\n /**\n * Function to update the selected value.\n * @param value - The new value to select\n * @param reason - The reason for the change (default: 'item-press')\n * @param event - The native DOM event that triggered the change\n */\n setValue: (\n value: string,\n reason?: RadioValueChangeReason,\n event?: Event,\n ) => void\n /** Whether all items in the group are disabled */\n disabled: boolean\n}\n\nconst RadioGroupContext = React.createContext<RadioGroupContextValue | null>(\n null,\n)\n\nexport function useRadioGroupContext(): RadioGroupContextValue {\n const context = React.useContext(RadioGroupContext)\n if (!context) {\n throw new Error(\n 'PopupMenu.RadioItem must be used within PopupMenu.RadioGroup',\n )\n }\n return context\n}\n\nexport { RadioGroupContext }\n","'use client'\n\nimport * as React from 'react'\nimport {\n createChangeEventDetails,\n REASONS,\n} from '../../../../utils/events/index.js'\nimport type {\n RadioValueChangeEventDetails,\n RadioValueChangeReason,\n} from '../../events.js'\nimport {\n RadioGroupContext,\n type RadioGroupContextValue,\n} from './radio-group-context.js'\n\nexport interface PopupMenuRadioGroupValueProps {\n /**\n * The controlled selected value.\n */\n value: string | undefined\n\n /**\n * Callback fired when the selected value changes.\n * The second parameter contains event details including the reason for the change.\n */\n onValueChange?: (\n value: string,\n eventDetails: RadioValueChangeEventDetails,\n ) => void\n\n /**\n * Whether all items in this group are disabled.\n * @default false\n */\n disabled?: boolean\n\n /**\n * Children to render within the radio group context.\n */\n children: React.ReactNode\n}\n\n/**\n * Headless provider for radio group state.\n * Use this to wrap DataSurface when using RadioItems in deep search.\n * Does not render any DOM element - only provides context.\n *\n * @example\n * ```tsx\n * const [theme, setTheme] = useState('light')\n *\n * <DropdownMenu.RadioGroupValue value={theme} onValueChange={setTheme}>\n * <DropdownMenu.DataSurface content={content}>\n * ...\n * </DropdownMenu.DataSurface>\n * </DropdownMenu.RadioGroupValue>\n * ```\n */\nexport function PopupMenuRadioGroupValue(props: PopupMenuRadioGroupValueProps) {\n const { value, onValueChange, disabled = false, children } = props\n\n const setValue = React.useCallback(\n (\n newValue: string,\n reason: RadioValueChangeReason = REASONS.itemPress,\n event?: Event,\n ) => {\n const eventDetails = createChangeEventDetails(reason, event)\n onValueChange?.(newValue, eventDetails)\n },\n [onValueChange],\n )\n\n const contextValue: RadioGroupContextValue = React.useMemo(\n () => ({ value, setValue, disabled }),\n [value, setValue, disabled],\n )\n\n return (\n <RadioGroupContext.Provider value={contextValue}>\n {children}\n </RadioGroupContext.Provider>\n )\n}\n\nexport namespace PopupMenuRadioGroupValue {\n export interface Props extends PopupMenuRadioGroupValueProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { ItemContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { usePopupMenuItem } from '../../hooks/use-popup-menu-item.js'\nimport { useRadioGroupContext } from '../radio-group/radio-group-context.js'\nimport { PopupMenuRadioItemDataAttributes } from './radio-item.data-attrs.js'\nimport {\n RadioItemContext,\n type RadioItemContextValue,\n} from './radio-item-context.js'\n\nexport { PopupMenuRadioItemDataAttributes }\n\nexport interface PopupMenuRadioItemState extends Record<string, unknown> {\n /**\n * Whether the item is highlighted (via keyboard or pointer).\n */\n highlighted: boolean\n /**\n * Whether the item is disabled.\n */\n disabled: boolean\n /**\n * Whether the item is currently selected/checked.\n */\n checked: boolean\n}\n\nexport interface PopupMenuRadioItemProps\n extends ComponentProps<'div', PopupMenuRadioItem.State> {\n /**\n * The value to set when this item is selected.\n * This is required and must be unique within the RadioGroup.\n */\n value: string\n\n /**\n * Additional keywords to match against when filtering.\n * Useful for aliases or synonyms.\n */\n keywords?: string[]\n\n /**\n * Whether this item is disabled.\n * Disabled items are not selectable and are skipped during keyboard navigation.\n * @default false\n */\n disabled?: boolean\n\n /**\n * Callback when this item is selected.\n */\n onSelect?: () => void\n\n /**\n * Whether to force render this item regardless of filter results.\n * @default false\n */\n forceMount?: boolean\n\n /**\n * Whether clicking this item should close the menu.\n * @default false\n */\n closeOnClick?: boolean\n\n /**\n * Keyboard shortcut to trigger this item.\n * When the menu is focused and the user presses this key, the item will be selected.\n * Should be a single character (e.g., \"1\", \"a\", etc.).\n */\n shortcut?: string\n\n /**\n * Forces this row's relative order during score-based sorting.\n * Lower values appear earlier.\n * @default 0\n */\n forceOrder?: number\n\n /**\n * Overrides this row's computed fuzzy-match score.\n */\n forceScore?: number\n}\n\nconst stateAttributesMapping = {\n checked: (value: unknown): Record<string, string> | null =>\n value\n ? { [PopupMenuRadioItemDataAttributes.checked]: '' }\n : { [PopupMenuRadioItemDataAttributes.unchecked]: '' },\n highlighted: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuRadioItemDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuRadioItemDataAttributes.disabled]: '' } : null,\n}\n\n/**\n * A selectable radio item within a RadioGroup.\n * Only one RadioItem can be selected at a time within a RadioGroup.\n * Renders a `<div>` element with role=\"menuitemradio\".\n */\nexport const PopupMenuRadioItem = React.forwardRef(function PopupMenuRadioItem(\n props: PopupMenuRadioItemProps,\n forwardedRef: React.ForwardedRef<HTMLDivElement>,\n) {\n const {\n id,\n value,\n keywords,\n disabled: disabledProp = false,\n onSelect,\n forceMount = false,\n closeOnClick = false,\n shortcut,\n forceOrder,\n forceScore,\n render,\n className,\n style,\n onClick,\n onPointerDown,\n onPointerMove,\n children,\n ...rest\n } = props\n\n const radioGroupContext = useRadioGroupContext()\n\n // Combine disabled from props and RadioGroup\n const localDisabled = disabledProp || radioGroupContext.disabled\n\n // Check if this item is selected\n const checked = radioGroupContext.value === value\n\n const item = usePopupMenuItem({\n id,\n keywords,\n disabled: localDisabled,\n forceMount,\n shortcut,\n forceOrder,\n forceScore,\n closeOnClick,\n children,\n })\n\n const disabled = item.disabled\n\n // Register the select handler that sets the radio value\n // Note: closeOnClick is handled by usePopupMenuItem's onAfterSelect\n React.useEffect(() => {\n const handleSelect = () => {\n if (disabled) return\n radioGroupContext.setValue(value)\n onSelect?.()\n }\n return item.registerSelect(handleSelect)\n }, [disabled, radioGroupContext, value, onSelect, item])\n\n const state: PopupMenuRadioItem.State = React.useMemo(\n () => ({ highlighted: item.isHighlighted, disabled, checked }),\n [item.isHighlighted, disabled, checked],\n )\n\n const radioItemContextValue: RadioItemContextValue = React.useMemo(\n () => ({\n ...item.contextValue,\n checked,\n }),\n [item.contextValue, checked],\n )\n\n // Merge user-provided handlers with item handlers\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onClick(event)\n }\n },\n [onClick, item.handlers],\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n item.handlers.onPointerDown(event)\n onPointerDown?.(event)\n },\n [item.handlers, onPointerDown],\n )\n\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onPointerMove(event)\n }\n },\n [onPointerMove, item.handlers],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'radio-item')\n\n const element = useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: item.id,\n role: 'menuitemradio',\n tabIndex: -1,\n 'aria-checked': checked,\n 'aria-disabled': disabled || undefined,\n className,\n style,\n onClick: handleClick,\n onPointerMove: handlePointerMove,\n onPointerDown: handlePointerDown,\n children,\n },\n enabled: item.isVisible,\n defaultTagName: 'div',\n })\n\n if (!item.isVisible) {\n return null\n }\n\n return (\n <ItemContext.Provider value={item.contextValue}>\n <RadioItemContext.Provider value={radioItemContextValue}>\n {element}\n </RadioItemContext.Provider>\n </ItemContext.Provider>\n )\n})\n\nexport namespace PopupMenuRadioItem {\n export type State = PopupMenuRadioItemState\n export interface Props extends PopupMenuRadioItemProps {}\n}\n","export enum PopupMenuRadioItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-radio-item' | 'bazzaui-context-menu-radio-item'}\n */\n slot = 'bazzaui-[component]-radio-item',\n /**\n * Present when the radio item is checked/selected.\n */\n checked = 'data-checked',\n /**\n * Present when the radio item is unchecked.\n */\n unchecked = 'data-unchecked',\n /**\n * Present when the item is highlighted (via keyboard or pointer).\n */\n highlighted = 'data-highlighted',\n /**\n * Present when the item is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ItemContextValue } from '../../../listbox/index.js'\n\n/**\n * Context value for radio menu items.\n * Extends ItemContextValue with radio-specific state.\n */\nexport interface RadioItemContextValue extends ItemContextValue {\n /** Whether this radio item is currently selected */\n checked: boolean\n}\n\nconst RadioItemContext = React.createContext<RadioItemContextValue | null>(null)\n\nexport function useRadioItemContext(): RadioItemContextValue {\n const context = React.useContext(RadioItemContext)\n if (!context) {\n throw new Error(\n 'PopupMenu.RadioItemIndicator must be used within PopupMenu.RadioItem',\n )\n }\n return context\n}\n\nexport { RadioItemContext }\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { PopupMenuRadioItemDataAttributes } from './radio-item.data-attrs.js'\nimport { useRadioItemContext } from './radio-item-context.js'\n\nexport interface PopupMenuRadioItemIndicatorState\n extends Record<string, unknown> {\n /**\n * Whether the parent radio item is currently selected/checked.\n */\n checked: boolean\n /**\n * Whether the parent radio item is currently highlighted.\n */\n highlighted: boolean\n /**\n * Whether the parent radio item is disabled.\n */\n disabled: boolean\n}\n\nexport interface PopupMenuRadioItemIndicatorProps\n extends ComponentProps<'span', PopupMenuRadioItemIndicator.State> {\n /**\n * Whether to keep the indicator mounted in the DOM when unchecked.\n * Useful for animations.\n * @default false\n */\n keepMounted?: boolean\n}\n\nconst stateAttributesMapping = {\n checked: (value: unknown): Record<string, string> | null =>\n value\n ? { [PopupMenuRadioItemDataAttributes.checked]: '' }\n : { [PopupMenuRadioItemDataAttributes.unchecked]: '' },\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuRadioItemDataAttributes.disabled]: '' } : null,\n}\n\n/**\n * A visual indicator that shows when a RadioItem is selected.\n * Must be used within a RadioItem component.\n * Renders a `<span>` element with aria-hidden=\"true\".\n */\nexport const PopupMenuRadioItemIndicator = React.forwardRef<\n HTMLSpanElement,\n PopupMenuRadioItemIndicator.Props\n>(function PopupMenuRadioItemIndicator(props, forwardedRef) {\n const {\n keepMounted = false,\n render,\n className,\n style,\n children,\n ...rest\n } = props\n\n const { checked, highlighted, disabled } = useRadioItemContext()\n\n const state: PopupMenuRadioItemIndicator.State = React.useMemo(\n () => ({ checked, highlighted, disabled }),\n [checked, highlighted, disabled],\n )\n\n const shouldRender = keepMounted || checked\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'radio-item-indicator')\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n 'aria-hidden': true,\n className,\n style,\n children,\n },\n enabled: shouldRender,\n defaultTagName: 'span',\n })\n})\n\nexport namespace PopupMenuRadioItemIndicator {\n export type State = PopupMenuRadioItemIndicatorState\n export interface Props extends PopupMenuRadioItemIndicatorProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { GroupContext, useSurfaceContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\n\nexport interface PopupMenuGroupState extends Record<string, unknown> {\n /**\n * Whether the group is hidden due to no matching items.\n */\n hidden: boolean\n}\n\nexport interface PopupMenuGroupProps\n extends ComponentProps<'div', PopupMenuGroup.State> {\n /**\n * Whether to force render this group regardless of filter results.\n * @default false\n */\n forceMount?: boolean\n\n children: React.ReactNode\n}\n\n/**\n * Groups related popup menu items together.\n * Hidden when no child items match the current filter.\n * Renders a `<div>` element with role=\"group\".\n */\nexport const PopupMenuGroup = React.forwardRef<\n HTMLDivElement,\n PopupMenuGroup.Props\n>(function PopupMenuGroup(props, forwardedRef) {\n const {\n forceMount = false,\n render,\n className,\n style,\n children,\n ...rest\n } = props\n\n const { store } = useSurfaceContext()\n const groupId = React.useId()\n\n // Register group with store\n React.useEffect(() => {\n const unregister = store.registerGroup(groupId)\n return unregister\n }, [groupId, store])\n\n // Check if group has visible items using selector\n const isGroupVisible = store.useState('isGroupVisible', groupId)\n const isVisible = forceMount || isGroupVisible\n\n // Provide group context to children\n const groupContextValue = React.useMemo(() => ({ groupId }), [groupId])\n\n const state: PopupMenuGroup.State = React.useMemo(\n () => ({\n hidden: !isVisible,\n }),\n [isVisible],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'group')\n\n const element = useRender({\n render,\n ref: forwardedRef,\n state,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n // Using role=\"presentation\" since we're inside a listbox.\n // The group is purely visual - items are the semantic options.\n role: 'presentation',\n className,\n style,\n children,\n },\n enabled: isVisible,\n defaultTagName: 'div',\n })\n\n if (!isVisible) {\n return null\n }\n\n return (\n <GroupContext.Provider value={groupContextValue}>\n {element}\n </GroupContext.Provider>\n )\n})\n\nexport namespace PopupMenuGroup {\n export type State = PopupMenuGroupState\n export interface Props extends PopupMenuGroupProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\n\n// GroupLabel doesn't have any state - using an empty object type\nexport interface PopupMenuGroupLabelState extends Record<string, unknown> {}\n\nexport interface PopupMenuGroupLabelProps\n extends ComponentProps<'div', PopupMenuGroupLabel.State> {\n children: React.ReactNode\n}\n\n/**\n * A label/heading for a group of popup menu items.\n * Renders a `<div>` element with role=\"presentation\".\n */\nexport const PopupMenuGroupLabel = React.forwardRef<\n HTMLDivElement,\n PopupMenuGroupLabel.Props\n>(function PopupMenuGroupLabel(props, forwardedRef) {\n const { render, className, style, children, ...rest } = props\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'group-label')\n\n return useRender({\n render,\n ref: forwardedRef,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n // Presentation role - this is a visual label, not interactive\n role: 'presentation',\n // aria-hidden since the group label is decorative for screen readers\n // in the context of a listbox (options are the semantic elements)\n 'aria-hidden': 'true',\n className,\n style,\n children,\n },\n defaultTagName: 'div',\n })\n})\n\nexport namespace PopupMenuGroupLabel {\n export type State = PopupMenuGroupLabelState\n export interface Props extends PopupMenuGroupLabelProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { useSurfaceContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\n\n// Separator doesn't have any state - using an empty object type\nexport interface PopupMenuSeparatorState extends Record<string, unknown> {}\n\nexport interface PopupMenuSeparatorProps\n extends ComponentProps<'div', PopupMenuSeparator.State> {\n /**\n * Whether to always render the separator, even during search.\n * By default, separators are hidden when there's an active search query.\n * @default false\n */\n alwaysRender?: boolean\n}\n\n/**\n * A visual separator between popup menu items.\n * Hidden during active search unless `alwaysRender` is true.\n * Renders a `<div>` element with role=\"separator\".\n */\nexport const PopupMenuSeparator = React.forwardRef<\n HTMLDivElement,\n PopupMenuSeparator.Props\n>(function PopupMenuSeparator(props, forwardedRef) {\n const { alwaysRender = false, render, className, style, ...rest } = props\n\n const { store } = useSurfaceContext()\n\n // Get search state from store\n const search = store.useState('normalizedSearch')\n\n // Hide separator when there's an active search (unless alwaysRender)\n const hasSearch = search.length > 0\n const isHidden = hasSearch && !alwaysRender\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'separator')\n\n const element = useRender({\n render,\n ref: forwardedRef,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n // Using role=\"none\" as this is a purely visual separator within a listbox.\n // The semantic separator role requires focus for interactive separators.\n role: 'none',\n className,\n style,\n },\n defaultTagName: 'div',\n })\n\n if (isHidden) {\n return null\n }\n\n return element\n})\n\nexport namespace PopupMenuSeparator {\n export type State = PopupMenuSeparatorState\n export interface Props extends PopupMenuSeparatorProps {}\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { useItemContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { PopupMenuShortcutDataAttributes } from './shortcut.data-attrs.js'\n\nexport { PopupMenuShortcutDataAttributes }\n\n/**\n * State for the Shortcut component, passed to children render function.\n */\nexport interface PopupMenuShortcutState extends Record<string, unknown> {\n /**\n * The keyboard shortcut value from the parent Item.\n */\n shortcut: string | undefined\n /**\n * Whether the parent item is highlighted.\n */\n highlighted: boolean\n}\n\nexport interface PopupMenuShortcutProps\n extends Omit<ComponentProps<'kbd', PopupMenuShortcut.State>, 'children'> {\n /**\n * Content to render inside the shortcut.\n * Can be a render function that receives the shortcut value.\n * If not provided, renders the shortcut value from the parent Item.\n */\n children?:\n | React.ReactNode\n | ((state: PopupMenuShortcutState) => React.ReactNode)\n}\n\nconst stateAttributesMapping = {\n highlighted: (value: unknown): Record<string, string> | null =>\n value ? { [PopupMenuShortcutDataAttributes.highlighted]: '' } : null,\n}\n\n/**\n * Displays the keyboard shortcut for a menu item.\n * Must be used within a PopupMenu.Item component.\n * Renders a `<kbd>` element by default.\n *\n * @example\n * ```tsx\n * // Auto-renders the shortcut value\n * <PopupMenu.Item shortcut=\"1\">\n * Icebox\n * <PopupMenu.Shortcut />\n * </PopupMenu.Item>\n *\n * // Custom rendering with children as function\n * <PopupMenu.Item shortcut=\"1\">\n * Icebox\n * <PopupMenu.Shortcut>\n * {({ shortcut }) => <span className=\"key\">{shortcut}</span>}\n * </PopupMenu.Shortcut>\n * </PopupMenu.Item>\n * ```\n */\nexport const PopupMenuShortcut = React.forwardRef<\n HTMLElement,\n PopupMenuShortcut.Props\n>(function PopupMenuShortcut(props, forwardedRef) {\n const { children, render, className, style, ...rest } = props\n\n const { shortcut, highlighted } = useItemContext()\n\n const state: PopupMenuShortcut.State = React.useMemo(\n () => ({ shortcut, highlighted }),\n [shortcut, highlighted],\n )\n\n // Render children as function, custom children, or default to shortcut value\n const renderedChildren =\n typeof children === 'function' ? children(state) : (children ?? shortcut)\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'shortcut')\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n className,\n style,\n children: renderedChildren,\n },\n defaultTagName: 'kbd',\n })\n})\n\nexport namespace PopupMenuShortcut {\n export type State = PopupMenuShortcutState\n export interface Props extends PopupMenuShortcutProps {}\n}\n","export enum PopupMenuShortcutDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-shortcut' | 'bazzaui-context-menu-shortcut'}\n */\n slot = 'bazzaui-[component]-shortcut',\n /**\n * Present when the parent item is highlighted.\n */\n highlighted = 'data-highlighted',\n}\n","'use client'\n\nimport { Popover, type PopoverRootProps } from '@base-ui/react/popover'\nimport { useStableCallback } from '@base-ui/utils/useStableCallback'\nimport * as React from 'react'\nimport {\n ListboxContextProvider,\n ListboxStore,\n useMaybeListboxContext,\n useSurfaceContext,\n type VirtualItem,\n} from '../../../listbox/index.js'\nimport { useOpenChain } from '../../contexts/open-chain-context.js'\nimport {\n PopupMenuContext,\n useMaybePopupMenuContext,\n} from '../../contexts/popup-menu-context.js'\nimport { SubmenuContext } from '../../contexts/submenu-context.js'\nimport type { PopupMenuRootActions } from '../../hooks/use-popup-menu-root.js'\n\nexport interface PopupMenuSubmenuRootProps\n extends Omit<\n PopoverRootProps,\n 'open' | 'onOpenChange' | 'defaultOpen' | 'actionsRef'\n > {\n /**\n * Whether the submenu is open.\n * Use for controlled mode.\n */\n open?: boolean\n\n /**\n * Callback when the open state changes.\n * The second parameter contains event details including the reason for the change.\n */\n onOpenChange?: (\n open: boolean,\n eventDetails: Popover.Root.ChangeEventDetails,\n ) => void\n\n /**\n * Whether the submenu is initially open.\n * Use for uncontrolled mode.\n * @default false\n */\n defaultOpen?: boolean\n\n /**\n * Whether pressing Escape in this submenu closes the entire menu from the root.\n * When true (default), Escape closes the entire menu tree.\n * When false, Escape only closes this submenu and moves focus to the parent.\n * @default true\n */\n closeRootOnEsc?: boolean\n\n /**\n * Whether virtualization mode is enabled for this submenu.\n * When true, items should provide an explicit `index` prop and\n * the `items` prop should be provided for navigation to work correctly.\n * @default false\n */\n virtualized?: boolean\n\n /**\n * Pre-registered items for virtualization.\n * When provided with `virtualized={true}`, this allows navigation to work\n * for items that aren't currently mounted in the DOM.\n */\n items?: VirtualItem[]\n\n /**\n * Callback when the highlighted item changes.\n * Useful for synchronizing with a virtualizer (e.g., scrollToIndex).\n */\n onHighlightChange?: (id: string | null, index: number) => void\n\n /**\n * Event handler called after any open/close animations have completed.\n * When `clearSearchOnClose=\"after-exit\"` is set on Surface, the search\n * will be cleared before this callback is invoked.\n */\n onOpenChangeComplete?: (open: boolean) => void\n\n /**\n * Whether this submenu should ignore user interaction.\n * Also inherits disabled state from its parent menu.\n * @default false\n */\n disabled?: boolean\n\n /**\n * A ref to imperative actions.\n * - `close`: closes the submenu imperatively.\n * - `unmount`: unmounts the popup imperatively (when keep-mounted mode is enabled).\n * - `setDisabled`: enables/disables the submenu imperatively.\n */\n actionsRef?: React.RefObject<PopupMenuSubmenuRoot.Actions | null>\n\n children: React.ReactNode\n}\n\n/**\n * Groups all parts of a submenu.\n * Manages open state and provides context to children.\n * Creates its own ListboxStore independent from the parent menu.\n * Doesn't render its own HTML element.\n */\nexport function PopupMenuSubmenuRoot(props: PopupMenuSubmenuRootProps) {\n const {\n open: openProp,\n onOpenChange,\n defaultOpen = false,\n closeRootOnEsc = true,\n virtualized = false,\n items: itemsProp,\n onHighlightChange,\n onOpenChangeComplete: onOpenChangeCompleteProp,\n disabled: disabledProp = false,\n actionsRef,\n children,\n ...rest\n } = props\n\n const parentListboxContext = useMaybeListboxContext()\n const parentPopupMenuContext = useMaybePopupMenuContext()\n const parentDepth = parentListboxContext?.depth ?? 0\n const parentCloseAll = parentListboxContext?.closeAll\n const parentRegisterSurface = parentListboxContext?.registerSurface\n\n // Get parent surface ID for keyboard navigation back\n const { surfaceId: parentSurfaceId } = useSurfaceContext()\n\n // Generate unique surface ID for this submenu\n const childSurfaceId = React.useId()\n\n // Ref for trigger element\n const triggerRef = React.useRef<HTMLElement | null>(null)\n // Ref for submenu content element (used for aim guard rect calculations)\n const contentRef = React.useRef<HTMLElement | null>(null)\n\n // Create the store instance for this submenu\n const store = ListboxStore.useStore(undefined, { open: defaultOpen })\n\n const [imperativeDisabled, setImperativeDisabled] = React.useState(false)\n const disabled =\n (parentPopupMenuContext?.disabled ?? false) ||\n disabledProp ||\n imperativeDisabled\n\n const setDisabled = React.useCallback((nextDisabled: boolean) => {\n setImperativeDisabled(nextDisabled)\n }, [])\n\n const setOpen = React.useCallback(\n (newOpen: boolean) => {\n if (newOpen && disabled) {\n return\n }\n store.setOpen(newOpen)\n },\n [store, disabled],\n )\n\n // Sync controlled open prop to store\n store.useControlledProp('open', openProp, defaultOpen)\n\n // Get open chain store\n const openChainStore = useOpenChain()\n\n // Get open state from store for Popover\n const open = store.useState('open')\n\n // Track this submenu in the open chain\n React.useEffect(() => {\n if (open) {\n openChainStore.open(childSurfaceId)\n } else {\n openChainStore.close(childSurfaceId)\n }\n }, [open, childSurfaceId, openChainStore])\n\n // Handle Popover's onOpenChange to update the store and call user's callback\n const handlePopoverOpenChange = React.useCallback(\n (newOpen: boolean, eventDetails: Popover.Root.ChangeEventDetails) => {\n // Call user's onOpenChange first so they can cancel\n onOpenChange?.(newOpen, eventDetails)\n\n // If the user cancelled, don't update the store\n if (eventDetails.isCanceled) {\n return\n }\n\n setOpen(newOpen)\n },\n [setOpen, onOpenChange],\n )\n\n // Handle animation complete - clear search and hide input if clearSearchOnClose is 'after-exit'\n const handleOpenChangeComplete = React.useCallback(\n (nextOpen: boolean) => {\n // Clear search and hide input after exit animation completes\n if (!nextOpen && store.context.clearSearchOnClose === 'after-exit') {\n store.clearSearch()\n store.setInputActive(false)\n }\n // Reset row width measurements after close animation completes\n if (!nextOpen) {\n store.context.onCloseComplete?.()\n store.context.onPopupCloseComplete?.()\n }\n // Call user's callback\n onOpenChangeCompleteProp?.(nextOpen)\n },\n [store, onOpenChangeCompleteProp],\n )\n\n // Close submenu when parent menu closes\n // We track parent open state to close the submenu when parent closes\n const [parentOpen, setParentOpen] = React.useState(true)\n\n React.useEffect(() => {\n if (!parentListboxContext) return\n\n const parentStore = parentListboxContext.store\n // Poll the parent store's open state\n const checkParentOpen = () => {\n const isOpen = parentStore.state.open\n setParentOpen(isOpen)\n }\n\n // Check immediately\n checkParentOpen()\n\n // Subscribe to state changes by observing the store\n // We use observe method which is called when state changes\n const unsubscribe = parentStore.observe('open', checkParentOpen)\n\n return unsubscribe\n }, [parentListboxContext])\n\n React.useEffect(() => {\n if (!parentOpen) {\n setOpen(false)\n }\n }, [parentOpen, setOpen])\n\n // Register this submenu with the root for closeAll tracking\n const depth = parentDepth + 1\n React.useEffect(() => {\n if (!parentRegisterSurface) return\n return parentRegisterSurface(depth, (newOpen) => setOpen(newOpen))\n }, [parentRegisterSurface, depth, setOpen])\n\n const popoverActionsRef = React.useRef<Popover.Root.Actions | null>(null)\n\n React.useImperativeHandle(\n actionsRef,\n () => ({\n close: () => {\n popoverActionsRef.current?.close()\n },\n unmount: () => {\n popoverActionsRef.current?.unmount()\n },\n setDisabled,\n }),\n [setDisabled],\n )\n\n // Submenu context value\n const submenuContextValue = React.useMemo(\n () => ({\n open,\n setOpen,\n triggerRef,\n contentRef,\n parentSurfaceId,\n childSurfaceId,\n closeRootOnEsc,\n }),\n [open, setOpen, parentSurfaceId, childSurfaceId, closeRootOnEsc],\n )\n\n // Fallback registerSurface for edge cases (submenu without parent root)\n const fallbackRegisterSurface = React.useCallback(() => () => {}, [])\n\n // Memoize listbox wiring config for this submenu\n const virtualization = React.useMemo(() => {\n if (!virtualized && !onHighlightChange) {\n return undefined\n }\n\n return {\n virtualized,\n items: itemsProp ?? [],\n onHighlightChange,\n }\n }, [virtualized, itemsProp, onHighlightChange])\n\n // Listbox context value with incremented depth\n // Pass parent's closeAll and registerSurface through unchanged\n const listboxContextValue = React.useMemo(\n () => ({\n store,\n depth,\n closeAll: parentCloseAll ?? (() => store.setOpen(false)),\n registerSurface: parentRegisterSurface ?? fallbackRegisterSurface,\n virtualization,\n }),\n [\n store,\n depth,\n parentCloseAll,\n parentRegisterSurface,\n fallbackRegisterSurface,\n virtualization,\n ],\n )\n\n // PopupMenu context value with incremented depth\n // This is needed for PopupMenuPositioner to get the correct depth\n const popupMenuContextValue = React.useMemo(\n () => ({\n store,\n disabled,\n depth,\n closeAll: parentCloseAll ?? (() => setOpen(false)),\n registerSurface: parentRegisterSurface ?? fallbackRegisterSurface,\n virtualization,\n virtualAnchor: parentPopupMenuContext?.virtualAnchor,\n menuType: parentPopupMenuContext?.menuType ?? ('dropdown' as const),\n closeOnOutsidePress:\n parentPopupMenuContext?.closeOnOutsidePress ?? 'pointerdown',\n getQualifiedRowId: parentPopupMenuContext?.getQualifiedRowId,\n }),\n [\n store,\n disabled,\n depth,\n parentCloseAll,\n parentRegisterSurface,\n setOpen,\n fallbackRegisterSurface,\n virtualization,\n parentPopupMenuContext?.virtualAnchor,\n parentPopupMenuContext?.menuType,\n parentPopupMenuContext?.closeOnOutsidePress,\n parentPopupMenuContext?.getQualifiedRowId,\n ],\n )\n\n return (\n <SubmenuContext.Provider value={submenuContextValue}>\n <PopupMenuContext.Provider value={popupMenuContextValue}>\n <ListboxContextProvider.Provider value={listboxContextValue}>\n <Popover.Root\n {...rest}\n open={open}\n onOpenChange={handlePopoverOpenChange}\n onOpenChangeComplete={handleOpenChangeComplete}\n actionsRef={actionsRef ? popoverActionsRef : undefined}\n >\n {children}\n </Popover.Root>\n </ListboxContextProvider.Provider>\n </PopupMenuContext.Provider>\n </SubmenuContext.Provider>\n )\n}\n\nexport namespace PopupMenuSubmenuRoot {\n export interface Props extends PopupMenuSubmenuRootProps {}\n export type ChangeEventDetails = Popover.Root.ChangeEventDetails\n export type Actions = PopupMenuRootActions\n}\n","'use client'\n\nimport { Popover } from '@base-ui/react/popover'\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n ItemContext,\n useListboxContext,\n useSurfaceContext,\n} from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { usePopupMenuDebug } from '../../contexts/popup-menu-debug-context.js'\nimport { useSubmenuContext } from '../../contexts/submenu-context.js'\nimport { useAimGuard } from '../../hooks/use-aim-guard.js'\nimport { usePopupMenuItem } from '../../hooks/use-popup-menu-item.js'\nimport {\n type AnchorSide,\n getSmoothedHeading,\n resolveAnchorSide,\n willHitSubmenu,\n} from '../../utils/aim-guard.js'\nimport { isMouseLikePointerType } from '../../utils/is-mouse-like-pointer.js'\nimport { useMouseTrail } from '../../utils/use-mouse-trail.js'\nimport {\n PopupMenuSubmenuSafeTriangleArea,\n type PopupMenuSubmenuSafeTriangleTone,\n} from './submenu-safe-triangle-area.js'\nimport { PopupMenuSubmenuTriggerDataAttributes } from './submenu-trigger-indicator.js'\n\nexport interface PopupMenuSubmenuTriggerState extends Record<string, unknown> {\n /**\n * Whether this is a submenu trigger (always true).\n */\n submenuTrigger: boolean\n /**\n * Whether the submenu popup is open.\n */\n popupOpen: boolean\n /**\n * Whether the submenu owns keyboard focus.\n */\n popupFocused: boolean\n /**\n * Whether the item is highlighted.\n */\n highlighted: boolean\n /**\n * Whether the item is disabled.\n */\n disabled: boolean\n}\n\n// Custom mapping to convert state to kebab-case data attributes\nconst stateAttributesMapping = {\n submenuTrigger: (value: unknown) =>\n value\n ? { [PopupMenuSubmenuTriggerDataAttributes.submenuTrigger]: '' }\n : null,\n popupOpen: (value: unknown) =>\n value ? { [PopupMenuSubmenuTriggerDataAttributes.popupOpen]: '' } : null,\n popupFocused: (value: unknown) =>\n value ? { [PopupMenuSubmenuTriggerDataAttributes.popupFocused]: '' } : null,\n highlighted: (value: unknown) =>\n value ? { [PopupMenuSubmenuTriggerDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown) =>\n value ? { [PopupMenuSubmenuTriggerDataAttributes.disabled]: '' } : null,\n}\n\nexport interface PopupMenuSubmenuTriggerProps\n extends ComponentProps<'div', PopupMenuSubmenuTrigger.State> {\n /**\n * Explicit unique identifier for this item in the store.\n * When provided (e.g., from data-first API's computed composite ID),\n * this takes priority over `value` for store registration.\n */\n id?: string\n\n /**\n * Unique value for this item used for filtering.\n * If not provided, will be inferred from textContent.\n */\n value?: string\n\n /**\n * Additional keywords to match against when filtering.\n * Useful for aliases or synonyms.\n */\n keywords?: string[]\n\n /**\n * Whether this item is disabled.\n * Disabled items are not selectable and are skipped during keyboard navigation.\n */\n disabled?: boolean\n\n /**\n * Whether to force render this item regardless of filter results.\n * @default false\n */\n forceMount?: boolean\n\n /**\n * Whether the submenu opens when this trigger is highlighted.\n * @default true\n */\n openOnHighlight?: boolean\n\n /**\n * Delay before opening the submenu (in milliseconds).\n * Can be a number (applies to both pointer and keyboard) or an object\n * with separate `pointer` and `keyboard` values.\n * @default { pointer: 0, keyboard: 150 }\n */\n delay?: number | { pointer?: number; keyboard?: number }\n\n /**\n * Delay before closing the submenu when pointer leaves (in milliseconds).\n * @default 0\n */\n closeDelay?: number\n\n /**\n * Forces this row's relative order during score-based sorting.\n * Lower values appear earlier.\n * @default 0\n */\n forceOrder?: number\n\n /**\n * Overrides this row's computed fuzzy-match score.\n */\n forceScore?: number\n}\n\ntype SubmenuSafeTriangleDebugState = 'hidden' | 'hover' | 'activated' | 'missed'\n\ninterface SubmenuSafeTriangleDebugSnapshot {\n contentRect: DOMRect\n triggerRect: DOMRect | null\n pointerX: number\n pointerY: number\n}\n\n/**\n * A menu item that opens a submenu when hovered.\n * Must be used within PopupMenu.Submenu.\n * Renders a `<div>` element with role=\"menuitem\" wrapped in Popover.Trigger.\n */\nexport const PopupMenuSubmenuTrigger = React.forwardRef<\n HTMLDivElement,\n PopupMenuSubmenuTrigger.Props\n>(function PopupMenuSubmenuTrigger(props, forwardedRef) {\n const {\n id: idProp,\n value,\n keywords,\n disabled: disabledProp = false,\n forceMount = false,\n openOnHighlight = true,\n delay: delayProp,\n closeDelay = 0,\n forceOrder,\n forceScore,\n render,\n className,\n style,\n onPointerDown,\n onPointerMove,\n onPointerEnter,\n onPointerLeave,\n children,\n ...rest\n } = props\n\n // Normalize delay prop to { pointer, keyboard } format\n const delay = React.useMemo(() => {\n if (typeof delayProp === 'number') {\n return { pointer: delayProp, keyboard: delayProp }\n }\n return {\n pointer: delayProp?.pointer ?? 0,\n keyboard: delayProp?.keyboard ?? 150,\n }\n }, [delayProp])\n\n // Get parent menu's store (from Surface context)\n const { store: parentStore } = useSurfaceContext()\n\n // Get depth from listbox context (this is the submenu's depth, parent is depth - 1)\n const { depth } = useListboxContext()\n const parentDepth = depth - 1\n\n // Get submenu context for open state and refs\n const submenuContext = useSubmenuContext()\n const { open, setOpen, triggerRef, contentRef, childSurfaceId } =\n submenuContext\n\n // Timer for delayed opening (pointer / keyboard navigation)\n const openTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n // Timer for delayed close on pointer leave misses\n const closeTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n const leaveMonitorCleanupRef = React.useRef<(() => void) | null>(null)\n const leaveMonitorTimerRef = React.useRef<ReturnType<\n typeof setTimeout\n > | null>(null)\n\n const clearOpenTimer = React.useCallback(() => {\n if (openTimerRef.current !== null) {\n clearTimeout(openTimerRef.current)\n openTimerRef.current = null\n }\n }, [])\n\n const clearCloseTimer = React.useCallback(() => {\n if (closeTimerRef.current !== null) {\n clearTimeout(closeTimerRef.current)\n closeTimerRef.current = null\n }\n }, [])\n\n const scheduleClose = React.useCallback(() => {\n clearCloseTimer()\n\n if (closeDelay <= 0) {\n setOpen(false)\n return\n }\n\n closeTimerRef.current = setTimeout(() => {\n closeTimerRef.current = null\n setOpen(false)\n }, closeDelay)\n }, [clearCloseTimer, closeDelay, setOpen])\n\n const clearLeaveMonitor = React.useCallback(() => {\n if (leaveMonitorCleanupRef.current) {\n leaveMonitorCleanupRef.current()\n leaveMonitorCleanupRef.current = null\n }\n\n if (leaveMonitorTimerRef.current !== null) {\n clearTimeout(leaveMonitorTimerRef.current)\n leaveMonitorTimerRef.current = null\n }\n }, [])\n\n // Cleanup timer on unmount\n React.useEffect(() => {\n return () => {\n clearOpenTimer()\n clearCloseTimer()\n clearLeaveMonitor()\n }\n }, [clearOpenTimer, clearCloseTimer, clearLeaveMonitor])\n\n // Track if submenu was just closed while highlighted (e.g. ArrowLeft back)\n // to suppress the keyboard auto-open until highlight leaves and returns\n const suppressAutoOpenRef = React.useRef(false)\n\n // Get focus owner store for keyboard focus transfer\n const focusOwnerStore = useFocusOwner()\n\n // Get aim guard for safe polygon navigation\n const {\n aimGuardActive,\n guardedTriggerId,\n guardedDepth,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n guardedDepthRef,\n activateAimGuard,\n clearAimGuard,\n } = useAimGuard()\n\n // Track mouse positions for aim guard trajectory calculation\n const mouseTrailRef = useMouseTrail(4)\n\n const { showSafeTriangleArea, logAimGuardEvents } = usePopupMenuDebug()\n const showSafeTriangleAreaEnabled = showSafeTriangleArea.enabled\n const [submenuSafeTriangleDebugState, setSubmenuSafeTriangleDebugState] =\n React.useState<SubmenuSafeTriangleDebugState>('hidden')\n const [\n submenuSafeTriangleDebugSnapshot,\n setSubmenuSafeTriangleDebugSnapshot,\n ] = React.useState<SubmenuSafeTriangleDebugSnapshot | null>(null)\n const missSafeTriangleTimerRef = React.useRef<ReturnType<\n typeof setTimeout\n > | null>(null)\n\n // Use the shared item hook for registration, visibility, and highlight state\n // When id is provided (e.g., from data-first API), it takes priority for store registration\n const item = usePopupMenuItem({\n id: idProp,\n value,\n keywords,\n disabled: disabledProp,\n forceMount,\n forceOrder,\n forceScore,\n isSubmenuTrigger: true,\n closeOnClick: false, // Submenu triggers don't close the menu\n children,\n })\n\n const disabled = item.disabled\n\n const logAimTrace = React.useCallback(\n (eventName: string, details?: Record<string, unknown>) => {\n if (!logAimGuardEvents) {\n return\n }\n\n console.log(`[PopupMenu][AimGuard] ${eventName}`, {\n triggerId: item.id,\n triggerStoreId: item.storeId,\n parentDepth,\n aimGuardActive: aimGuardActiveRef.current,\n guardedTriggerId: guardedTriggerIdRef.current,\n guardedDepth: guardedDepthRef.current,\n ...details,\n })\n },\n [\n logAimGuardEvents,\n item.id,\n item.storeId,\n parentDepth,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n guardedDepthRef,\n ],\n )\n\n const clearMissSafeTriangleTimer = React.useCallback(() => {\n if (missSafeTriangleTimerRef.current !== null) {\n clearTimeout(missSafeTriangleTimerRef.current)\n missSafeTriangleTimerRef.current = null\n }\n }, [])\n\n React.useEffect(\n () => clearMissSafeTriangleTimer,\n [clearMissSafeTriangleTimer],\n )\n\n const showActivatedSafeTriangle = React.useCallback(\n (snapshot: SubmenuSafeTriangleDebugSnapshot) => {\n if (!showSafeTriangleAreaEnabled) {\n return\n }\n\n clearMissSafeTriangleTimer()\n\n if (showSafeTriangleArea.freezeOnPointerLeave) {\n setSubmenuSafeTriangleDebugSnapshot(snapshot)\n } else {\n setSubmenuSafeTriangleDebugSnapshot(null)\n }\n\n setSubmenuSafeTriangleDebugState('activated')\n },\n [\n showSafeTriangleAreaEnabled,\n showSafeTriangleArea.freezeOnPointerLeave,\n clearMissSafeTriangleTimer,\n ],\n )\n\n const showMissedSafeTriangle = React.useCallback(\n (snapshot: SubmenuSafeTriangleDebugSnapshot) => {\n clearMissSafeTriangleTimer()\n\n if (!showSafeTriangleAreaEnabled || !showSafeTriangleArea.showMissState) {\n setSubmenuSafeTriangleDebugState('hidden')\n setSubmenuSafeTriangleDebugSnapshot(null)\n return\n }\n\n setSubmenuSafeTriangleDebugState('missed')\n setSubmenuSafeTriangleDebugSnapshot(snapshot)\n\n const hideAfter = showSafeTriangleArea.missFreezeDuration\n if (hideAfter <= 0) {\n setSubmenuSafeTriangleDebugState('hidden')\n setSubmenuSafeTriangleDebugSnapshot(null)\n return\n }\n\n missSafeTriangleTimerRef.current = setTimeout(() => {\n missSafeTriangleTimerRef.current = null\n setSubmenuSafeTriangleDebugState('hidden')\n setSubmenuSafeTriangleDebugSnapshot(null)\n }, hideAfter)\n },\n [\n clearMissSafeTriangleTimer,\n showSafeTriangleAreaEnabled,\n showSafeTriangleArea.showMissState,\n showSafeTriangleArea.missFreezeDuration,\n ],\n )\n\n const startLeaveMonitor = React.useCallback(\n (\n anchor: AnchorSide,\n triggerRect: DOMRect | null,\n initialHit: boolean,\n timeoutMs: number,\n initialPointerX: number,\n initialPointerY: number,\n ) => {\n clearLeaveMonitor()\n\n logAimTrace('leave-monitor-start', {\n anchor,\n initialHit,\n timeoutMs,\n closeDelay,\n triggerRect,\n initialPointerX,\n initialPointerY,\n })\n\n if (timeoutMs <= 0) {\n logAimTrace('leave-monitor-skip-timeout', { timeoutMs })\n return\n }\n\n let lastHit = initialHit\n let previousPointerX = initialPointerX\n let previousPointerY = initialPointerY\n\n const onWindowPointerMove = (pointerEvent: PointerEvent) => {\n if (!isMouseLikePointerType(pointerEvent.pointerType)) {\n return\n }\n\n const contentRect = contentRef.current?.getBoundingClientRect()\n if (!contentRect) {\n logAimTrace('leave-monitor-stop-no-content-rect')\n clearLeaveMonitor()\n return\n }\n\n const { clientX, clientY } = pointerEvent\n const isInsidePopup =\n clientX >= contentRect.left &&\n clientX <= contentRect.right &&\n clientY >= contentRect.top &&\n clientY <= contentRect.bottom\n\n const axisDelta =\n anchor === 'left' || anchor === 'right'\n ? clientX - previousPointerX\n : clientY - previousPointerY\n\n previousPointerX = clientX\n previousPointerY = clientY\n\n if (isInsidePopup) {\n logAimTrace('leave-monitor-inside-popup', {\n clientX,\n clientY,\n })\n clearCloseTimer()\n clearLeaveMonitor()\n return\n }\n\n const movedAwayFromSubmenu =\n (anchor === 'left' && axisDelta <= -2) ||\n (anchor === 'right' && axisDelta >= 2) ||\n (anchor === 'top' && axisDelta <= -2) ||\n (anchor === 'bottom' && axisDelta >= 2)\n\n logAimTrace('leave-monitor-pointermove', {\n anchor,\n clientX,\n clientY,\n axisDelta,\n movedAwayFromSubmenu,\n lastHit,\n })\n\n if (lastHit && movedAwayFromSubmenu) {\n const debugSnapshot: SubmenuSafeTriangleDebugSnapshot = {\n contentRect,\n triggerRect,\n pointerX: clientX,\n pointerY: clientY,\n }\n\n lastHit = false\n logAimTrace('leave-monitor-reversal-close', {\n anchor,\n clientX,\n clientY,\n axisDelta,\n })\n showMissedSafeTriangle(debugSnapshot)\n clearAimGuard()\n scheduleClose()\n\n if (closeDelay <= 0) {\n clearLeaveMonitor()\n }\n\n return\n }\n\n const heading = getSmoothedHeading(\n mouseTrailRef.current,\n clientX,\n clientY,\n anchor,\n triggerRect,\n contentRect,\n )\n\n const hit = willHitSubmenu(\n clientX,\n clientY,\n heading,\n contentRect,\n anchor,\n triggerRect,\n )\n\n logAimTrace('leave-monitor-hit-eval', {\n anchor,\n clientX,\n clientY,\n hit,\n lastHit,\n heading,\n })\n\n if (hit === lastHit) {\n return\n }\n\n const debugSnapshot: SubmenuSafeTriangleDebugSnapshot = {\n contentRect,\n triggerRect,\n pointerX: clientX,\n pointerY: clientY,\n }\n\n lastHit = hit\n\n if (hit) {\n logAimTrace('leave-monitor-hit-transition', {\n anchor,\n clientX,\n clientY,\n })\n showActivatedSafeTriangle(debugSnapshot)\n clearCloseTimer()\n activateAimGuard(item.id, parentDepth, childSurfaceId, 600)\n parentStore.setHighlightedId(item.storeId)\n setOpen(true)\n return\n }\n\n logAimTrace('leave-monitor-miss-transition', {\n anchor,\n clientX,\n clientY,\n })\n showMissedSafeTriangle(debugSnapshot)\n clearAimGuard()\n scheduleClose()\n\n if (closeDelay <= 0) {\n clearLeaveMonitor()\n }\n }\n\n window.addEventListener('pointermove', onWindowPointerMove, {\n passive: true,\n })\n\n leaveMonitorCleanupRef.current = () => {\n logAimTrace('leave-monitor-cleanup-remove-listener')\n window.removeEventListener('pointermove', onWindowPointerMove)\n }\n\n leaveMonitorTimerRef.current = setTimeout(() => {\n leaveMonitorTimerRef.current = null\n logAimTrace('leave-monitor-timeout-expired', { timeoutMs })\n clearLeaveMonitor()\n }, timeoutMs)\n },\n [\n clearLeaveMonitor,\n logAimTrace,\n contentRef,\n clearCloseTimer,\n mouseTrailRef,\n showActivatedSafeTriangle,\n activateAimGuard,\n item.id,\n parentDepth,\n childSurfaceId,\n parentStore,\n item.storeId,\n setOpen,\n showMissedSafeTriangle,\n clearAimGuard,\n scheduleClose,\n closeDelay,\n ],\n )\n\n React.useEffect(() => {\n if (showSafeTriangleAreaEnabled) {\n return\n }\n\n clearMissSafeTriangleTimer()\n setSubmenuSafeTriangleDebugState('hidden')\n setSubmenuSafeTriangleDebugSnapshot(null)\n }, [showSafeTriangleAreaEnabled, clearMissSafeTriangleTimer])\n\n React.useEffect(() => {\n if (\n !showSafeTriangleAreaEnabled ||\n showSafeTriangleArea.persistOnSuccess ||\n submenuSafeTriangleDebugState !== 'activated'\n ) {\n return\n }\n\n const isGuardActiveForThisTrigger =\n aimGuardActive &&\n guardedTriggerId === item.id &&\n guardedDepth === parentDepth\n\n if (!isGuardActiveForThisTrigger) {\n clearMissSafeTriangleTimer()\n setSubmenuSafeTriangleDebugState('hidden')\n setSubmenuSafeTriangleDebugSnapshot(null)\n }\n }, [\n showSafeTriangleAreaEnabled,\n showSafeTriangleArea.persistOnSuccess,\n submenuSafeTriangleDebugState,\n aimGuardActive,\n guardedTriggerId,\n guardedDepth,\n item.id,\n parentDepth,\n clearMissSafeTriangleTimer,\n ])\n\n React.useEffect(() => {\n if (submenuSafeTriangleDebugState !== 'activated' || open) {\n return\n }\n\n clearMissSafeTriangleTimer()\n setSubmenuSafeTriangleDebugState('hidden')\n setSubmenuSafeTriangleDebugSnapshot(null)\n }, [submenuSafeTriangleDebugState, open, clearMissSafeTriangleTimer])\n\n React.useEffect(() => {\n if (!open) {\n clearCloseTimer()\n clearLeaveMonitor()\n }\n }, [open, clearCloseTimer, clearLeaveMonitor])\n\n React.useEffect(() => {\n if (\n open ||\n !aimGuardActiveRef.current ||\n guardedTriggerIdRef.current !== item.id ||\n guardedDepthRef.current !== parentDepth\n ) {\n return\n }\n\n clearAimGuard()\n }, [\n open,\n item.id,\n parentDepth,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n guardedDepthRef,\n clearAimGuard,\n ])\n\n React.useEffect(() => {\n if (\n item.isVisible ||\n !aimGuardActiveRef.current ||\n guardedTriggerIdRef.current !== item.id ||\n guardedDepthRef.current !== parentDepth\n ) {\n return\n }\n\n clearAimGuard()\n }, [\n item.isVisible,\n item.id,\n parentDepth,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n guardedDepthRef,\n clearAimGuard,\n ])\n\n React.useEffect(() => {\n return () => {\n if (\n aimGuardActiveRef.current &&\n guardedTriggerIdRef.current === item.id &&\n guardedDepthRef.current === parentDepth\n ) {\n clearAimGuard()\n }\n }\n }, [\n item.id,\n parentDepth,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n guardedDepthRef,\n clearAimGuard,\n ])\n\n React.useEffect(() => {\n if (!open) {\n return\n }\n\n const contentEl = contentRef.current\n if (!contentEl) {\n return\n }\n\n const handlePointerEnterContent = () => {\n clearCloseTimer()\n clearLeaveMonitor()\n }\n\n const handlePointerMoveContent = () => {\n clearCloseTimer()\n clearLeaveMonitor()\n }\n\n contentEl.addEventListener('pointerenter', handlePointerEnterContent)\n contentEl.addEventListener('pointermove', handlePointerMoveContent, {\n passive: true,\n })\n\n return () => {\n contentEl.removeEventListener('pointerenter', handlePointerEnterContent)\n contentEl.removeEventListener('pointermove', handlePointerMoveContent)\n }\n }, [open, contentRef, clearCloseTimer, clearLeaveMonitor])\n\n // Register submenu open callback with parent store\n // When submenu is opened via keyboard (ArrowRight/Ctrl+L), transfer focus ownership\n React.useEffect(() => {\n return parentStore.registerSubmenuOpen(item.storeId, () => {\n setOpen(true)\n // Transfer focus ownership to the submenu surface\n focusOwnerStore.setOwnerId(childSurfaceId)\n // Auto-focus after DOM is ready\n requestAnimationFrame(() => {\n const input = contentRef.current?.querySelector('input')\n const list = contentRef.current?.querySelector('[role=\"listbox\"]')\n const focusTarget = input ?? list\n if (focusTarget && focusTarget instanceof HTMLElement) {\n focusTarget.focus()\n }\n })\n })\n }, [\n item.storeId,\n parentStore,\n setOpen,\n focusOwnerStore,\n childSurfaceId,\n contentRef,\n ])\n\n // Register submenu close callback with parent store\n // This allows the store to close this submenu when another item is highlighted\n React.useEffect(() => {\n return parentStore.registerSubmenuClose(item.storeId, () => setOpen(false))\n }, [item.storeId, parentStore, setOpen])\n\n // Check if this submenu owns keyboard focus\n const isPopupFocused = focusOwnerStore.useState('isOwner', childSurfaceId)\n\n // Close submenu when trigger becomes invisible (e.g., filtered out by search)\n // This prevents the popup from rendering without its anchor element\n React.useEffect(() => {\n if (!item.isVisible && open) {\n setOpen(false)\n }\n }, [item.isVisible, open, setOpen])\n\n // When submenu closes while this trigger is highlighted, suppress auto-open\n const prevOpenRef = React.useRef(open)\n React.useEffect(() => {\n if (prevOpenRef.current && !open && item.isHighlighted) {\n suppressAutoOpenRef.current = true\n }\n prevOpenRef.current = open\n }, [open, item.isHighlighted])\n\n // Reset suppression when highlight leaves this trigger\n React.useEffect(() => {\n if (!item.isHighlighted) {\n suppressAutoOpenRef.current = false\n }\n }, [item.isHighlighted])\n\n // When highlighted via keyboard, schedule open after keyboard delay\n // This effect only handles *navigation* highlight (ArrowUp/Down).\n // Explicit open actions (ArrowRight, Ctrl+L) bypass this by calling registerSubmenuOpen directly.\n React.useEffect(() => {\n // Skip if openOnHighlight is disabled\n if (!openOnHighlight) {\n return\n }\n\n // Only schedule open when highlighted via explicit keyboard navigation\n // Don't auto-open for 'auto' highlights (search results, initial open)\n if (\n !item.isHighlighted ||\n parentStore.state.highlightSource !== 'keyboard'\n ) {\n clearOpenTimer()\n return\n }\n\n // Don't auto-open if user just explicitly closed the submenu (e.g. ArrowLeft)\n if (suppressAutoOpenRef.current) {\n return\n }\n\n const keyboardDelay = delay.keyboard\n if (keyboardDelay <= 0) {\n setOpen(true)\n } else {\n openTimerRef.current = setTimeout(() => {\n openTimerRef.current = null\n setOpen(true)\n }, keyboardDelay)\n }\n\n return clearOpenTimer\n }, [\n item.isHighlighted,\n parentStore,\n delay.keyboard,\n setOpen,\n clearOpenTimer,\n openOnHighlight,\n ])\n\n // Set the trigger ref when element mounts\n React.useEffect(() => {\n ;(triggerRef as React.MutableRefObject<HTMLElement | null>).current =\n item.ref.current\n return () => {\n ;(triggerRef as React.MutableRefObject<HTMLElement | null>).current = null\n }\n }, [triggerRef, item.ref])\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n // Prevent focus from leaving the input\n event.preventDefault()\n\n if (open) {\n suppressAutoOpenRef.current = true\n logAimTrace('pointerdown-suppress-auto-open', {\n clientX: event.clientX,\n clientY: event.clientY,\n })\n }\n\n onPointerDown?.(event)\n },\n [open, logAimTrace, onPointerDown],\n )\n\n // Custom pointer move handler for submenu triggers\n // Different from usePopupMenuItem's handler: allows the guarded trigger to highlight itself\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event)\n\n if (event.defaultPrevented) return\n if (disabled) return\n if (!isMouseLikePointerType(event.pointerType)) return\n\n // Check if pointer has actually moved (prevents phantom highlights)\n if (\n !parentStore.shouldAllowPointerHighlight(event.clientX, event.clientY)\n ) {\n return\n }\n\n // Don't highlight if aim guard is active at this depth for a different trigger\n if (\n aimGuardActiveRef.current &&\n guardedDepthRef.current === parentDepth &&\n guardedTriggerIdRef.current !== item.id\n ) {\n logAimTrace('pointermove-blocked-by-guard', {\n clientX: event.clientX,\n clientY: event.clientY,\n blockedByTriggerId: guardedTriggerIdRef.current,\n })\n return\n }\n\n // Highlight on hover (use storeId for store operations)\n parentStore.setHighlightedId(item.storeId)\n\n // Pointer move can be the first allowed event after aim-guard unblocks\n // this row (e.g. pointerenter was blocked earlier), so allow it to open.\n if (!openOnHighlight || open) {\n return\n }\n\n if (suppressAutoOpenRef.current) {\n logAimTrace('pointermove-open-suppressed-after-explicit-close', {\n clientX: event.clientX,\n clientY: event.clientY,\n })\n return\n }\n\n clearLeaveMonitor()\n clearCloseTimer()\n\n const pointerDelay = delay.pointer\n if (pointerDelay <= 0) {\n setOpen(true)\n return\n }\n\n if (openTimerRef.current !== null) {\n return\n }\n\n openTimerRef.current = setTimeout(() => {\n openTimerRef.current = null\n setOpen(true)\n }, pointerDelay)\n },\n [\n onPointerMove,\n disabled,\n aimGuardActiveRef,\n guardedDepthRef,\n parentDepth,\n guardedTriggerIdRef,\n item.id,\n item.storeId,\n openOnHighlight,\n open,\n suppressAutoOpenRef,\n clearLeaveMonitor,\n clearCloseTimer,\n delay.pointer,\n setOpen,\n logAimTrace,\n parentStore,\n ],\n )\n\n const handlePointerEnter = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerEnter?.(event)\n\n if (event.defaultPrevented) return\n if (disabled) return\n if (!isMouseLikePointerType(event.pointerType)) return\n\n // Check if aim guard is blocking this trigger\n if (\n aimGuardActiveRef.current &&\n guardedDepthRef.current === parentDepth &&\n guardedTriggerIdRef.current !== item.id\n ) {\n logAimTrace('pointerenter-blocked-by-guard', {\n clientX: event.clientX,\n clientY: event.clientY,\n blockedByTriggerId: guardedTriggerIdRef.current,\n blockedByDepth: guardedDepthRef.current,\n })\n return\n }\n\n logAimTrace('pointerenter-submenu-trigger', {\n clientX: event.clientX,\n clientY: event.clientY,\n })\n\n if (showSafeTriangleAreaEnabled) {\n clearMissSafeTriangleTimer()\n setSubmenuSafeTriangleDebugSnapshot(null)\n setSubmenuSafeTriangleDebugState('hover')\n }\n\n // Highlight the trigger on pointer enter (use storeId for store operations)\n parentStore.setHighlightedId(item.storeId)\n\n // Skip submenu opening if openOnHighlight is disabled\n if (!openOnHighlight) return\n\n if (suppressAutoOpenRef.current) {\n logAimTrace('pointerenter-open-suppressed-after-explicit-close', {\n clientX: event.clientX,\n clientY: event.clientY,\n })\n return\n }\n\n // Clear any existing aim guard and schedule open with delay\n clearLeaveMonitor()\n clearAimGuard()\n clearOpenTimer()\n clearCloseTimer()\n\n const pointerDelay = delay.pointer\n if (pointerDelay <= 0) {\n setOpen(true)\n } else {\n openTimerRef.current = setTimeout(() => {\n openTimerRef.current = null\n setOpen(true)\n }, pointerDelay)\n }\n },\n [\n onPointerEnter,\n disabled,\n aimGuardActiveRef,\n guardedDepthRef,\n guardedTriggerIdRef,\n item.id,\n item.storeId,\n parentStore,\n openOnHighlight,\n suppressAutoOpenRef,\n clearLeaveMonitor,\n clearAimGuard,\n clearOpenTimer,\n clearCloseTimer,\n clearMissSafeTriangleTimer,\n showSafeTriangleAreaEnabled,\n delay.pointer,\n setOpen,\n logAimTrace,\n ],\n )\n\n const handlePointerLeave = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerLeave?.(event)\n\n if (event.defaultPrevented) return\n if (disabled) return\n if (!isMouseLikePointerType(event.pointerType)) return\n\n // Cancel any pending open timer\n clearOpenTimer()\n\n logAimTrace('pointerleave-submenu-trigger', {\n clientX: event.clientX,\n clientY: event.clientY,\n })\n\n // Check if aim guard is blocking this trigger\n if (\n aimGuardActiveRef.current &&\n guardedDepthRef.current === parentDepth &&\n guardedTriggerIdRef.current !== item.id\n ) {\n logAimTrace('pointerleave-blocked-by-guard', {\n clientX: event.clientX,\n clientY: event.clientY,\n blockedByTriggerId: guardedTriggerIdRef.current,\n blockedByDepth: guardedDepthRef.current,\n })\n return\n }\n\n // Get the submenu content rect for safe polygon calculation\n const contentRect = contentRef.current?.getBoundingClientRect()\n if (!contentRect) {\n logAimTrace('pointerleave-no-content-rect')\n clearLeaveMonitor()\n clearMissSafeTriangleTimer()\n setSubmenuSafeTriangleDebugState('hidden')\n setSubmenuSafeTriangleDebugSnapshot(null)\n clearAimGuard()\n scheduleClose()\n return\n }\n\n // Check if pointer is already inside the popup (can happen with fast movement or overlapping elements)\n const { clientX, clientY } = event\n\n // Get trigger rect for aim guard calculation\n const tRect = triggerRef.current?.getBoundingClientRect() ?? null\n const debugSnapshot: SubmenuSafeTriangleDebugSnapshot = {\n contentRect,\n triggerRect: tRect,\n pointerX: clientX,\n pointerY: clientY,\n }\n\n const isInsidePopup =\n clientX >= contentRect.left &&\n clientX <= contentRect.right &&\n clientY >= contentRect.top &&\n clientY <= contentRect.bottom\n\n if (isInsidePopup) {\n // Pointer is already in the popup, clear guard and keep open\n logAimTrace('pointerleave-inside-popup-success', {\n clientX,\n clientY,\n })\n showActivatedSafeTriangle(debugSnapshot)\n clearCloseTimer()\n clearLeaveMonitor()\n clearAimGuard()\n return\n }\n\n // Calculate safe polygon and check if user is aiming toward submenu\n const anchor = resolveAnchorSide(contentRect, tRect, clientX, clientY)\n const heading = getSmoothedHeading(\n mouseTrailRef.current,\n clientX,\n clientY,\n anchor,\n tRect,\n contentRect,\n )\n const hit = willHitSubmenu(\n clientX,\n clientY,\n heading,\n contentRect,\n anchor,\n tRect,\n )\n\n logAimTrace('pointerleave-hit-eval', {\n anchor,\n hit,\n clientX,\n clientY,\n heading,\n })\n\n if (hit) {\n // User is aiming at submenu - activate aim guard for 600ms\n // Guard is activated at parentDepth to block highlighting in the parent menu only\n logAimTrace('pointerleave-hit-activate-guard', {\n anchor,\n clientX,\n clientY,\n })\n showActivatedSafeTriangle(debugSnapshot)\n activateAimGuard(item.id, parentDepth, childSurfaceId, 600)\n parentStore.setHighlightedId(item.storeId)\n setOpen(true)\n startLeaveMonitor(anchor, tRect, true, 600, clientX, clientY)\n } else {\n // User is not aiming at submenu - close it\n logAimTrace('pointerleave-miss-close', {\n anchor,\n clientX,\n clientY,\n })\n showMissedSafeTriangle(debugSnapshot)\n clearAimGuard()\n scheduleClose()\n if (closeDelay > 0) {\n startLeaveMonitor(anchor, tRect, false, closeDelay, clientX, clientY)\n } else {\n clearLeaveMonitor()\n }\n }\n },\n [\n onPointerLeave,\n disabled,\n clearOpenTimer,\n aimGuardActiveRef,\n guardedDepthRef,\n guardedTriggerIdRef,\n item.id,\n item.storeId,\n closeDelay,\n contentRef,\n clearLeaveMonitor,\n clearMissSafeTriangleTimer,\n clearAimGuard,\n showActivatedSafeTriangle,\n showMissedSafeTriangle,\n setOpen,\n clearCloseTimer,\n scheduleClose,\n startLeaveMonitor,\n triggerRef,\n mouseTrailRef,\n activateAimGuard,\n parentDepth,\n childSurfaceId,\n parentStore,\n logAimTrace,\n ],\n )\n\n const state: PopupMenuSubmenuTrigger.State = React.useMemo(\n () => ({\n submenuTrigger: true,\n popupOpen: open,\n popupFocused: isPopupFocused,\n highlighted: item.isHighlighted,\n disabled,\n }),\n [open, isPopupFocused, item.isHighlighted, disabled],\n )\n\n // Wrap children with ItemContext.Provider so child components can access item state\n const wrappedChildren = (\n <ItemContext.Provider value={item.contextValue}>\n {children}\n </ItemContext.Provider>\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'submenu-trigger')\n\n // Use useRender to create the element with state-based data attributes\n const element = useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: item.id,\n role: 'menuitem',\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n tabIndex: -1,\n 'aria-disabled': disabled || undefined,\n className,\n style,\n onPointerMove: handlePointerMove,\n onPointerDown: handlePointerDown,\n onPointerEnter: handlePointerEnter,\n onPointerLeave: handlePointerLeave,\n children: wrappedChildren,\n },\n defaultTagName: 'div',\n })\n\n const safeTriangleTone: PopupMenuSubmenuSafeTriangleTone | null =\n React.useMemo(() => {\n if (submenuSafeTriangleDebugState === 'hover') {\n return 'hover'\n }\n\n if (submenuSafeTriangleDebugState === 'activated') {\n return 'activated'\n }\n\n if (submenuSafeTriangleDebugState === 'missed') {\n return 'missed'\n }\n\n return null\n }, [submenuSafeTriangleDebugState])\n\n const trigger = <Popover.Trigger nativeButton={false} render={element} />\n\n // Don't render if not visible\n if (!item.isVisible) return null\n\n if (!showSafeTriangleAreaEnabled || safeTriangleTone === null) {\n return trigger\n }\n\n return (\n <>\n {trigger}\n <PopupMenuSubmenuSafeTriangleArea\n config={showSafeTriangleArea}\n contentRef={contentRef}\n triggerRef={triggerRef}\n tone={safeTriangleTone}\n contentRectOverride={submenuSafeTriangleDebugSnapshot?.contentRect}\n triggerRectOverride={submenuSafeTriangleDebugSnapshot?.triggerRect}\n mousePointOverride={\n submenuSafeTriangleDebugSnapshot\n ? [\n submenuSafeTriangleDebugSnapshot.pointerX,\n submenuSafeTriangleDebugSnapshot.pointerY,\n ]\n : null\n }\n />\n </>\n )\n})\n\nexport namespace PopupMenuSubmenuTrigger {\n export type State = PopupMenuSubmenuTriggerState\n export interface Props extends PopupMenuSubmenuTriggerProps {}\n}\n","/**\n * On some Linux + Chromium setups, mouse inputs may report pointerType as \"pen\".\n */\nexport function isMouseLikePointerType(\n pointerType: string | undefined,\n strict = false,\n): boolean {\n const mouseLikeTypes: Array<string | undefined> = ['mouse', 'pen']\n\n if (!strict) {\n mouseLikeTypes.push('', undefined)\n }\n\n return mouseLikeTypes.includes(pointerType)\n}\n","'use client'\n\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\nimport type { PopupMenuSafeTriangleAreaDebugSettings } from '../../contexts/popup-menu-debug-context.js'\nimport { resolveAnchorSide } from '../../utils/aim-guard.js'\nimport { useMousePosition } from '../../utils/use-mouse-position.js'\n\nexport type PopupMenuSubmenuSafeTriangleTone = 'hover' | 'activated' | 'missed'\n\nexport interface PopupMenuSubmenuSafeTriangleAreaProps {\n config: PopupMenuSafeTriangleAreaDebugSettings\n contentRef: React.RefObject<HTMLElement | null>\n triggerRef: React.RefObject<HTMLElement | null>\n tone: PopupMenuSubmenuSafeTriangleTone\n contentRectOverride?: DOMRect | null\n triggerRectOverride?: DOMRect | null\n mousePointOverride?: [number, number] | null\n}\n\n/**\n * Visual-only debug triangle showing the submenu safe area.\n */\nexport function PopupMenuSubmenuSafeTriangleArea(\n props: PopupMenuSubmenuSafeTriangleAreaProps,\n) {\n const {\n config,\n contentRef,\n triggerRef,\n tone,\n contentRectOverride,\n triggerRectOverride,\n mousePointOverride,\n } = props\n const [liveMouseX, liveMouseY] = useMousePosition()\n\n const isCoarse = React.useMemo(\n () =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia('(pointer: coarse)').matches\n : false,\n [],\n )\n\n const contentElement = contentRef.current\n const rect = contentRectOverride ?? contentElement?.getBoundingClientRect()\n if (!rect || isCoarse || typeof document === 'undefined' || !document.body) {\n return null\n }\n\n const triggerRect =\n triggerRectOverride ??\n (triggerRef.current ? triggerRef.current.getBoundingClientRect() : null)\n\n const mouseX = mousePointOverride?.[0] ?? liveMouseX\n const mouseY = mousePointOverride?.[1] ?? liveMouseY\n\n const x = rect.left\n const y = rect.top\n const width = rect.width\n const height = rect.height\n\n if (!width || !height) {\n return null\n }\n\n const anchor = resolveAnchorSide(rect, triggerRect, mouseX, mouseY)\n\n if (anchor === 'top' || anchor === 'bottom') {\n return null\n }\n\n if (anchor === 'left' && mouseX >= x) {\n return null\n }\n\n if (anchor === 'right' && mouseX <= x + width) {\n return null\n }\n\n const inset = 2\n const yPct = Math.max(0, Math.min(100, ((mouseY - y) / height) * 100))\n\n const triangleWidth =\n anchor === 'left'\n ? Math.max(x - mouseX, 10) + inset\n : Math.max(mouseX - (x + width), 10) + inset\n\n const overlayOpacity = Math.max(0, Math.min(1, config.overlayOpacity))\n const triangleFillOpacity = Math.max(\n 0,\n Math.min(1, config.triangleFillOpacity),\n )\n\n const borderStrokeWidth = config.showStroke\n ? Math.max(0, config.strokeWidth)\n : 0\n const requestedDotRadius = config.showDots ? Math.max(0, config.dotRadius) : 0\n const maxAllowedInset = Math.max(1, Math.min(triangleWidth, height) / 2)\n\n // Keep stroke + dots inside the SVG viewport to avoid clipping.\n const borderInset = Math.min(\n Math.max(requestedDotRadius, borderStrokeWidth / 2) + 0.5,\n maxAllowedInset,\n )\n\n const cornerDotRadius = config.showDots\n ? Math.max(\n 0,\n Math.min(requestedDotRadius, borderInset - borderStrokeWidth / 2 - 0.5),\n )\n : 0\n\n const apexY = Math.max(\n borderInset,\n Math.min(height - borderInset, (yPct / 100) * height),\n )\n\n const left = anchor === 'left' ? x - triangleWidth : x + width\n\n let toneColor = config.idleColor\n if (tone === 'activated') {\n toneColor = config.successColor\n } else if (tone === 'missed') {\n toneColor = config.missColor\n }\n\n const trianglePoints: [[number, number], [number, number], [number, number]] =\n anchor === 'left'\n ? [\n [triangleWidth - borderInset, borderInset],\n [borderInset, apexY],\n [triangleWidth - borderInset, height - borderInset],\n ]\n : [\n [borderInset, borderInset],\n [borderInset, height - borderInset],\n [triangleWidth - borderInset, apexY],\n ]\n\n const polygonPoints = trianglePoints\n .map(([px, py]) => `${px},${py}`)\n .join(' ')\n\n const triangle = (\n <svg\n data-bazzaui-submenu-safe-triangle-area=\"\"\n data-safe-triangle-tone={tone}\n aria-hidden\n viewBox={`0 0 ${triangleWidth} ${height}`}\n style={{\n position: 'fixed',\n top: y,\n left,\n width: triangleWidth,\n height,\n pointerEvents: 'none',\n zIndex: Number.MAX_SAFE_INTEGER,\n transform: 'translateZ(0)',\n opacity: overlayOpacity,\n }}\n >\n <polygon\n points={polygonPoints}\n fill={toneColor}\n fillOpacity={triangleFillOpacity}\n stroke={config.showStroke ? toneColor : 'none'}\n strokeWidth={borderStrokeWidth}\n strokeDasharray={config.showStroke ? config.strokeDasharray : undefined}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n\n {config.showDots\n ? trianglePoints.map(([cx, cy]) => (\n <circle\n key={`${cx}-${cy}`}\n cx={cx}\n cy={cy}\n r={cornerDotRadius}\n fill={toneColor}\n />\n ))\n : null}\n </svg>\n )\n\n return createPortal(triangle, document.body)\n}\n","import * as React from 'react'\n\n/**\n * Tracks the current mouse coordinates.\n * Used by debug overlays that follow pointer position.\n */\nexport function useMousePosition(): [number, number] {\n const [position, setPosition] = React.useState<[number, number]>([0, 0])\n\n React.useEffect(() => {\n const onMove = (event: PointerEvent) => {\n setPosition([event.clientX, event.clientY])\n }\n\n window.addEventListener('pointermove', onMove, { passive: true })\n\n return () => {\n window.removeEventListener('pointermove', onMove)\n }\n }, [])\n\n return position\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { useSubmenuContext } from '../../contexts/submenu-context.js'\nimport { PopupMenuSubmenuTriggerDataAttributes } from './submenu-trigger.data-attrs.js'\n\nexport { PopupMenuSubmenuTriggerDataAttributes }\n\nexport interface PopupMenuSubmenuTriggerIndicatorState\n extends Record<string, unknown> {\n /**\n * Whether the submenu popup is open.\n */\n popupOpen: boolean\n /**\n * Whether the submenu owns keyboard focus.\n */\n popupFocused: boolean\n}\n\n// Custom mapping to convert state to kebab-case data attributes\nconst stateAttributesMapping = {\n popupOpen: (value: unknown) =>\n value ? { [PopupMenuSubmenuTriggerDataAttributes.popupOpen]: '' } : null,\n popupFocused: (value: unknown) =>\n value ? { [PopupMenuSubmenuTriggerDataAttributes.popupFocused]: '' } : null,\n}\n\nexport interface PopupMenuSubmenuTriggerIndicatorProps\n extends ComponentProps<'span', PopupMenuSubmenuTriggerIndicator.State> {}\n\n/**\n * An indicator element for submenu triggers that reflects the submenu's open and focus state.\n * Typically used to render a chevron or arrow icon.\n * Must be used within PopupMenu.SubmenuTrigger.\n * Renders a `<span>` element.\n */\nexport const PopupMenuSubmenuTriggerIndicator = React.forwardRef<\n HTMLSpanElement,\n PopupMenuSubmenuTriggerIndicator.Props\n>(function PopupMenuSubmenuTriggerIndicator(props, forwardedRef) {\n const { render, className, style, children, ...rest } = props\n\n // Get submenu context for open state\n const { open, childSurfaceId } = useSubmenuContext()\n\n // Get focus owner store to check if this submenu owns focus\n const focusOwnerStore = useFocusOwner()\n const isPopupFocused = focusOwnerStore.useState('isOwner', childSurfaceId)\n\n const state: PopupMenuSubmenuTriggerIndicator.State = React.useMemo(\n () => ({\n popupOpen: open,\n popupFocused: isPopupFocused,\n }),\n [open, isPopupFocused],\n )\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'submenu-trigger-indicator')\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n 'aria-hidden': true,\n className,\n style,\n children,\n },\n defaultTagName: 'span',\n })\n})\n\nexport namespace PopupMenuSubmenuTriggerIndicator {\n export type State = PopupMenuSubmenuTriggerIndicatorState\n export interface Props extends PopupMenuSubmenuTriggerIndicatorProps {}\n}\n","export enum PopupMenuSubmenuTriggerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-submenu-trigger' | 'bazzaui-context-menu-submenu-trigger'}\n */\n slot = 'bazzaui-[component]-submenu-trigger',\n /**\n * Present on submenu trigger elements.\n */\n submenuTrigger = 'data-submenu-trigger',\n /**\n * Present when the submenu popup is open.\n */\n popupOpen = 'data-popup-open',\n /**\n * Present when the submenu owns keyboard focus.\n */\n popupFocused = 'data-popup-focused',\n /**\n * Present when the item is highlighted.\n */\n highlighted = 'data-highlighted',\n /**\n * Present when the item is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport * as React from 'react'\nimport {\n ListboxContextProvider,\n ListboxStore,\n useMaybeListboxContext,\n} from '../../../listbox/index.js'\nimport {\n PopupMenuContext,\n useMaybePopupMenuContext,\n} from '../../contexts/popup-menu-context.js'\nimport { PopupSurfaceIdContext } from '../../contexts/popup-surface-id-context.js'\nimport { SubpageContext } from '../../contexts/subpage-context.js'\nimport {\n ROOT_SUBPAGE_ID,\n useSubpageStack,\n} from '../../contexts/subpage-stack-context.js'\n\nexport interface PopupMenuSubpageProps {\n /** Unique page ID for stack navigation. */\n pageId: string\n /**\n * Whether pressing Escape in this page closes the entire menu tree.\n * When false (default), Escape navigates back one page.\n * @default false\n */\n closeRootOnEsc?: boolean\n children: React.ReactNode\n}\n\n/**\n * Groups all parts of a subpage.\n * Creates an isolated menu surface that renders in the same popup and\n * participates in push/pop page stack navigation.\n * Doesn't render its own HTML element.\n */\nexport function PopupMenuSubpage(props: PopupMenuSubpageProps) {\n const { pageId, closeRootOnEsc = false, children } = props\n\n const parentListboxContext = useMaybeListboxContext()\n const parentPopupMenuContext = useMaybePopupMenuContext()\n const subpageStack = useSubpageStack()\n\n if (!parentListboxContext || !parentPopupMenuContext) {\n throw new Error('PopupMenu.Subpage must be used within PopupMenu.Popup')\n }\n\n if (pageId === ROOT_SUBPAGE_ID) {\n throw new Error(\n `PopupMenu.Subpage pageId \"${ROOT_SUBPAGE_ID}\" is reserved for the root page`,\n )\n }\n\n // Create an isolated store for this page.\n const store = ListboxStore.useStore(undefined, { open: false })\n\n // Surface ID used by this page's Surface/List/Input.\n const surfaceId = React.useId()\n\n // Parent popup open state.\n const parentOpen = parentListboxContext.store.useState('open')\n\n const activePageId = subpageStack.activePageId\n const stack = subpageStack.stack\n const registerPage = subpageStack.registerPage\n const goBack = subpageStack.goBack\n const getSurfaceId = subpageStack.getSurfaceId\n\n const isActive = activePageId === pageId\n\n // Register this page in the popup's page registry.\n React.useEffect(() => {\n return registerPage({\n pageId,\n surfaceId,\n closeRootOnEsc,\n })\n }, [registerPage, pageId, surfaceId, closeRootOnEsc])\n\n // Sync this page's store open state with popup open + page activity.\n React.useEffect(() => {\n store.setOpen(parentOpen && isActive)\n }, [store, parentOpen, isActive])\n\n // Register with root closeAll tracking.\n React.useEffect(() => {\n return parentListboxContext.registerSurface(\n parentListboxContext.depth,\n (nextOpen) => store.setOpen(nextOpen),\n )\n }, [parentListboxContext, store])\n\n const parentSurfaceId = React.useMemo(() => {\n const currentIndex = stack.lastIndexOf(pageId)\n\n if (currentIndex <= 0) {\n return getSurfaceId(ROOT_SUBPAGE_ID)\n }\n\n const previousPageId = stack[currentIndex - 1]\n return previousPageId ? getSurfaceId(previousPageId) : null\n }, [stack, pageId, getSurfaceId])\n\n const subpageContextValue = React.useMemo(\n () => ({\n pageId,\n surfaceId,\n parentSurfaceId,\n isActive,\n closeRootOnEsc,\n goBack,\n }),\n [pageId, surfaceId, parentSurfaceId, isActive, closeRootOnEsc, goBack],\n )\n\n const listboxContextValue = React.useMemo(\n () => ({\n store,\n depth: parentListboxContext.depth,\n closeAll: parentListboxContext.closeAll,\n registerSurface: parentListboxContext.registerSurface,\n virtualization: parentListboxContext.virtualization,\n }),\n [store, parentListboxContext],\n )\n\n const popupMenuContextValue = React.useMemo(\n () => ({\n store,\n depth: parentPopupMenuContext.depth,\n closeAll: parentPopupMenuContext.closeAll,\n registerSurface: parentPopupMenuContext.registerSurface,\n virtualization: parentPopupMenuContext.virtualization,\n virtualAnchor: parentPopupMenuContext.virtualAnchor,\n menuType: parentPopupMenuContext.menuType,\n disabled: parentPopupMenuContext.disabled,\n closeOnOutsidePress: parentPopupMenuContext.closeOnOutsidePress,\n getQualifiedRowId: parentPopupMenuContext.getQualifiedRowId,\n }),\n [store, parentPopupMenuContext],\n )\n\n const shouldRenderChildren = isActive\n\n return (\n <SubpageContext.Provider value={subpageContextValue}>\n <PopupSurfaceIdContext.Provider value={surfaceId}>\n <PopupMenuContext.Provider value={popupMenuContextValue}>\n <ListboxContextProvider.Provider value={listboxContextValue}>\n {shouldRenderChildren ? children : null}\n </ListboxContextProvider.Provider>\n </PopupMenuContext.Provider>\n </PopupSurfaceIdContext.Provider>\n </SubpageContext.Provider>\n )\n}\n\nexport namespace PopupMenuSubpage {\n export interface Props extends PopupMenuSubpageProps {}\n}\n","export enum PopupMenuSubpageBackDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-subpage-back' | 'bazzaui-context-menu-subpage-back'}\n */\n slot = 'bazzaui-[component]-subpage-back',\n /**\n * Present when navigating back is available.\n */\n canGoBack = 'data-can-go-back',\n /**\n * Present when the button is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { usePopupMenuContext } from '../../contexts/popup-menu-context.js'\nimport { useSubpageContext } from '../../contexts/subpage-context.js'\nimport { useSubpageStack } from '../../contexts/subpage-stack-context.js'\nimport { PopupMenuSubpageBackDataAttributes } from './subpage-back.data-attrs.js'\n\nexport { PopupMenuSubpageBackDataAttributes }\n\nexport interface PopupMenuSubpageBackState extends Record<string, unknown> {\n /** Whether navigating back is currently possible. */\n canGoBack: boolean\n /** Whether the button is disabled. */\n disabled: boolean\n}\n\nconst stateAttributesMapping = {\n canGoBack: (value: unknown) =>\n value ? { [PopupMenuSubpageBackDataAttributes.canGoBack]: '' } : null,\n disabled: (value: unknown) =>\n value ? { [PopupMenuSubpageBackDataAttributes.disabled]: '' } : null,\n}\n\nexport interface PopupMenuSubpageBackProps\n extends ComponentProps<'button', PopupMenuSubpageBack.State> {\n /** Whether this button is disabled. */\n disabled?: boolean\n}\n\n/**\n * A button that navigates back one page in the current subpage stack.\n * Useful for custom headers/toolbars outside of list rows.\n * Renders a `<button>` element.\n */\nexport const PopupMenuSubpageBack = React.forwardRef<\n HTMLButtonElement,\n PopupMenuSubpageBack.Props\n>(function PopupMenuSubpageBack(props, forwardedRef) {\n const {\n disabled: disabledProp = false,\n render,\n className,\n style,\n onClick,\n children,\n ...rest\n } = props\n\n const subpageContext = useSubpageContext()\n const subpageStack = useSubpageStack()\n const focusOwnerStore = useFocusOwner()\n const popupMenuContext = usePopupMenuContext()\n\n const disabled = disabledProp || popupMenuContext.disabled\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented || disabled) {\n return\n }\n\n const didGoBack = subpageContext.goBack()\n if (didGoBack && subpageContext.parentSurfaceId) {\n focusOwnerStore.setOwnerId(subpageContext.parentSurfaceId)\n }\n },\n [onClick, disabled, subpageContext, focusOwnerStore],\n )\n\n const state: PopupMenuSubpageBack.State = React.useMemo(\n () => ({\n canGoBack: subpageStack.canGoBack,\n disabled,\n }),\n [subpageStack.canGoBack, disabled],\n )\n\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'subpage-back')\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n type: 'button',\n disabled,\n className,\n style,\n onClick: handleClick,\n children,\n },\n defaultTagName: 'button',\n })\n})\n\nexport namespace PopupMenuSubpageBack {\n export type State = PopupMenuSubpageBackState\n export interface Props extends PopupMenuSubpageBackProps {}\n}\n","export enum PopupMenuSubpageBackItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-subpage-back-item' | 'bazzaui-context-menu-subpage-back-item'}\n */\n slot = 'bazzaui-[component]-subpage-back-item',\n /**\n * Present on subpage back item elements.\n */\n subpageBackItem = 'data-subpage-back-item',\n /**\n * Present when the item is highlighted.\n */\n highlighted = 'data-highlighted',\n /**\n * Present when the item is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { ItemContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { useSubpageContext } from '../../contexts/subpage-context.js'\nimport { usePopupMenuItem } from '../../hooks/use-popup-menu-item.js'\nimport { PopupMenuSubpageBackItemDataAttributes } from './subpage-back-item.data-attrs.js'\n\nexport { PopupMenuSubpageBackItemDataAttributes }\n\nexport interface PopupMenuSubpageBackItemState extends Record<string, unknown> {\n /** Whether this is a subpage back item (always true). */\n subpageBackItem: boolean\n /** Whether the item is highlighted. */\n highlighted: boolean\n /** Whether the item is disabled. */\n disabled: boolean\n}\n\nconst stateAttributesMapping = {\n subpageBackItem: (value: unknown) =>\n value\n ? { [PopupMenuSubpageBackItemDataAttributes.subpageBackItem]: '' }\n : null,\n highlighted: (value: unknown) =>\n value ? { [PopupMenuSubpageBackItemDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown) =>\n value ? { [PopupMenuSubpageBackItemDataAttributes.disabled]: '' } : null,\n}\n\nexport interface PopupMenuSubpageBackItemProps\n extends ComponentProps<'div', PopupMenuSubpageBackItem.State> {\n /** Explicit unique identifier for this item in the store. */\n id?: string\n /** Unique value for this item used for filtering. */\n value?: string\n /** Additional keywords to match against when filtering. */\n keywords?: string[]\n /** Whether this item is disabled. */\n disabled?: boolean\n /** Whether to force render this item regardless of filter results. */\n forceMount?: boolean\n /** Callback when this item is selected. */\n onSelect?: () => void\n /**\n * Async callback when this item is selected.\n *\n * When provided, this takes precedence over `onSelect`.\n * If provided, this callback is awaited before navigating back.\n * Return `false` to prevent automatic navigation.\n */\n onSelectAsync?: (\n context: PopupMenuSubpageBackItem.OnSelectAsyncContext,\n ) => Promise<void | boolean>\n}\n\n/**\n * A list row that navigates back one page in the current subpage stack.\n * Renders a `<div>` element with role=\"option\".\n */\nexport const PopupMenuSubpageBackItem = React.forwardRef<\n HTMLDivElement,\n PopupMenuSubpageBackItem.Props\n>(function PopupMenuSubpageBackItem(props, forwardedRef) {\n const {\n id,\n value,\n keywords,\n disabled: disabledProp = false,\n forceMount = false,\n onSelect,\n onSelectAsync,\n render,\n className,\n style,\n onClick,\n onPointerMove,\n onPointerDown,\n children,\n ...rest\n } = props\n\n const subpageContext = useSubpageContext()\n const focusOwnerStore = useFocusOwner()\n const [isPending, setIsPending] = React.useState(false)\n const abortControllerRef = React.useRef<AbortController | null>(null)\n\n React.useEffect(\n () => () => {\n abortControllerRef.current?.abort()\n },\n [],\n )\n\n const goBack = React.useCallback(() => {\n const didGoBack = subpageContext.goBack()\n if (didGoBack && subpageContext.parentSurfaceId) {\n focusOwnerStore.setOwnerId(subpageContext.parentSurfaceId)\n }\n\n return didGoBack\n }, [subpageContext, focusOwnerStore])\n\n const handleBack = React.useCallback(() => {\n if (onSelectAsync) {\n if (isPending) {\n return\n }\n\n abortControllerRef.current?.abort()\n\n const controller = new AbortController()\n abortControllerRef.current = controller\n setIsPending(true)\n\n let didNavigate = false\n const context: PopupMenuSubpageBackItem.OnSelectAsyncContext = {\n goBack: () => {\n const didGoBack = goBack()\n if (didGoBack) {\n didNavigate = true\n }\n\n return didGoBack\n },\n signal: controller.signal,\n }\n\n void onSelectAsync(context)\n .then((result) => {\n if (controller.signal.aborted) {\n return\n }\n\n if (result !== false && !didNavigate) {\n context.goBack()\n }\n })\n .catch(() => {\n // ignore async selection errors and keep current subpage open\n })\n .finally(() => {\n if (!controller.signal.aborted) {\n setIsPending(false)\n }\n })\n\n return\n }\n\n onSelect?.()\n\n goBack()\n }, [onSelect, onSelectAsync, goBack, isPending])\n\n const item = usePopupMenuItem({\n id,\n value,\n keywords,\n disabled: disabledProp || isPending,\n forceMount,\n closeOnClick: false,\n onSelect: handleBack,\n children,\n })\n\n const disabled = item.disabled\n\n const state: PopupMenuSubpageBackItem.State = React.useMemo(\n () => ({\n subpageBackItem: true,\n highlighted: item.isHighlighted,\n disabled,\n }),\n [item.isHighlighted, disabled],\n )\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onClick(event)\n }\n },\n [onClick, item.handlers],\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n item.handlers.onPointerDown(event)\n onPointerDown?.(event)\n },\n [item.handlers, onPointerDown],\n )\n\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onPointerMove(event)\n }\n },\n [onPointerMove, item.handlers],\n )\n\n const wrappedChildren = (\n <ItemContext.Provider value={item.contextValue}>\n {children}\n </ItemContext.Provider>\n )\n\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'subpage-back-item')\n\n return useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: item.id,\n role: 'option',\n tabIndex: -1,\n 'aria-selected': item.isHighlighted,\n 'aria-disabled': disabled || undefined,\n className,\n style,\n onClick: handleClick,\n onPointerMove: handlePointerMove,\n onPointerDown: handlePointerDown,\n children: wrappedChildren,\n },\n enabled: item.isVisible,\n defaultTagName: 'div',\n })\n})\n\nexport namespace PopupMenuSubpageBackItem {\n export type State = PopupMenuSubpageBackItemState\n export interface OnSelectAsyncContext {\n /** Navigate back one page manually. */\n goBack: () => boolean\n /** Aborts when a pending async selection is canceled or unmounted. */\n signal: AbortSignal\n }\n export interface Props extends PopupMenuSubpageBackItemProps {}\n}\n","export enum PopupMenuSubpageTriggerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-subpage-trigger' | 'bazzaui-context-menu-subpage-trigger'}\n */\n slot = 'bazzaui-[component]-subpage-trigger',\n /**\n * Present on subpage trigger elements.\n */\n subpageTrigger = 'data-subpage-trigger',\n /**\n * Present when the target page is active.\n */\n popupOpen = 'data-popup-open',\n /**\n * Present when the target page owns keyboard focus.\n */\n popupFocused = 'data-popup-focused',\n /**\n * Present when the item is highlighted.\n */\n highlighted = 'data-highlighted',\n /**\n * Present when the item is disabled.\n */\n disabled = 'data-disabled',\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport type { ComponentProps } from '../../../../utils/types.js'\nimport { ItemContext } from '../../../listbox/index.js'\nimport {\n getSlotAttribute,\n useMaybeComponentName,\n} from '../../contexts/component-name-context.js'\nimport { useFocusOwner } from '../../contexts/focus-owner-context.js'\nimport { useSubpageStack } from '../../contexts/subpage-stack-context.js'\nimport { usePopupMenuItem } from '../../hooks/use-popup-menu-item.js'\nimport { PopupMenuSubpageTriggerDataAttributes } from './subpage-trigger.data-attrs.js'\n\nexport { PopupMenuSubpageTriggerDataAttributes }\n\nexport interface PopupMenuSubpageTriggerState extends Record<string, unknown> {\n /** Whether this is a subpage trigger (always true). */\n subpageTrigger: boolean\n /** Whether the target page is active. */\n popupOpen: boolean\n /** Whether the target page owns keyboard focus. */\n popupFocused: boolean\n /** Whether the item is highlighted. */\n highlighted: boolean\n /** Whether the item is disabled. */\n disabled: boolean\n}\n\nconst stateAttributesMapping = {\n subpageTrigger: (value: unknown) =>\n value\n ? { [PopupMenuSubpageTriggerDataAttributes.subpageTrigger]: '' }\n : null,\n popupOpen: (value: unknown) =>\n value ? { [PopupMenuSubpageTriggerDataAttributes.popupOpen]: '' } : null,\n popupFocused: (value: unknown) =>\n value ? { [PopupMenuSubpageTriggerDataAttributes.popupFocused]: '' } : null,\n highlighted: (value: unknown) =>\n value ? { [PopupMenuSubpageTriggerDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown) =>\n value ? { [PopupMenuSubpageTriggerDataAttributes.disabled]: '' } : null,\n}\n\nexport interface PopupMenuSubpageTriggerProps\n extends ComponentProps<'div', PopupMenuSubpageTrigger.State> {\n /** Explicit unique identifier for this item in the store. */\n id?: string\n /** Unique value for this item used for filtering. */\n value?: string\n /** Additional keywords to match against when filtering. */\n keywords?: string[]\n /** Whether this item is disabled. */\n disabled?: boolean\n /** Whether to force render this item regardless of filter results. */\n forceMount?: boolean\n /**\n * Forces this row's relative order during score-based sorting.\n * Lower values appear earlier.\n * @default 0\n */\n forceOrder?: number\n /**\n * Overrides this row's computed fuzzy-match score.\n */\n forceScore?: number\n /** Target page ID to open when this trigger is selected. */\n targetPageId: string\n}\n\n/**\n * A menu item that pushes a new page in the same popup.\n * Renders a `<div>` element with role=\"menuitem\".\n */\nexport const PopupMenuSubpageTrigger = React.forwardRef<\n HTMLDivElement,\n PopupMenuSubpageTrigger.Props\n>(function PopupMenuSubpageTrigger(props, forwardedRef) {\n const {\n id: idProp,\n value,\n keywords,\n disabled: disabledProp = false,\n forceMount = false,\n forceOrder,\n forceScore,\n targetPageId,\n render,\n className,\n style,\n onClick,\n onPointerDown,\n onPointerMove,\n children,\n ...rest\n } = props\n\n const focusOwnerStore = useFocusOwner()\n const subpageStack = useSubpageStack()\n const activePageId = subpageStack.activePageId\n const openPage = subpageStack.openPage\n const getSurfaceId = subpageStack.getSurfaceId\n\n const openTargetPage = React.useCallback(() => {\n const didOpen = openPage(targetPageId)\n if (!didOpen) {\n return\n }\n\n const targetSurfaceId = getSurfaceId(targetPageId)\n if (targetSurfaceId) {\n focusOwnerStore.setOwnerId(targetSurfaceId)\n }\n }, [openPage, getSurfaceId, targetPageId, focusOwnerStore])\n\n const item = usePopupMenuItem({\n id: idProp,\n value,\n keywords,\n disabled: disabledProp,\n forceMount,\n forceOrder,\n forceScore,\n isSubmenuTrigger: false,\n closeOnClick: false,\n onSelect: openTargetPage,\n children,\n })\n\n const disabled = item.disabled\n\n const isTargetOpen = activePageId === targetPageId\n const targetSurfaceId = getSurfaceId(targetPageId)\n const isPopupFocused = focusOwnerStore.useState(\n 'isOwner',\n targetSurfaceId ?? '',\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n item.handlers.onPointerDown(event)\n onPointerDown?.(event)\n },\n [item.handlers, onPointerDown],\n )\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onClick(event)\n }\n },\n [item.handlers, onClick],\n )\n\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event)\n if (!event.defaultPrevented) {\n item.handlers.onPointerMove(event)\n }\n },\n [onPointerMove, item.handlers],\n )\n\n const state: PopupMenuSubpageTrigger.State = React.useMemo(\n () => ({\n subpageTrigger: true,\n popupOpen: isTargetOpen,\n popupFocused: isPopupFocused,\n highlighted: item.isHighlighted,\n disabled,\n }),\n [isTargetOpen, isPopupFocused, item.isHighlighted, disabled],\n )\n\n const wrappedChildren = (\n <ItemContext.Provider value={item.contextValue}>\n {children}\n </ItemContext.Provider>\n )\n\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'subpage-trigger')\n\n return useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n ...(slotAttr ? { [slotAttr]: '' } : {}),\n id: item.id,\n role: 'menuitem',\n 'aria-haspopup': 'menu',\n 'aria-expanded': isTargetOpen,\n tabIndex: -1,\n 'aria-disabled': disabled || undefined,\n className,\n style,\n onPointerDown: handlePointerDown,\n onClick: handleClick,\n onPointerMove: handlePointerMove,\n children: wrappedChildren,\n },\n enabled: item.isVisible,\n defaultTagName: 'div',\n })\n})\n\nexport namespace PopupMenuSubpageTrigger {\n export type State = PopupMenuSubpageTriggerState\n export interface Props extends PopupMenuSubpageTriggerProps {}\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useSurfaceContext } from '../../listbox/index.js'\nimport { normalizeValue } from '../../listbox/utils/normalize.js'\nimport { PopupMenuList } from '../components/list/list.js'\nimport {\n type AsyncMenuState,\n useAsyncMenuCoordinator,\n} from './async-coordinator.js'\nimport { type RenderNodeFn, useDataSurfaceContext } from './context.js'\nimport type {\n AsyncLoaderResult,\n AsyncNodesConfig,\n BreadcrumbNode,\n CheckboxItemDef,\n DataListChildrenState,\n DataListProps,\n DisplayNode,\n DisplayRowNode,\n GetQualifiedRowIdFn,\n GroupRenderContext,\n ItemDef,\n NodeDef,\n QueryDependentLoaderConfig,\n RadioGroupDef,\n RowRenderContext,\n SubmenuDef,\n SubpageDef,\n} from './types.js'\nimport {\n isDisplayGroupNode,\n isDisplayRadioGroupNode,\n isDisplaySeparatorNode,\n} from './types.js'\nimport {\n type AsyncSubmenuInfo,\n collectAsyncSubmenus,\n filterNodes,\n getSubpagePageId,\n mergeAsyncNodesIntoTree,\n shouldLoadEagerly,\n} from './utils.js'\n\n// ============================================================================\n// Helper: Compute composite IDs for all row nodes\n// ============================================================================\n\n/**\n * Computes and sets composite IDs directly on all row nodes in the display list.\n * Mutates the displayNodes in place for performance.\n * The index is the flat position across all items (including those inside groups).\n */\nfunction computeItemIds(\n displayNodes: DisplayNode[],\n getQualifiedRowId: GetQualifiedRowIdFn,\n isDeepSearching: boolean,\n): void {\n let index = 0\n\n for (const displayNode of displayNodes) {\n if (isDisplayGroupNode(displayNode)) {\n for (const item of displayNode.items) {\n item.compositeId = getQualifiedRowId({\n node: item.node,\n value: item.node.value,\n id: item.node.id,\n index,\n breadcrumbs: item.context.breadcrumbs,\n isDeepSearching,\n search: item.context.search,\n isDeepSearchResult: item.context.isDeepSearchResult,\n group: item.context.group,\n radioGroup: null,\n })\n index++\n }\n } else if (isDisplayRadioGroupNode(displayNode)) {\n for (const item of displayNode.items) {\n item.compositeId = getQualifiedRowId({\n node: item.node,\n value: item.node.value,\n id: item.node.id,\n index,\n breadcrumbs: item.context.breadcrumbs,\n isDeepSearching,\n search: item.context.search,\n isDeepSearchResult: item.context.isDeepSearchResult,\n group: null,\n radioGroup: item.radioGroup ?? null,\n })\n index++\n }\n } else if (isDisplaySeparatorNode(displayNode)) {\n // Separators don't need IDs\n } else {\n // Row node\n displayNode.compositeId = getQualifiedRowId({\n node: displayNode.node,\n value: displayNode.node.value,\n id: displayNode.node.id,\n index,\n breadcrumbs: displayNode.context.breadcrumbs,\n isDeepSearching,\n search: displayNode.context.search,\n isDeepSearchResult: displayNode.context.isDeepSearchResult,\n group: displayNode.context.group,\n radioGroup: displayNode.radioGroup ?? null,\n })\n index++\n }\n }\n}\n\n/**\n * Extracts ordered composite IDs from display nodes for store navigation.\n * Assumes `computeItemIds` has already been called to set `compositeId` on each node.\n */\nfunction getOrderedItemIds(displayNodes: DisplayNode[]): string[] {\n const ids: string[] = []\n\n for (const displayNode of displayNodes) {\n if (isDisplayGroupNode(displayNode)) {\n for (const item of displayNode.items) {\n if (!item.node.disabled && item.compositeId) {\n ids.push(item.compositeId)\n }\n }\n } else if (isDisplayRadioGroupNode(displayNode)) {\n for (const item of displayNode.items) {\n if (!item.node.disabled && item.compositeId) {\n ids.push(item.compositeId)\n }\n }\n } else if (isDisplaySeparatorNode(displayNode)) {\n // skip\n } else {\n if (!displayNode.node.disabled && displayNode.compositeId) {\n ids.push(displayNode.compositeId)\n }\n }\n }\n\n return ids\n}\n\nfunction isAppendOnlyOrderedItemsUpdate(\n previousIds: string[],\n nextIds: string[],\n): boolean {\n if (previousIds.length === 0 || nextIds.length <= previousIds.length) {\n return false\n }\n\n for (let i = 0; i < previousIds.length; i++) {\n if (previousIds[i] !== nextIds[i]) {\n return false\n }\n }\n\n return true\n}\n\nfunction getBreadcrumbStreamKey(breadcrumbs: BreadcrumbNode[]): string {\n return breadcrumbs\n .map((breadcrumb) => breadcrumb.id ?? breadcrumb.value)\n .join('>')\n}\n\nfunction getDisplayNodeStreamKey(displayNode: DisplayNode): string {\n if (isDisplayGroupNode(displayNode)) {\n return `group:${displayNode.group.id}:${getBreadcrumbStreamKey(displayNode.context.breadcrumbs)}`\n }\n\n if (isDisplayRadioGroupNode(displayNode)) {\n return `radio-group:${displayNode.radioGroup.id}:${getBreadcrumbStreamKey(displayNode.context.breadcrumbs)}`\n }\n\n if (isDisplaySeparatorNode(displayNode)) {\n return `separator:${displayNode.separator.id ?? 'separator'}`\n }\n\n return `row:${displayNode.node.kind}:${displayNode.node.id ?? ''}:${displayNode.node.value}:${getBreadcrumbStreamKey(displayNode.context.breadcrumbs)}`\n}\n\nconst identityQuery = (query: string) => query\n\nfunction orderDisplayNodesForStreaming(\n displayNodes: DisplayNode[],\n previousOrder: string[],\n): {\n orderedNodes: DisplayNode[]\n nextOrder: string[]\n} {\n const currentEntries = displayNodes.map(\n (node) => [getDisplayNodeStreamKey(node), node] as const,\n )\n\n const currentByKey = new Map(currentEntries)\n const currentOrder = currentEntries.map(([key]) => key)\n\n const preservedOrder = previousOrder.filter((key) => currentByKey.has(key))\n const preservedKeysSet = new Set(preservedOrder)\n const appendedOrder = currentOrder.filter((key) => !preservedKeysSet.has(key))\n const nextOrder = [...preservedOrder, ...appendedOrder]\n\n const orderedNodes = nextOrder\n .map((key) => currentByKey.get(key))\n .filter((node): node is DisplayNode => node !== undefined)\n\n return { orderedNodes, nextOrder }\n}\n\n// ============================================================================\n// Async Loader Component\n// ============================================================================\n\ninterface AsyncLoaderRendererProps {\n info: AsyncSubmenuInfo\n query: string\n enabled: boolean\n}\n\ninterface QueryExecutionState {\n effectiveQuery: string\n enabled: boolean\n isBelowMinLength: boolean\n}\n\nfunction resolveInitialQueryBehavior(config: QueryDependentLoaderConfig):\n | {\n value: string\n loadWhen: 'needed' | 'parent-open'\n }\n | false {\n if (config.initialQueryBehavior !== undefined) {\n if (config.initialQueryBehavior === false) {\n return false\n }\n return {\n value: config.initialQueryBehavior.value ?? '',\n loadWhen: config.initialQueryBehavior.loadWhen ?? 'needed',\n }\n }\n\n if (config.initialQuery !== undefined) {\n return { value: config.initialQuery, loadWhen: 'needed' }\n }\n\n return { value: '', loadWhen: 'needed' }\n}\n\nfunction resolveQueryExecutionState(\n config: QueryDependentLoaderConfig,\n query: string,\n): QueryExecutionState {\n const minLength = config.minQueryLength ?? 1\n const initialQueryBehavior = resolveInitialQueryBehavior(config)\n\n if (query.length >= minLength) {\n return {\n effectiveQuery: query,\n enabled: true,\n isBelowMinLength: false,\n }\n }\n\n if (initialQueryBehavior !== false) {\n return {\n effectiveQuery: initialQueryBehavior.value,\n enabled: true,\n isBelowMinLength: false,\n }\n }\n\n return {\n effectiveQuery: '',\n enabled: false,\n isBelowMinLength: true,\n }\n}\n\nfunction getAsyncLoaderIdForBranch(\n node: SubmenuDef | SubpageDef,\n breadcrumbs: BreadcrumbNode[],\n): string {\n return [\n ...breadcrumbs.map((breadcrumb) => normalizeValue(breadcrumb.value)),\n normalizeValue(node.value),\n ].join('.')\n}\n\n/**\n * Renders an async loader component and registers its state with the coordinator.\n * This component exists solely to call the Loader component (which contains hooks).\n */\nfunction AsyncLoaderRenderer({\n info,\n query,\n enabled,\n}: AsyncLoaderRendererProps) {\n const coordinator = useAsyncMenuCoordinator()\n const { config, id, breadcrumbs } = info\n const Loader = config.Loader\n\n const queryExecution = React.useMemo(() => {\n if (config.type !== 'query') {\n return null\n }\n\n return resolveQueryExecutionState(config, query)\n }, [config, query])\n\n const effectiveQuery = queryExecution?.effectiveQuery ?? query\n const shouldFetch = queryExecution?.enabled ?? true\n\n // Track if this loader should be active\n const isActive = enabled || shouldLoadEagerly(config)\n\n if (!isActive) {\n return null\n }\n\n return (\n <Loader query={effectiveQuery} enabled={shouldFetch}>\n {(result) => (\n <AsyncLoaderResultHandler\n id={id}\n breadcrumbs={breadcrumbs}\n config={config}\n result={result}\n coordinator={coordinator}\n />\n )}\n </Loader>\n )\n}\n\ninterface AsyncLoaderResultHandlerProps {\n id: string\n breadcrumbs: string[]\n config: AsyncNodesConfig\n result: AsyncLoaderResult<NodeDef[]>\n coordinator: ReturnType<typeof useAsyncMenuCoordinator>\n}\n\n/**\n * Handles registering and updating loader results with the coordinator.\n * This is a separate component to avoid re-rendering the Loader on every result change.\n */\nfunction AsyncLoaderResultHandler({\n id,\n breadcrumbs,\n config,\n result,\n coordinator,\n}: AsyncLoaderResultHandlerProps) {\n // Use refs to hold the latest values without causing re-renders\n // This is critical because coordinator changes on every state update (new Map)\n const breadcrumbsRef = React.useRef(breadcrumbs)\n const configRef = React.useRef(config)\n const coordinatorRef = React.useRef(coordinator)\n const resultRef = React.useRef(result)\n\n // Track previous result values to avoid unnecessary updates\n // TanStack Query returns new object references on every render\n const prevResultRef = React.useRef<{\n data: unknown\n status: string\n fetchStatus: string\n loadingPhase: string\n isLoading: boolean\n isFetching: boolean\n isInitialLoading: boolean\n isRefetching: boolean\n isPending: boolean\n isSuccess: boolean\n isError: boolean\n isPaused: boolean\n hasData: boolean\n hasFetched: boolean\n error: Error | null\n } | null>(null)\n\n // Keep refs up to date\n breadcrumbsRef.current = breadcrumbs\n configRef.current = config\n coordinatorRef.current = coordinator\n resultRef.current = result\n\n // Register on mount, unregister on unmount\n // IMPORTANT: Only depend on `id` - coordinator is accessed via ref to avoid\n // infinite loops (coordinator object changes on every state update)\n React.useEffect(() => {\n const coord = coordinatorRef.current\n if (!coord) return\n\n const state: AsyncMenuState = {\n id,\n breadcrumbs: breadcrumbsRef.current,\n config: configRef.current,\n result: resultRef.current,\n }\n\n coord.registerLoader(state)\n\n return () => {\n coord.unregisterLoader(id)\n }\n }, [id]) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Update result when meaningful values change\n // IMPORTANT: Depend on individual result values, not the result object reference.\n // TanStack Query creates new object references on every render, but we only want\n // to trigger updates when actual values change.\n // Using coordinatorRef prevents re-running when coordinator context changes.\n React.useEffect(() => {\n const coord = coordinatorRef.current\n if (!coord) return\n\n // Compare against previous values to avoid unnecessary updates\n const prev = prevResultRef.current\n const hasChanged =\n prev === null ||\n prev.data !== result.data ||\n prev.status !== result.status ||\n prev.fetchStatus !== result.fetchStatus ||\n prev.loadingPhase !== result.loadingPhase ||\n prev.isLoading !== result.isLoading ||\n prev.isFetching !== result.isFetching ||\n prev.isInitialLoading !== result.isInitialLoading ||\n prev.isRefetching !== result.isRefetching ||\n prev.isPending !== result.isPending ||\n prev.isSuccess !== result.isSuccess ||\n prev.isError !== result.isError ||\n prev.isPaused !== result.isPaused ||\n prev.hasData !== result.hasData ||\n prev.hasFetched !== result.hasFetched ||\n prev.error !== result.error\n\n if (hasChanged) {\n prevResultRef.current = {\n data: result.data,\n status: result.status,\n fetchStatus: result.fetchStatus,\n loadingPhase: result.loadingPhase,\n isLoading: result.isLoading,\n isFetching: result.isFetching,\n isInitialLoading: result.isInitialLoading,\n isRefetching: result.isRefetching,\n isPending: result.isPending,\n isSuccess: result.isSuccess,\n isError: result.isError,\n isPaused: result.isPaused,\n hasData: result.hasData,\n hasFetched: result.hasFetched,\n error: result.error,\n }\n coord.updateLoaderResult(id, result)\n }\n }, [\n id,\n result.data,\n result.status,\n result.fetchStatus,\n result.loadingPhase,\n result.isLoading,\n result.isFetching,\n result.isInitialLoading,\n result.isRefetching,\n result.isPending,\n result.isSuccess,\n result.isError,\n result.isPaused,\n result.hasData,\n result.hasFetched,\n result.error,\n ]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return null\n}\n\n// ============================================================================\n// Root Async Loader Component\n// ============================================================================\n\ninterface RootAsyncLoaderProps {\n query: string\n}\n\n/**\n * Renders the root async content loader if configured.\n */\nfunction RootAsyncLoader({ query }: RootAsyncLoaderProps) {\n const dataSurfaceCtx = useDataSurfaceContext()\n const coordinator = useAsyncMenuCoordinator()\n const { asyncContent } = dataSurfaceCtx\n\n const queryExecution = React.useMemo(() => {\n if (!asyncContent || asyncContent.type !== 'query') {\n return null\n }\n\n return resolveQueryExecutionState(asyncContent, query)\n }, [asyncContent, query])\n\n const effectiveQuery = queryExecution?.effectiveQuery ?? query\n const shouldFetch = queryExecution?.enabled ?? true\n\n if (!asyncContent) {\n return null\n }\n\n const Loader = asyncContent.Loader\n\n return (\n <Loader query={effectiveQuery} enabled={shouldFetch}>\n {(result) => (\n <AsyncLoaderResultHandler\n id=\"__root__\"\n breadcrumbs={[]}\n config={asyncContent as AsyncNodesConfig}\n result={result}\n coordinator={coordinator}\n />\n )}\n </Loader>\n )\n}\n\n// ============================================================================\n// DataList Component\n// ============================================================================\n\nexport interface PopupMenuDataListProps extends DataListProps {\n /** Render function for custom element */\n render?: React.ReactElement\n}\n\n/**\n * DataList renders the menu items using a render prop pattern.\n * It reads from the store for search and computes filtered nodes.\n *\n * Place inside PopupMenuDataSurface.\n * Wraps PopupMenuList for keyboard navigation and accessibility.\n */\nexport const PopupMenuDataList = React.forwardRef<\n HTMLDivElement,\n PopupMenuDataList.Props\n>(function PopupMenuDataList(props, forwardedRef) {\n // Get data surface context for content and deep search config\n const dataSurfaceCtx = useDataSurfaceContext()\n const {\n content,\n asyncContent,\n deepSearchConfig,\n includeInDeepSearch,\n getQualifiedRowId,\n } = dataSurfaceCtx\n\n // Get store from surface context for search state\n const { store } = useSurfaceContext()\n const search = store.useState('search')\n const normalizedSearch = store.useState('normalizedSearch')\n\n return (\n <DataListInner\n ref={forwardedRef}\n {...props}\n content={content}\n asyncContent={asyncContent}\n deepSearchConfig={deepSearchConfig}\n includeInDeepSearch={includeInDeepSearch}\n getQualifiedRowId={getQualifiedRowId}\n search={search}\n normalizedSearch={normalizedSearch}\n store={store}\n />\n )\n})\n\n// ============================================================================\n// DataList Inner Component (with coordinator access)\n// ============================================================================\n\ninterface DataListInnerProps extends PopupMenuDataListProps {\n content: NodeDef[]\n asyncContent: ReturnType<typeof useDataSurfaceContext>['asyncContent']\n deepSearchConfig: ReturnType<typeof useDataSurfaceContext>['deepSearchConfig']\n includeInDeepSearch: ReturnType<\n typeof useDataSurfaceContext\n >['includeInDeepSearch']\n getQualifiedRowId: GetQualifiedRowIdFn\n search: string\n normalizedSearch: string\n store: ReturnType<typeof useSurfaceContext>['store']\n}\n\nconst DataListInner = React.forwardRef<HTMLDivElement, DataListInnerProps>(\n function DataListInner(props, forwardedRef) {\n const {\n children,\n label = 'Menu',\n className,\n style,\n render,\n measureRowWidth,\n maxRowWidth,\n content,\n asyncContent,\n deepSearchConfig,\n includeInDeepSearch,\n getQualifiedRowId,\n search,\n normalizedSearch,\n store,\n } = props\n\n // Get coordinator for async state\n const coordinator = useAsyncMenuCoordinator()\n\n // Collect async submenus from content\n const asyncSubmenus = React.useMemo(\n () => collectAsyncSubmenus(content, [], includeInDeepSearch),\n [content, includeInDeepSearch],\n )\n\n // Determine if deep search is active\n const minLength = deepSearchConfig.minLength ?? 0\n const isDeepSearchActive =\n deepSearchConfig.enabled !== false && normalizedSearch.length >= minLength\n\n // Determine which async loaders should be rendered\n const shouldRenderAsyncLoaders =\n isDeepSearchActive ||\n asyncSubmenus.some((s) => shouldLoadEagerly(s.config)) ||\n (asyncContent && asyncContent.loadStrategy === 'eager')\n\n // Get async nodes from coordinator\n const asyncNodes = React.useMemo(() => {\n if (!coordinator) return []\n return coordinator.getAsyncNodes()\n }, [coordinator, coordinator?.loaders])\n\n // Merge async nodes into content tree\n const mergedContent = React.useMemo(() => {\n if (asyncNodes.length === 0) return content\n return mergeAsyncNodesIntoTree(content, asyncNodes)\n }, [content, asyncNodes])\n\n // Handle root async content if available\n const contentWithRootAsync = React.useMemo(() => {\n const rootAsyncData = asyncNodes.find((n) => n.id === '__root__')\n if (!rootAsyncData) return mergedContent\n\n // When asyncContent is provided, it's the sole data source - use only its results\n if (asyncContent) {\n return rootAsyncData.nodes\n }\n\n // For root-level DataSurface without asyncContent, append to static content\n return [...mergedContent, ...rootAsyncData.nodes]\n }, [mergedContent, asyncNodes, asyncContent])\n\n const streamOrderRef = React.useRef<{\n query: string\n order: string[]\n } | null>(null)\n\n // Compute filtered display nodes and set composite IDs\n const { displayNodes, isDeepSearching } = React.useMemo(() => {\n const result = filterNodes({\n query: normalizedSearch,\n normalizeQuery: identityQuery,\n nodes: contentWithRootAsync,\n highlightedId: null, // Primitives handle highlighting via store\n deepSearch: deepSearchConfig.enabled,\n includeInDeepSearch,\n minLength: deepSearchConfig.minLength,\n groupSearchBehavior: deepSearchConfig.groupSearchBehavior,\n radioGroupSearchBehavior: deepSearchConfig.radioGroupSearchBehavior,\n sortGroups: deepSearchConfig.sortGroups,\n })\n\n const asyncResultBehavior =\n deepSearchConfig.asyncResultBehavior ?? 'stream'\n const expectedAsyncLoaderCount =\n asyncSubmenus.length + (asyncContent ? 1 : 0)\n const hasAsyncSources = expectedAsyncLoaderCount > 0\n\n const shouldBlockAsyncResults =\n asyncResultBehavior === 'block' &&\n result.isDeepSearching &&\n hasAsyncSources &&\n coordinator !== null &&\n (coordinator.loaders.size < expectedAsyncLoaderCount ||\n coordinator.isAnyLoading)\n\n let displayNodesToRender = result.displayNodes\n\n if (shouldBlockAsyncResults) {\n streamOrderRef.current = null\n displayNodesToRender = []\n } else if (asyncResultBehavior === 'stream' && result.isDeepSearching) {\n const previousStreamState = streamOrderRef.current\n\n if (\n !previousStreamState ||\n previousStreamState.query !== normalizedSearch\n ) {\n streamOrderRef.current = {\n query: normalizedSearch,\n order: displayNodesToRender.map(getDisplayNodeStreamKey),\n }\n } else {\n const { orderedNodes, nextOrder } = orderDisplayNodesForStreaming(\n displayNodesToRender,\n previousStreamState.order,\n )\n\n displayNodesToRender = orderedNodes\n streamOrderRef.current = {\n query: normalizedSearch,\n order: nextOrder,\n }\n }\n } else {\n streamOrderRef.current = null\n }\n\n // Set composite IDs directly on the freshly created display nodes\n computeItemIds(\n displayNodesToRender,\n getQualifiedRowId,\n result.isDeepSearching,\n )\n\n return {\n displayNodes: displayNodesToRender,\n isDeepSearching: result.isDeepSearching,\n }\n }, [\n normalizedSearch,\n contentWithRootAsync,\n deepSearchConfig,\n includeInDeepSearch,\n getQualifiedRowId,\n asyncSubmenus.length,\n asyncContent,\n coordinator,\n coordinator?.isAnyLoading,\n coordinator?.loaders,\n ])\n\n // Sync orderedItems with the store when display nodes change\n // This is needed because DataSurface sets filter={false} on the underlying Surface\n //\n // We use a ref to track the previous IDs and do a deep comparison to avoid\n // triggering highlight resets when the content hasn't actually changed.\n const prevOrderedItemIdsRef = React.useRef<string[]>([])\n const prevOrderedItemsSearchRef = React.useRef<string | null>(null)\n const orderedItemsUpdateReasonRef = React.useRef<'replace' | 'append'>(\n 'replace',\n )\n\n // Compute new ordered IDs using composite IDs\n const newOrderedItemIds = React.useMemo(\n () => getOrderedItemIds(displayNodes),\n [displayNodes],\n )\n\n // Memoize the ordered IDs, only returning a new array if content changed\n const orderedItemIds = React.useMemo(() => {\n const prev = prevOrderedItemIdsRef.current\n const current = newOrderedItemIds\n\n // Deep comparison\n const changed =\n prev.length !== current.length ||\n prev.some((id, i) => id !== current[i])\n\n if (changed) {\n const asyncResultBehavior =\n deepSearchConfig.asyncResultBehavior ?? 'stream'\n const shouldUseAppendReason =\n asyncResultBehavior === 'stream' &&\n isDeepSearching &&\n prevOrderedItemsSearchRef.current === normalizedSearch &&\n isAppendOnlyOrderedItemsUpdate(prev, current)\n\n orderedItemsUpdateReasonRef.current = shouldUseAppendReason\n ? 'append'\n : 'replace'\n prevOrderedItemIdsRef.current = current\n prevOrderedItemsSearchRef.current = normalizedSearch\n return current\n }\n\n return prev\n }, [\n newOrderedItemIds,\n deepSearchConfig.asyncResultBehavior,\n isDeepSearching,\n normalizedSearch,\n ])\n\n React.useEffect(() => {\n store.setOrderedItems(orderedItemIds, {\n reason: orderedItemsUpdateReasonRef.current,\n })\n }, [store, orderedItemIds])\n\n // Helper to render a single row node (item, checkbox item, submenu, or subpage)\n // biome-ignore lint/correctness/useExhaustiveDependencies: renderRowNode and renderRadioGroup are intentionally recursive.\n const renderRowNode = React.useCallback(\n (displayNode: DisplayRowNode): React.ReactNode => {\n const { node, context } = displayNode\n\n // Use composite ID from display node, fallback to node.id/value for nested children\n const compositeId = displayNode.compositeId ?? node.id ?? node.value\n\n const getBranchAsyncState = (branchNode: SubmenuDef | SubpageDef) => {\n if (!branchNode.asyncNodes || !coordinator) {\n return undefined\n }\n\n const asyncLoaderId = getAsyncLoaderIdForBranch(\n branchNode,\n context.breadcrumbs,\n )\n const asyncResult = coordinator.loaders.get(asyncLoaderId)\n\n if (!asyncResult) {\n return undefined\n }\n\n const isBelowMinLength =\n branchNode.asyncNodes.type === 'query'\n ? resolveQueryExecutionState(\n branchNode.asyncNodes,\n normalizedSearch,\n ).isBelowMinLength\n : false\n\n return {\n status: asyncResult.result.status,\n fetchStatus: asyncResult.result.fetchStatus,\n loadingPhase: asyncResult.result.loadingPhase,\n isLoading: asyncResult.result.isLoading,\n isFetching: asyncResult.result.isFetching,\n isInitialLoading: asyncResult.result.isInitialLoading,\n isRefetching: asyncResult.result.isRefetching,\n isError: asyncResult.result.isError,\n error: asyncResult.result.error,\n isBelowMinLength,\n }\n }\n\n if (node.kind === 'item') {\n return (\n <React.Fragment key={compositeId}>\n {node.render({\n props: {\n id: compositeId,\n value: node.value,\n disabled: node.disabled ?? false,\n closeOnClick: node.closeOnClick,\n onSelect: node.onSelect,\n shortcut: node.shortcut,\n forceOrder: node.forceOrder,\n forceScore: node.forceScore,\n },\n context: {\n ...context,\n value: node.value,\n disabled: node.disabled ?? false,\n },\n })}\n </React.Fragment>\n )\n }\n\n if (node.kind === 'radio-item') {\n return (\n <React.Fragment key={compositeId}>\n {node.render({\n props: {\n id: compositeId,\n value: node.value,\n disabled: node.disabled ?? false,\n closeOnClick: node.closeOnClick,\n onSelect: node.onSelect,\n shortcut: node.shortcut,\n forceOrder: node.forceOrder,\n forceScore: node.forceScore,\n },\n context: {\n ...context,\n value: node.value,\n disabled: node.disabled ?? false,\n },\n })}\n </React.Fragment>\n )\n }\n\n if (node.kind === 'checkbox-item') {\n return (\n <React.Fragment key={compositeId}>\n {node.render({\n props: {\n id: compositeId,\n value: node.value,\n checked: node.checked,\n onCheckedChange: node.onCheckedChange,\n disabled: node.disabled ?? false,\n closeOnClick: node.closeOnClick,\n forceOrder: node.forceOrder,\n forceScore: node.forceScore,\n },\n context: {\n ...context,\n value: node.value,\n checked: node.checked,\n disabled: node.disabled ?? false,\n },\n })}\n </React.Fragment>\n )\n }\n\n if (node.kind === 'submenu') {\n // For submenus, provide the nodes and a recursive renderNode function\n // Note: We pass the compositeId to the submenu trigger so it registers with the\n // correct ID for keyboard navigation during deep search\n const submenuAsyncState = getBranchAsyncState(node)\n\n // Static nodes only - async content is handled by the submenu's own DataSurface\n const staticNodes = node.nodes ?? []\n\n // Create breadcrumb node for current submenu (used in child contexts)\n const submenuBreadcrumb: BreadcrumbNode = {\n node,\n value: node.value,\n id: node.id,\n }\n\n const submenuRenderNode = (childNode: NodeDef): React.ReactNode => {\n // Skip separators\n if (childNode.kind === 'separator') {\n return null\n }\n\n // Handle groups - render the group with its children\n if (childNode.kind === 'group') {\n const groupItems = childNode.nodes.filter(\n (n): n is ItemDef | CheckboxItemDef | SubmenuDef | SubpageDef =>\n (n.kind === 'item' ||\n n.kind === 'checkbox-item' ||\n n.kind === 'submenu' ||\n n.kind === 'subpage') &&\n !n.hidden,\n )\n\n if (groupItems.length === 0) {\n return null\n }\n\n // Render group items - renderRowNode already wraps in keyed Fragment\n const groupChildren = groupItems.map((item) => {\n const itemContext: RowRenderContext = {\n search: null,\n breadcrumbs: [...context.breadcrumbs, submenuBreadcrumb],\n isDeepSearchResult: false,\n highlighted: false,\n disabled: item.disabled ?? false,\n group: { id: childNode.id, label: childNode.label },\n }\n\n return renderRowNode({ node: item, context: itemContext })\n })\n\n // Use custom group render if provided\n if (childNode.render) {\n const groupContext: GroupRenderContext = {\n search: null,\n matchCount: groupItems.length,\n breadcrumbs: [...context.breadcrumbs, submenuBreadcrumb],\n isDeepSearchResult: false,\n }\n return (\n <React.Fragment key={childNode.id}>\n {childNode.render({\n props: {},\n context: {\n ...groupContext,\n label: childNode.label,\n },\n children: <>{groupChildren}</>,\n })}\n </React.Fragment>\n )\n }\n\n // Default group rendering\n return (\n // biome-ignore lint/a11y/useSemanticElements: ignore for now\n <div\n key={childNode.id}\n role=\"group\"\n aria-label={childNode.label}\n >\n {groupChildren}\n </div>\n )\n }\n\n // Handle radio groups inside submenus\n if (childNode.kind === 'radio-group') {\n return renderRadioGroup(childNode, [\n ...context.breadcrumbs,\n submenuBreadcrumb,\n ])\n }\n\n // Handle items, checkbox items, submenus, and subpages\n if (\n childNode.kind !== 'item' &&\n childNode.kind !== 'checkbox-item' &&\n childNode.kind !== 'submenu' &&\n childNode.kind !== 'subpage'\n ) {\n return null\n }\n\n // Create context for child node (no deep search in submenu)\n const childContext: RowRenderContext = {\n search: null,\n breadcrumbs: [...context.breadcrumbs, submenuBreadcrumb],\n isDeepSearchResult: false,\n highlighted: false,\n disabled: childNode.disabled ?? false,\n group: null,\n }\n\n // renderRowNode already wraps in a keyed Fragment\n return renderRowNode({\n node: childNode,\n context: childContext,\n })\n }\n\n return (\n <React.Fragment key={compositeId}>\n {node.render({\n props: {\n id: compositeId,\n value: node.value,\n disabled: node.disabled ?? false,\n forceOrder: node.forceOrder,\n forceScore: node.forceScore,\n },\n context: {\n ...context,\n value: node.value,\n disabled: node.disabled ?? false,\n async: submenuAsyncState,\n },\n nodes: staticNodes,\n asyncContent: node.asyncNodes,\n renderNode: submenuRenderNode,\n })}\n </React.Fragment>\n )\n }\n\n if (node.kind === 'subpage') {\n const subpageAsyncState = getBranchAsyncState(node)\n const pageId = getSubpagePageId(node, context.breadcrumbs)\n\n return (\n <React.Fragment key={compositeId}>\n {node.renderTrigger({\n props: {\n id: compositeId,\n value: node.value,\n disabled: node.disabled ?? false,\n targetPageId: pageId,\n },\n context: {\n ...context,\n value: node.value,\n disabled: node.disabled ?? false,\n async: subpageAsyncState,\n },\n })}\n </React.Fragment>\n )\n }\n\n return null\n },\n [coordinator, normalizedSearch],\n )\n\n // Helper to render a radio group\n const renderRadioGroup = React.useCallback(\n (\n radioGroup: RadioGroupDef,\n breadcrumbs: BreadcrumbNode[] = [],\n ): React.ReactNode => {\n const isDeepSearchResult = breadcrumbs.length > 0\n\n // Build group context\n const groupContext: GroupRenderContext = {\n search: null,\n matchCount: radioGroup.nodes.length,\n breadcrumbs,\n isDeepSearchResult,\n }\n\n // Render children - renderRowNode already wraps in keyed Fragment\n const childElements = radioGroup.nodes.map((item) => {\n if (item.hidden) return null\n\n const itemContext: RowRenderContext = {\n search: null,\n breadcrumbs,\n isDeepSearchResult,\n highlighted: false,\n disabled: item.disabled ?? false,\n group: null,\n }\n\n return renderRowNode({\n node: item,\n context: itemContext,\n radioGroup: { id: radioGroup.id, label: radioGroup.label },\n })\n })\n\n // Use custom render if provided\n if (radioGroup.render) {\n return (\n <React.Fragment key={radioGroup.id}>\n {radioGroup.render({\n props: {\n value: radioGroup.value,\n onValueChange: radioGroup.onValueChange,\n disabled: radioGroup.disabled ?? false,\n },\n context: {\n ...groupContext,\n label: radioGroup.label,\n value: radioGroup.value,\n disabled: radioGroup.disabled ?? false,\n },\n children: <>{childElements}</>,\n })}\n </React.Fragment>\n )\n }\n\n // Minimal default: just render children with a wrapper\n return (\n <div\n key={radioGroup.id}\n role=\"radiogroup\"\n aria-label={radioGroup.label}\n >\n {childElements}\n </div>\n )\n },\n [renderRowNode],\n )\n\n // Build the renderNode function that handles groups, radio groups, and rows\n const renderNode: RenderNodeFn = React.useCallback(\n (displayNode: DisplayNode): React.ReactNode => {\n // Handle group display nodes\n if (isDisplayGroupNode(displayNode)) {\n const { group, context, items } = displayNode\n\n // Render children - renderRowNode already wraps in keyed Fragment\n const children = items.map((item) => renderRowNode(item))\n\n // Use custom render if provided\n if (group.render) {\n return (\n <React.Fragment key={group.id}>\n {group.render({\n props: {},\n context: {\n ...context,\n label: group.label,\n },\n children: <>{children}</>,\n })}\n </React.Fragment>\n )\n }\n\n // Minimal default: just render children with a wrapper\n return (\n // biome-ignore lint/a11y/useSemanticElements: ignore for now\n <div key={group.id} role=\"group\" aria-label={group.label}>\n {children}\n </div>\n )\n }\n\n // Handle radio group display nodes\n if (isDisplayRadioGroupNode(displayNode)) {\n const { radioGroup, context, items } = displayNode\n\n // Render children - renderRowNode already wraps in keyed Fragment\n const children = items.map((item) => renderRowNode(item))\n\n // Use custom render if provided\n if (radioGroup.render) {\n return (\n <React.Fragment key={radioGroup.id}>\n {radioGroup.render({\n props: {\n value: radioGroup.value,\n onValueChange: radioGroup.onValueChange,\n disabled: radioGroup.disabled ?? false,\n },\n context: {\n ...context,\n label: radioGroup.label,\n value: radioGroup.value,\n disabled: radioGroup.disabled ?? false,\n },\n children: <>{children}</>,\n })}\n </React.Fragment>\n )\n }\n\n // Minimal default: just render children with a wrapper\n return (\n <div\n key={radioGroup.id}\n role=\"radiogroup\"\n aria-label={radioGroup.label}\n >\n {children}\n </div>\n )\n }\n\n // Handle separator display nodes\n if (isDisplaySeparatorNode(displayNode)) {\n const { separator } = displayNode\n\n // Use custom render if provided\n if (separator.render) {\n return (\n <React.Fragment key={separator.id ?? 'separator'}>\n {separator.render({\n props: { id: separator.id },\n })}\n </React.Fragment>\n )\n }\n\n // Minimal default: render a div with role=\"none\"\n return <div key={separator.id ?? 'separator'} role=\"none\" />\n }\n\n // Handle row display nodes (items/checkbox items/submenus/subpages)\n // renderRowNode already wraps in keyed Fragment\n return renderRowNode(displayNode)\n },\n [renderRowNode],\n )\n\n // Get async state from coordinator\n const asyncState = React.useMemo(() => {\n if (!coordinator) {\n return {\n isLoading: false,\n isFetching: false,\n isInitialLoading: false,\n isRefetching: false,\n isAllRefetching: false,\n isStaticLoading: false,\n isStaticInitialLoading: false,\n isStaticRefetching: false,\n isQueryLoading: false,\n isQueryInitialLoading: false,\n isQueryRefetching: false,\n skippedMenus: [] as Array<{\n id: string\n reason: 'error'\n }>,\n }\n }\n return coordinator.getAsyncState()\n }, [coordinator, coordinator?.loaders, coordinator?.erroredLoaders])\n\n // Build children state\n const childrenState: DataListChildrenState = React.useMemo(\n () => ({\n search,\n nodes: displayNodes,\n renderNode,\n count: displayNodes.length,\n isDeepSearching,\n async: asyncState,\n }),\n [search, displayNodes, renderNode, isDeepSearching, asyncState],\n )\n\n const renderedChildren = children(childrenState)\n\n // Use PopupMenuList which handles keyboard navigation\n return (\n <>\n {/* Render async loaders (hidden, just for hook execution) */}\n {shouldRenderAsyncLoaders && (\n <>\n {/* Root async content loader */}\n <RootAsyncLoader query={normalizedSearch} />\n\n {/* Submenu async loaders */}\n {asyncSubmenus.map((info) => (\n <AsyncLoaderRenderer\n key={info.id}\n info={info}\n query={normalizedSearch}\n enabled={isDeepSearchActive}\n />\n ))}\n </>\n )}\n\n <PopupMenuList\n ref={forwardedRef}\n label={label}\n className={className}\n style={style}\n render={render}\n measureRowWidth={measureRowWidth}\n maxRowWidth={maxRowWidth}\n >\n {renderedChildren}\n </PopupMenuList>\n </>\n )\n },\n)\n\nexport namespace PopupMenuDataList {\n export interface Props extends PopupMenuDataListProps {}\n export type ChildrenState = DataListChildrenState\n}\n","import type * as React from 'react'\nimport type { PopupMenuCheckboxItemProps } from '../components/checkbox-item/checkbox-item.js'\nimport type { PopupMenuItemProps } from '../components/item/item.js'\nimport type { PopupMenuRadioGroupProps } from '../components/radio-group/radio-group.js'\nimport type { PopupMenuRadioItemProps } from '../components/radio-item/radio-item.js'\nimport type { PopupMenuSubmenuTriggerProps } from '../components/submenu-trigger/submenu-trigger.js'\nimport type { PopupMenuSubpageTriggerProps } from '../components/subpage-trigger/subpage-trigger.js'\n\n// ============================================================================\n// Async Loader Types\n// ============================================================================\n\n/**\n * Library-agnostic result from an async loader.\n * Compatible with TanStack Query, SWR, and custom loaders.\n */\nexport type AsyncLoaderSource = 'tanstack-query' | 'swr' | 'vanilla' | 'custom'\n\n/**\n * Canonical async loader status.\n * - 'idle': no request has been executed yet\n * - 'pending': request in progress and no successful data yet\n * - 'success': last resolved state has data\n * - 'error': last resolved state errored\n */\nexport type AsyncLoaderStatus = 'idle' | 'pending' | 'success' | 'error'\n\n/**\n * Canonical fetch status.\n */\nexport type AsyncLoaderFetchStatus = 'idle' | 'fetching' | 'paused'\n\n/**\n * Loading phase for distinguishing first-load from background revalidation.\n */\nexport type AsyncLoaderLoadingPhase = 'none' | 'initial' | 'background'\n\nexport interface AsyncLoaderResult<TData, TRaw = unknown> {\n /** The loaded data, undefined while loading or on error */\n data: TData | undefined\n\n /** Raw result object returned by the underlying data library */\n raw?: TRaw\n\n /** Source data library backing this result */\n source?: AsyncLoaderSource\n\n /** Error if the load failed, null otherwise */\n error: Error | null\n\n /** Canonical status state */\n status: AsyncLoaderStatus\n\n /** Canonical fetch state */\n fetchStatus: AsyncLoaderFetchStatus\n\n /** Distinguishes initial load vs background fetch */\n loadingPhase: AsyncLoaderLoadingPhase\n\n /** True during the initial loading phase (TanStack-aligned semantics) */\n isLoading: boolean\n\n /** Whether any fetch is currently in-flight */\n isFetching: boolean\n\n /** Alias of `isLoading` for explicit phase naming */\n isInitialLoading: boolean\n\n /** True when background re-fetch is in-flight */\n isRefetching: boolean\n\n /** Whether query state is pending */\n isPending: boolean\n\n /** Whether query state is successful */\n isSuccess: boolean\n\n /** Whether the loader encountered an error */\n isError: boolean\n\n /** Whether fetching is paused */\n isPaused: boolean\n\n /** Whether data is currently available */\n hasData: boolean\n\n /** Whether any fetch has completed at least once */\n hasFetched: boolean\n\n /** Optional function to refetch the data */\n refetch?: () => unknown\n}\n\n/**\n * Props passed to loader components.\n * The component should call hooks internally and pass the result to children.\n */\nexport interface LoaderComponentProps {\n /** Search query (for query-dependent loaders) */\n query: string\n /** Whether the loader should execute its fetch/query hook */\n enabled?: boolean\n /** Render function receiving loader state */\n children: (state: AsyncLoaderResult<NodeDef[]>) => React.ReactNode\n}\n\n/**\n * Controls query-loader behavior before users type an active query.\n */\nexport interface InitialQueryBehavior {\n /**\n * Query value used before user input reaches minQueryLength.\n * Defaults to '' (top/default results).\n * @default ''\n */\n value?: string\n /**\n * When the initial query should load.\n * - 'needed': when submenu is explicitly opened or needed for deep-search execution\n * - 'parent-open': eagerly when direct parent opens\n * @default 'needed'\n */\n loadWhen?: 'needed' | 'parent-open'\n}\n\n/**\n * Static loader configuration.\n * Loads data once, then filters client-side.\n */\nexport interface StaticLoaderConfig {\n type: 'static'\n /**\n * Component that calls hooks and provides loader state.\n * This component pattern allows hooks to be called legally within React's rules.\n */\n Loader: React.ComponentType<LoaderComponentProps>\n /**\n * When to trigger the loader:\n * - 'eager': Load when menu opens (good for deep search)\n * - 'lazy': Load when submenu opens (default)\n * @default 'lazy'\n */\n loadStrategy?: 'eager' | 'lazy'\n}\n\n/**\n * Query-dependent loader configuration.\n * Refetches based on search query - server does the filtering.\n */\nexport interface QueryDependentLoaderConfig {\n type: 'query'\n /**\n * Component that calls hooks and provides loader state.\n * Receives the current search query as a prop.\n */\n Loader: React.ComponentType<LoaderComponentProps>\n /**\n * Minimum query length before fetching.\n * @default 1\n */\n minQueryLength?: number\n /**\n * Defines behavior before user query reaches minQueryLength.\n * - object: executes query loader with the configured initial value (default behavior)\n * - false: disables initial fetch until query reaches minQueryLength\n * @default { value: '', loadWhen: 'needed' }\n */\n initialQueryBehavior?: InitialQueryBehavior | false\n /**\n * @deprecated Use `initialQueryBehavior` instead.\n */\n initialQuery?: string\n /**\n * When to trigger the loader:\n * - 'eager': Load when root menu opens (good for deep search)\n * - 'lazy': Load when submenu opens (default)\n * @default 'lazy'\n */\n loadStrategy?: 'eager' | 'lazy'\n /**\n * What to show when query is below minQueryLength.\n * - 'empty': Show nothing\n * - 'placeholder': Show placeholderNodes\n * @default 'empty'\n */\n belowMinBehavior?: 'empty' | 'placeholder'\n /**\n * Placeholder nodes shown when query is below minQueryLength.\n */\n placeholderNodes?: NodeDef[]\n}\n\n/**\n * Controls how submenu content participates in ancestor deep search results.\n * - `true`: include submenu trigger and descendants\n * - `'trigger-only'`: include submenu trigger only\n * - `false`: exclude submenu trigger and descendants\n */\nexport type IncludeInDeepSearch = true | 'trigger-only' | false\n\n/**\n * Union of all async loader configurations.\n */\nexport type AsyncLoaderConfig = StaticLoaderConfig | QueryDependentLoaderConfig\n\n/**\n * Static async nodes configuration for submenus.\n */\nexport type StaticAsyncNodesConfig = StaticLoaderConfig\n\n/**\n * Query-dependent async nodes configuration for submenus.\n */\nexport type QueryAsyncNodesConfig = QueryDependentLoaderConfig\n\n/**\n * Async nodes configuration for submenus.\n * Union of static and query-dependent loader configs.\n */\nexport type AsyncNodesConfig = StaticAsyncNodesConfig | QueryAsyncNodesConfig\n\n/**\n * Async state exposed to submenu render functions.\n */\nexport interface AsyncRenderState {\n /** Canonical status state */\n status: AsyncLoaderStatus\n /** Canonical fetch state */\n fetchStatus: AsyncLoaderFetchStatus\n /** Distinguishes initial load vs background fetch */\n loadingPhase: AsyncLoaderLoadingPhase\n /** True during the initial loading phase */\n isLoading: boolean\n /** Whether any fetch is currently in-flight */\n isFetching: boolean\n /** Alias of `isLoading` for explicit phase naming */\n isInitialLoading: boolean\n /** True when background re-fetch is in-flight */\n isRefetching: boolean\n /** Whether the loader encountered an error */\n isError: boolean\n /** The error if any */\n error: Error | null\n /** For query loaders: whether query is below minQueryLength */\n isBelowMinLength?: boolean\n}\n\n/**\n * Aggregate async state exposed to DataList children.\n */\nexport interface AsyncState {\n /** Any loader is currently in initial loading phase */\n isLoading: boolean\n\n /** Any loader is currently fetching */\n isFetching: boolean\n\n /** Any loader is in first-load phase */\n isInitialLoading: boolean\n\n /** Any loader is in background refetch phase */\n isRefetching: boolean\n\n /** All registered loaders are in background refetch phase */\n isAllRefetching: boolean\n\n /** Static loaders specifically are loading */\n isStaticLoading: boolean\n\n /** Static loaders in first-load phase */\n isStaticInitialLoading: boolean\n\n /** Static loaders in background refetch phase */\n isStaticRefetching: boolean\n\n /** Query loaders specifically are loading */\n isQueryLoading: boolean\n\n /** Query loaders in first-load phase */\n isQueryInitialLoading: boolean\n\n /** Query loaders in background refetch phase */\n isQueryRefetching: boolean\n\n /** Menus that failed (skipped from results) */\n skippedMenus: Array<{ id: string; reason: 'error' }>\n}\n\n// ============================================================================\n// getQualifiedRowId - Unique ID Generation\n// ============================================================================\n\n/**\n * Branch node info passed in breadcrumbs context.\n * Contains the full submenu/subpage definition for maximum flexibility.\n */\nexport interface BreadcrumbNode {\n /** The branch node definition */\n node: SubmenuDef | SubpageDef\n /** The branch node's value */\n value: string\n /** The branch node's explicit id (if provided) */\n id?: string\n}\n\n/**\n * Context passed to the getQualifiedRowId function.\n * Provides all information needed to generate a unique ID for a row.\n */\nexport interface GetQualifiedRowIdContext {\n /** The node definition */\n node: ItemDef | RadioItemDef | CheckboxItemDef | SubmenuDef | SubpageDef\n\n /** The node's value (node.value) - used for search/filtering and as fallback identifier */\n value: string\n\n /** The node's explicit id (node.id) - if provided, treated as globally unique */\n id: string | undefined\n\n /** Position in the flattened display list (0-based) */\n index: number\n\n /**\n * Breadcrumb nodes from root to parent.\n * Contains full submenu/subpage node definitions for maximum flexibility.\n */\n breadcrumbs: BreadcrumbNode[]\n\n /** Whether deep search is currently active (search query meets minLength threshold) */\n isDeepSearching: boolean\n\n /** Search context, null if browsing */\n search: { query: string; score: number } | null\n\n /** Whether surfaced via deep search (rendered outside its home menu) */\n isDeepSearchResult: boolean\n\n /** Group context, if any */\n group: { id: string; label?: string } | null\n\n /** Radio group context, if any */\n radioGroup: { id: string; label?: string } | null\n}\n\n/**\n * Function that generates a unique qualified ID for a row.\n * Used for React keys, store registration, and DOM id attributes.\n *\n * Default behavior:\n * - If node.id is provided, use it as-is (treat as globally unique)\n * - Otherwise, compute from breadcrumbs + value when deep searching\n *\n * @example\n * ```ts\n * // Custom implementation\n * const getQualifiedRowId: GetQualifiedRowIdFn = (ctx) => {\n * // Use explicit id if provided\n * if (ctx.id) return ctx.id\n *\n * // Otherwise, build from breadcrumbs + value\n * const path = ctx.breadcrumbs.map(b => b.id ?? slugify(b.value))\n * return [...path, slugify(ctx.value)].join('.')\n * }\n * ```\n */\nexport type GetQualifiedRowIdFn = (context: GetQualifiedRowIdContext) => string\n\n// ============================================================================\n// Render Context - passed to all render functions\n// ============================================================================\n\n/**\n * Context passed to item, submenu, and subpage render functions.\n * Provides information about the current rendering context (search, breadcrumbs, state).\n */\nexport interface RowRenderContext {\n /**\n * Search context - the query in the menu where this row is being rendered.\n * `null` if no active search (browsing mode).\n */\n search: {\n /** Current search query */\n query: string\n /** Match score for this row (higher = better match). */\n score: number\n } | null\n\n /**\n * Full path of branch nodes from root to this row's parent.\n * Contains the full submenu/subpage node definitions for maximum flexibility.\n * Empty array [] for items directly in root menu.\n */\n breadcrumbs: BreadcrumbNode[]\n\n /**\n * True if this row is being rendered outside its \"home\" menu\n * (surfaced via deep search from an ancestor menu).\n */\n isDeepSearchResult: boolean\n\n /** Whether this row is currently highlighted/focused */\n highlighted: boolean\n\n /** Whether this row is disabled */\n disabled: boolean\n\n /**\n * The group this item belongs to, if any.\n * `null` if the item is not inside a group.\n */\n group: { id: string; label?: string } | null\n}\n\n// ============================================================================\n// Item Render Params\n// ============================================================================\n\n/**\n * Props to spread onto the Item component.\n * Derived from PopupMenuItemProps.\n */\nexport type ItemRenderProps = {\n /**\n * Qualified unique ID for the item.\n * Must be passed to the rendered component for navigation to work.\n * This is the computed qualified ID (includes breadcrumb path for deep search results).\n */\n id: string\n /**\n * The original value from the node definition.\n * Use this for display, search matching, or any logic that needs the raw value.\n */\n value: string\n} & Required<Pick<PopupMenuItemProps, 'disabled'>> &\n Pick<\n PopupMenuItemProps,\n 'closeOnClick' | 'onSelect' | 'shortcut' | 'forceOrder' | 'forceScore'\n >\n\n/**\n * Parameters passed to item render functions.\n */\nexport interface ItemRenderParams {\n /** Props to spread onto the Item component */\n props: ItemRenderProps\n /** Context for conditional rendering (includes props values for convenience) */\n context: RowRenderContext & {\n /** The node's value (ItemDef.value) */\n value: string\n disabled: boolean\n }\n}\n\n// ============================================================================\n// Radio Item Render Params\n// ============================================================================\n\n/**\n * Props to spread onto the RadioItem component.\n * Derived from PopupMenuRadioItemProps.\n */\nexport type RadioItemRenderProps = {\n /**\n * Qualified unique ID for the radio item.\n * Must be passed to the rendered component for navigation to work.\n */\n id: string\n} & Required<Pick<PopupMenuRadioItemProps, 'value' | 'disabled'>> &\n Pick<\n PopupMenuRadioItemProps,\n 'closeOnClick' | 'onSelect' | 'shortcut' | 'forceOrder' | 'forceScore'\n >\n\n/**\n * Parameters passed to radio item render functions.\n */\nexport interface RadioItemRenderParams {\n /** Props to spread onto the RadioItem component */\n props: RadioItemRenderProps\n /** Context for conditional rendering (includes props values for convenience) */\n context: RowRenderContext & {\n /** The node's value (RadioItemDef.value) */\n value: string\n disabled: boolean\n }\n}\n\n// ============================================================================\n// Submenu Render Params\n// ============================================================================\n\n/**\n * Props to spread onto the SubmenuTrigger component.\n * Derived from PopupMenuSubmenuTriggerProps.\n */\nexport type SubmenuRenderProps = {\n /**\n * Qualified unique ID for the submenu trigger.\n * Must be passed to the rendered component for navigation to work.\n */\n id: string\n /**\n * The original value from the node definition.\n */\n value: string\n} & Required<Pick<PopupMenuSubmenuTriggerProps, 'disabled'>> &\n Pick<PopupMenuSubmenuTriggerProps, 'forceOrder' | 'forceScore'>\n\n/**\n * Parameters passed to submenu render functions.\n * Includes context plus the submenu's child nodes and render function.\n */\nexport interface SubmenuRenderParams {\n /** Props to spread onto the SubmenuTrigger */\n props: SubmenuRenderProps\n /** Context for conditional rendering (includes props values for convenience) */\n context: RowRenderContext & {\n /** The node's value (SubmenuDef.value) */\n value: string\n disabled: boolean\n /** Async loading state (if asyncNodes configured) */\n async?: AsyncRenderState\n }\n /**\n * The submenu's static child node definitions.\n * Does NOT include async results - use `asyncContent` for that.\n */\n nodes: NodeDef[]\n /**\n * Async content configuration for this submenu.\n * Pass this to the submenu's DataSurface to enable async loading\n * with the submenu's own search query (independent of parent search).\n */\n asyncContent?: AsyncNodesConfig\n /**\n * Function to render a child node.\n * Call this for each node in the submenu's list.\n */\n renderNode: (node: NodeDef) => React.ReactNode\n}\n\n// ============================================================================\n// Subpage Render Types\n// ============================================================================\n\n/**\n * Props to spread onto the SubpageTrigger component.\n * Derived from PopupMenuSubpageTriggerProps.\n */\nexport type SubpageTriggerRenderProps = {\n /**\n * Qualified unique ID for the subpage trigger.\n * Must be passed to the rendered component for navigation to work.\n */\n id: string\n /**\n * The original value from the node definition.\n */\n value: string\n /**\n * Computed page ID for the associated Subpage content.\n * Must be passed to `targetPageId` on SubpageTrigger.\n */\n targetPageId: string\n} & Required<Pick<PopupMenuSubpageTriggerProps, 'disabled'>>\n\n/**\n * Parameters passed to subpage trigger render functions.\n */\nexport interface SubpageTriggerRenderParams {\n /** Props to spread onto the SubpageTrigger */\n props: SubpageTriggerRenderProps\n /** Context for conditional rendering (includes props values for convenience) */\n context: RowRenderContext & {\n /** The node's value (SubpageDef.value) */\n value: string\n disabled: boolean\n /** Async loading state (if asyncNodes configured) */\n async?: AsyncRenderState\n }\n}\n\n/**\n * Parameters passed to subpage content render functions.\n * The returned JSX should include a `<PopupMenu.Subpage pageId={pageId}>` wrapper.\n */\nexport interface SubpageContentRenderParams {\n /** Computed page ID for this subpage */\n pageId: string\n /** Context for conditional rendering */\n context: RowRenderContext & {\n /** The node's value (SubpageDef.value) */\n value: string\n disabled: boolean\n /** Async loading state (if asyncNodes configured) */\n async?: AsyncRenderState\n }\n /**\n * The subpage's static child node definitions.\n * Does NOT include async results - use `asyncContent` for that.\n */\n nodes: NodeDef[]\n /**\n * Async content configuration for this subpage.\n * Pass this to the subpage's DataSurface to enable async loading\n * with the subpage's own search query (independent of parent search).\n */\n asyncContent?: AsyncNodesConfig\n /**\n * Function to render a child node.\n * Call this for each node in the subpage's list.\n */\n renderNode: (node: NodeDef) => React.ReactNode\n}\n\n// ============================================================================\n// Group Render Types\n// ============================================================================\n\n/**\n * Context passed to group render functions.\n * Contains information about the group's state during search.\n */\nexport interface GroupRenderContext {\n /**\n * Search context with the best match score among items in this group.\n * `null` if no active search (browsing mode).\n */\n search: {\n /** Current search query */\n query: string\n /** Best match score among items in this group (higher = better match). */\n bestScore: number\n } | null\n\n /** Number of matching items in this group */\n matchCount: number\n\n /**\n * Breadcrumb nodes if this group is from a surfaced submenu.\n * Empty array [] for groups in the root menu.\n */\n breadcrumbs: BreadcrumbNode[]\n\n /** Whether this group is from deep search (surfaced from a submenu) */\n isDeepSearchResult: boolean\n}\n\n/**\n * Parameters passed to group render functions.\n */\nexport interface GroupRenderParams {\n /** Props (empty for groups, but consistent structure) */\n props: Record<string, never>\n /** Context for conditional rendering (includes label for convenience) */\n context: GroupRenderContext & {\n /** The group's label */\n label?: string\n }\n /** Pre-rendered matching children */\n children: React.ReactNode\n}\n\n// ============================================================================\n// Checkbox Item Types\n// ============================================================================\n\n/**\n * Props to spread onto the CheckboxItem component.\n * Derived from PopupMenuCheckboxItemProps.\n */\nexport type CheckboxItemRenderProps = {\n /**\n * Qualified unique ID for the checkbox item.\n * Must be passed to the rendered component for navigation to work.\n */\n id: string\n /**\n * The original value from the node definition.\n */\n value: string\n} & Required<Pick<PopupMenuCheckboxItemProps, 'disabled'>> &\n Pick<\n PopupMenuCheckboxItemProps,\n 'checked' | 'onCheckedChange' | 'closeOnClick' | 'forceOrder' | 'forceScore'\n >\n\n/**\n * Parameters passed to checkbox item render functions.\n */\nexport interface CheckboxItemRenderParams {\n /** Props to spread onto the CheckboxItem component */\n props: CheckboxItemRenderProps\n /** Context for conditional rendering (includes props values for convenience) */\n context: RowRenderContext & {\n /** The node's value (CheckboxItemDef.value) */\n value: string\n checked?: boolean\n disabled: boolean\n }\n}\n\n// ============================================================================\n// Radio Group Types\n// ============================================================================\n\n/**\n * Props to spread onto the RadioGroup component.\n * Derived from PopupMenuRadioGroupProps.\n */\nexport type RadioGroupRenderProps = Required<\n Pick<PopupMenuRadioGroupProps, 'disabled'>\n> &\n Pick<PopupMenuRadioGroupProps, 'value' | 'onValueChange'>\n\n/**\n * Parameters passed to radio group render functions.\n */\nexport interface RadioGroupRenderParams {\n /** Props to spread onto the RadioGroup component */\n props: RadioGroupRenderProps\n /** Context for conditional rendering */\n context: GroupRenderContext & {\n /** The radio group's label */\n label?: string\n /** Current selected value */\n value?: string\n /** Whether the radio group is disabled */\n disabled: boolean\n }\n /** Pre-rendered radio items */\n children: React.ReactNode\n}\n\n// ============================================================================\n// Node Definitions\n// ============================================================================\n\n/**\n * Base properties shared by all node types.\n */\ninterface BaseNodeDef {\n /**\n * Unique identifier for this node.\n * If not provided, a composite ID is generated from the `value` and breadcrumbs\n * using the `getItemId` function.\n */\n id?: string\n /** Whether this node is hidden */\n hidden?: boolean\n}\n\n/**\n * Item node definition.\n * Represents a selectable menu item.\n * Props derived from PopupMenuItemProps.\n */\nexport interface ItemDef\n extends BaseNodeDef,\n Required<Pick<PopupMenuItemProps, 'value'>>,\n Pick<\n PopupMenuItemProps,\n | 'keywords'\n | 'disabled'\n | 'onSelect'\n | 'closeOnClick'\n | 'shortcut'\n | 'forceOrder'\n | 'forceScore'\n > {\n kind: 'item'\n /**\n * Render function for this item row.\n * Returns the JSX for the item.\n */\n render: (params: ItemRenderParams) => React.ReactNode\n}\n\n/**\n * Radio item node definition.\n * Represents a selectable radio menu item for use within RadioGroupDef.\n * Props derived from PopupMenuRadioItemProps.\n */\nexport interface RadioItemDef\n extends BaseNodeDef,\n Required<Pick<PopupMenuRadioItemProps, 'value'>>,\n Pick<\n PopupMenuRadioItemProps,\n | 'keywords'\n | 'disabled'\n | 'onSelect'\n | 'closeOnClick'\n | 'shortcut'\n | 'forceOrder'\n | 'forceScore'\n > {\n kind: 'radio-item'\n /**\n * Render function for this radio item row.\n * Returns the JSX for the radio item.\n */\n render: (params: RadioItemRenderParams) => React.ReactNode\n}\n\n/**\n * Checkbox item node definition.\n * Represents a toggleable checkbox menu item.\n * Props derived from PopupMenuCheckboxItemProps.\n */\nexport interface CheckboxItemDef\n extends BaseNodeDef,\n Pick<\n PopupMenuCheckboxItemProps,\n | 'keywords'\n | 'disabled'\n | 'checked'\n | 'onCheckedChange'\n | 'closeOnClick'\n | 'forceOrder'\n | 'forceScore'\n > {\n kind: 'checkbox-item'\n /**\n * Primary identifier and search text for this checkbox item.\n * Used for search matching and as the default identifier.\n */\n value: string\n /**\n * Render function for this checkbox item row.\n * Returns the JSX for the checkbox item.\n */\n render: (params: CheckboxItemRenderParams) => React.ReactNode\n}\n\n/**\n * Submenu node definition.\n * Represents a submenu trigger that opens a nested menu.\n * Props derived from PopupMenuSubmenuTriggerProps.\n */\nexport interface SubmenuDef\n extends BaseNodeDef,\n Required<Pick<PopupMenuSubmenuTriggerProps, 'value'>>,\n Pick<\n PopupMenuSubmenuTriggerProps,\n 'keywords' | 'disabled' | 'forceOrder' | 'forceScore'\n > {\n kind: 'submenu'\n\n /** Static child nodes */\n nodes?: NodeDef[]\n\n /**\n * Async child nodes configuration.\n * When provided, the Loader component will be rendered to fetch async data.\n * Async nodes are merged with static nodes.\n */\n asyncNodes?: AsyncNodesConfig\n\n /**\n * Whether to include this submenu's descendants in deep search.\n * @default true\n */\n deepSearch?: boolean\n\n /**\n * Whether this submenu is included in ancestor deep search results.\n * - `true`: include submenu trigger and descendants\n * - `'trigger-only'`: include submenu trigger only\n * - `false`: exclude submenu trigger and descendants\n * @default true\n */\n includeInDeepSearch?: IncludeInDeepSearch\n\n /**\n * Render function for the entire submenu structure.\n * Should return the complete submenu: trigger, portal, positioner, popup, surface, list.\n */\n render: (params: SubmenuRenderParams) => React.ReactNode\n}\n\n/**\n * Subpage node definition.\n * Represents a trigger row that opens a page in the same popup.\n * Props derived from PopupMenuSubpageTriggerProps.\n */\nexport interface SubpageDef\n extends BaseNodeDef,\n Required<Pick<PopupMenuSubpageTriggerProps, 'value'>>,\n Pick<\n PopupMenuSubpageTriggerProps,\n 'keywords' | 'disabled' | 'forceOrder' | 'forceScore'\n > {\n kind: 'subpage'\n\n /**\n * Optional explicit page ID for this subpage.\n * If omitted, a deterministic page ID is generated from id/value + breadcrumbs.\n */\n pageId?: string\n\n /** Static child nodes */\n nodes?: NodeDef[]\n\n /**\n * Async child nodes configuration.\n * When provided, the Loader component will be rendered to fetch async data.\n * Async nodes are merged with static nodes.\n */\n asyncNodes?: AsyncNodesConfig\n\n /**\n * Whether to include this subpage's descendants in deep search.\n * @default true\n */\n deepSearch?: boolean\n\n /**\n * Whether this subpage is included in ancestor deep search results.\n * - `true`: include subpage trigger and descendants\n * - `'trigger-only'`: include subpage trigger only\n * - `false`: exclude subpage trigger and descendants\n * @default true\n */\n includeInDeepSearch?: IncludeInDeepSearch\n\n /**\n * Render function for the trigger row.\n * Should return a `SubpageTrigger`.\n */\n renderTrigger: (params: SubpageTriggerRenderParams) => React.ReactNode\n\n /**\n * Render function for the subpage content.\n * Should return a `Subpage` rendered alongside the root Surface in Popup.\n */\n renderContent: (params: SubpageContentRenderParams) => React.ReactNode\n}\n\n/**\n * Render params for separator nodes.\n */\nexport interface SeparatorRenderParams {\n /** Props to spread on the separator element */\n props: {\n /** Unique identifier */\n id?: string\n }\n}\n\n/**\n * Separator node definition.\n * Represents a visual separator between items.\n */\nexport interface SeparatorDef {\n kind: 'separator'\n /** Optional identifier */\n id?: string\n /** Optional render function for custom separator rendering */\n render?: (params: SeparatorRenderParams) => React.ReactNode\n}\n\n/**\n * Group node definition.\n * Represents a group of items with an optional label.\n */\nexport interface GroupDef {\n kind: 'group'\n /** Unique identifier for this group */\n id: string\n /** Optional group heading/label */\n label?: string\n /** Child nodes in this group */\n nodes: NodeDef[]\n /** Optional render function for the group container */\n render?: (params: GroupRenderParams) => React.ReactNode\n}\n\n/**\n * Radio group node definition.\n * Represents a group of radio items where only one can be selected.\n * Props derived from PopupMenuRadioGroupProps.\n */\nexport interface RadioGroupDef\n extends Pick<\n PopupMenuRadioGroupProps,\n 'value' | 'onValueChange' | 'disabled'\n > {\n kind: 'radio-group'\n /** Unique identifier for this radio group */\n id: string\n /** Optional group heading/label */\n label?: string\n /** Whether the radio group is hidden */\n hidden?: boolean\n /** Child nodes in this radio group - must be RadioItemDef nodes */\n nodes: RadioItemDef[]\n /** Optional render function for the radio group container */\n render?: (params: RadioGroupRenderParams) => React.ReactNode\n}\n\n/**\n * Helper function to create a radio group definition with proper typing.\n */\nexport function defineRadioGroup(def: RadioGroupDef): RadioGroupDef {\n return def\n}\n\n/**\n * Union of all node definition types.\n */\nexport type NodeDef =\n | ItemDef\n | RadioItemDef\n | CheckboxItemDef\n | SubmenuDef\n | SubpageDef\n | SeparatorDef\n | GroupDef\n | RadioGroupDef\n\n// ============================================================================\n// Scored Node - internal type for search results\n// ============================================================================\n\n/**\n * A node with its search score and breadcrumb path.\n * Used internally during filtering and scoring.\n */\nexport interface ScoredNode {\n /** The original node definition */\n node: ItemDef | RadioItemDef | CheckboxItemDef | SubmenuDef | SubpageDef\n /** Search match score (higher = better match). */\n score: number\n /**\n * Breadcrumb nodes leading to this node.\n * Contains the full submenu definitions for maximum flexibility.\n */\n breadcrumbs: BreadcrumbNode[]\n /** The group this node belongs to, if any */\n group: { id: string; label?: string; groupDef: GroupDef } | null\n /** The radio group this node belongs to, if any */\n radioGroup: {\n id: string\n label?: string\n radioGroupDef: RadioGroupDef\n } | null\n}\n\n// ============================================================================\n// Display Node - node with render context attached\n// ============================================================================\n\n/**\n * A row node ready for display with its render context.\n * Used for items, radio items, checkbox items, and submenu triggers.\n */\nexport interface DisplayRowNode {\n /** The original node definition */\n node: ItemDef | RadioItemDef | CheckboxItemDef | SubmenuDef | SubpageDef\n /** Pre-computed render context for this node */\n context: RowRenderContext\n /** Radio group this node belongs to, if rendering inside one */\n radioGroup?: { id: string; label?: string }\n /**\n * Computed composite ID for this node.\n * Includes breadcrumb path for deep search results (e.g., \"status.in-progress\").\n * Set after filtering via `computeItemIds`.\n */\n compositeId?: string\n}\n\n/**\n * A subpage content node ready for display with its render context.\n * Used by DataSubpages to render subpage content alongside the root Surface.\n */\nexport interface DisplaySubpageNode {\n /** The original subpage definition */\n node: SubpageDef\n /** Pre-computed render context for this subpage trigger/content */\n context: RowRenderContext\n /** Computed page ID for this subpage */\n pageId: string\n}\n\n/**\n * A group node ready for display with its render context.\n * Contains the group definition and its matching items.\n */\nexport interface DisplayGroupNode {\n kind: 'group'\n /** The group definition */\n group: GroupDef\n /** Pre-computed render context for this group */\n context: GroupRenderContext\n /** Display nodes for items within this group */\n items: DisplayRowNode[]\n /** Best match score among items in this group */\n bestScore: number\n}\n\n/**\n * A radio group node ready for display with its render context.\n * Contains the radio group definition and its items.\n */\nexport interface DisplayRadioGroupNode {\n kind: 'radio-group'\n /** The radio group definition */\n radioGroup: RadioGroupDef\n /** Pre-computed render context for this radio group */\n context: GroupRenderContext\n /** Display nodes for items within this radio group */\n items: DisplayRowNode[]\n /** Best match score among items in this radio group */\n bestScore: number\n}\n\n/**\n * A separator node ready for display.\n */\nexport interface DisplaySeparatorNode {\n kind: 'separator'\n /** The separator definition */\n separator: SeparatorDef\n}\n\n/**\n * Union of all display node types.\n * Can be a row node (item/submenu/subpage), group node, radio group node, or separator.\n */\nexport type DisplayNode =\n | DisplayRowNode\n | DisplayGroupNode\n | DisplayRadioGroupNode\n | DisplaySeparatorNode\n\n/**\n * Type guard for DisplayGroupNode.\n */\nexport function isDisplayGroupNode(\n node: DisplayNode,\n): node is DisplayGroupNode {\n return 'kind' in node && node.kind === 'group'\n}\n\n/**\n * Type guard for DisplayRadioGroupNode.\n */\nexport function isDisplayRadioGroupNode(\n node: DisplayNode,\n): node is DisplayRadioGroupNode {\n return 'kind' in node && node.kind === 'radio-group'\n}\n\n/**\n * Type guard for DisplaySeparatorNode.\n */\nexport function isDisplaySeparatorNode(\n node: DisplayNode,\n): node is DisplaySeparatorNode {\n return 'kind' in node && node.kind === 'separator'\n}\n\n/**\n * Type guard for DisplayRowNode (items, checkbox items, submenus, subpages).\n */\nexport function isDisplayRowNode(node: DisplayNode): node is DisplayRowNode {\n return !('kind' in node)\n}\n\n// ============================================================================\n// Deep Search Configuration\n// ============================================================================\n\n/**\n * Defines how groups behave during deep search.\n * - 'flatten': Groups become invisible, items shown in flat list by score.\n * - 'preserve': Groups are shown as containers with their matching items.\n * Note: Radio groups are ALWAYS preserved regardless of this setting.\n */\nexport type GroupBehavior = 'flatten' | 'preserve'\n\n/**\n * Defines how radio groups behave during deep search.\n * - 'flatten': Radio group items are shown individually in the flat list (not recommended).\n * - 'preserve': Radio group is shown with only matching items visible.\n * - 'preserve-show-all': Radio group is shown with ALL items visible when any item matches.\n * This is useful when you want users to see all options in a radio group.\n */\nexport type RadioGroupBehavior = 'flatten' | 'preserve' | 'preserve-show-all'\n\n/**\n * Defines how deep-search async results are revealed.\n * - 'stream': show available results immediately and append new async batches as they resolve.\n * - 'block': hide all deep-search rows until every participating async loader resolves.\n */\nexport type AsyncResultBehavior = 'stream' | 'block'\n\n/**\n * Configuration for deep search behavior.\n */\nexport interface DeepSearchConfig {\n /** Whether deep search is enabled */\n enabled?: boolean\n /** Minimum query length before deep search activates */\n minLength?: number\n /**\n * How groups behave during search results.\n * Only affects search mode - groups are always shown in browse mode.\n * Note: Radio groups have their own behavior controlled by radioGroupSearchBehavior.\n * @default 'preserve'\n */\n groupSearchBehavior?: GroupBehavior\n /**\n * How radio groups behave during search results.\n * - 'flatten': Radio items shown individually (not recommended).\n * - 'preserve': Only matching radio items are shown (default).\n * - 'preserve-show-all': All radio items are shown when any item matches.\n * @default 'preserve'\n */\n radioGroupSearchBehavior?: RadioGroupBehavior\n /**\n * Whether to sort groups by their best-matching item's score.\n * Only applies when groupSearchBehavior: 'preserve'.\n * @default true\n */\n sortGroups?: boolean\n /**\n * How async deep-search results are revealed.\n * - 'stream': emit available results immediately, append later async batches (default)\n * - 'block': show loading state only until all loaders resolve, then render once\n * @default 'stream'\n */\n asyncResultBehavior?: AsyncResultBehavior\n}\n\n// ============================================================================\n// Data Surface Props\n// ============================================================================\n\n/**\n * Props for the DataSurface component.\n */\nexport interface DataSurfaceProps {\n /** The menu content (node definitions with render functions) */\n content?: NodeDef[]\n\n /**\n * Async content configuration for root-level async loading.\n * When provided, the Loader component will be rendered to fetch async data.\n * Async content is merged with static content.\n */\n asyncContent?: AsyncLoaderConfig\n\n /** Deep search configuration */\n deepSearch?: DeepSearchConfig | boolean\n\n /**\n * Default inclusion mode for descendant branch nodes in deep search results.\n * Submenus/subpages can override via `includeInDeepSearch`.\n * @default true\n */\n includeInDeepSearch?: IncludeInDeepSearch\n\n /** Filter function or false to disable filtering */\n filter?:\n | ((value: string, search: string, keywords?: string[]) => number)\n | false\n\n /**\n * Transforms search input before filtering and visibility logic.\n * @default trim whitespace (`search.trim()`)\n */\n normalizeSearch?: (search: string) => string\n\n /** Controlled search value */\n search?: string\n\n /** Callback when search value changes */\n onSearchChange?: (search: string) => void\n\n /** Default search value for uncontrolled usage */\n defaultSearch?: string\n\n /** Whether navigation should loop */\n loop?: boolean\n\n /** Auto-highlight behavior when menu opens */\n autoHighlightFirst?: boolean | string\n\n /**\n * Whether to clear search on close.\n * - `true`: clear immediately when menu closes (default)\n * - `false`: preserve search when menu closes\n * - `'after-exit'`: clear after exit animation completes\n */\n clearSearchOnClose?: boolean | 'after-exit'\n\n /**\n * Function to generate qualified IDs for row items.\n * Called for each item when rendering to produce IDs for:\n * - React keys\n * - Store registration\n * - DOM id attributes\n *\n * @default Uses node.id if provided, otherwise qualifies with breadcrumbs + slugified value\n */\n getQualifiedRowId?: GetQualifiedRowIdFn\n\n /** Children (Input, List, etc.) */\n children: React.ReactNode\n}\n\n// ============================================================================\n// Data List Props\n// ============================================================================\n\n/**\n * State passed to the DataList render function.\n */\nexport interface DataListChildrenState {\n /** Current search query (empty string if browsing) */\n search: string\n\n /**\n * Display nodes (filtered and scored if searching).\n * Can include groups (DisplayGroupNode) or radio groups (DisplayRadioGroupNode)\n * when groupSearchBehavior: 'preserve'.\n */\n nodes: DisplayNode[]\n\n /**\n * Function to render a node.\n * Handles items, submenus, groups, and radio groups, calling their render functions with context.\n */\n renderNode: (displayNode: DisplayNode) => React.ReactNode\n\n /** Number of visible items (counting items inside groups) */\n count: number\n\n /** Whether deep search is active (query length >= minLength) */\n isDeepSearching: boolean\n\n /** Aggregate async loading state across all menus */\n async: AsyncState\n}\n\n/**\n * Props for the DataList component.\n */\nexport interface DataListProps {\n /**\n * Render function for the list content.\n * Receives the current state and returns JSX.\n */\n children: (state: DataListChildrenState) => React.ReactNode\n\n /** Accessible label for the listbox */\n label?: string\n\n /** Additional class name */\n className?: string\n\n /** Additional styles */\n style?: React.CSSProperties\n\n /**\n * When true, measures row widths and applies `--row-width` CSS variable.\n * Keeps the list at the maximum width seen while scrolling.\n * Useful for virtualized lists where content width varies.\n * @default true\n */\n measureRowWidth?: boolean\n\n /**\n * Maximum width cap for row measurement (in pixels).\n * Only used when `measureRowWidth` is true.\n */\n maxRowWidth?: number\n}\n\n// ============================================================================\n// Data Subpages Props\n// ============================================================================\n\n/**\n * State passed to the DataSubpages render function.\n */\nexport interface DataSubpagesChildrenState {\n /** All subpage content nodes discovered in the current content tree. */\n subpages: DisplaySubpageNode[]\n\n /**\n * Function to render a subpage content node.\n * Calls the node's `renderContent` callback with page context and child renderer.\n */\n renderSubpageContent: (subpage: DisplaySubpageNode) => React.ReactNode\n}\n\n/**\n * Props for the DataSubpages component.\n */\nexport interface DataSubpagesProps {\n /**\n * Optional render function.\n * If omitted, all subpage contents are rendered by default.\n */\n children?: (state: DataSubpagesChildrenState) => React.ReactNode\n}\n","import { commandScore } from '../../listbox/utils/command-score.js'\nimport { normalizeValue, slugify } from '../../listbox/utils/normalize.js'\nimport type {\n AsyncNodesConfig,\n BreadcrumbNode,\n CheckboxItemDef,\n DisplayGroupNode,\n DisplayNode,\n DisplayRadioGroupNode,\n DisplayRowNode,\n GetQualifiedRowIdContext,\n GroupBehavior,\n GroupDef,\n GroupRenderContext,\n IncludeInDeepSearch,\n ItemDef,\n NodeDef,\n RadioGroupBehavior,\n RadioGroupDef,\n RadioItemDef,\n RowRenderContext,\n ScoredNode,\n SubmenuDef,\n SubpageDef,\n} from './types.js'\nimport {\n isDisplayGroupNode,\n isDisplayRadioGroupNode,\n isDisplaySeparatorNode,\n} from './types.js'\n\nconst identityQuery = (query: string) => query\n\n// ============================================================================\n// Default getQualifiedRowId Implementation\n// ============================================================================\n\n/**\n * Default function to generate qualified unique IDs for rows.\n *\n * Logic:\n * - If node.id is provided, use it as-is (treat as globally unique)\n * - Otherwise, when deep searching, qualify with breadcrumb path + value\n * - When not deep searching, just use the slugified value\n *\n * @example\n * // With explicit id:\n * // { id: 'my-unique-id', value: 'In Progress' }\n * // => 'my-unique-id'\n *\n * // Without id, deep searching in \"Status\" submenu:\n * // { value: 'In Progress' } in Status submenu\n * // => 'status.in-progress'\n *\n * // Without id, not deep searching:\n * // { value: 'In Progress' }\n * // => 'in-progress'\n */\nexport function defaultGetQualifiedRowId(\n ctx: GetQualifiedRowIdContext,\n): string {\n // If explicit id is provided, use it as-is (treat as globally unique)\n if (ctx.id) {\n return ctx.id\n }\n\n // Otherwise, compute from breadcrumbs + value\n const slugValue = slugify(ctx.value)\n\n // Only qualify with breadcrumbs when deep searching\n if (ctx.isDeepSearching && ctx.breadcrumbs.length > 0) {\n const slugBreadcrumbs = ctx.breadcrumbs\n .map((b) => b.id ?? slugify(b.value))\n .filter(Boolean)\n if (slugBreadcrumbs.length > 0) {\n return [...slugBreadcrumbs, slugValue].join('.')\n }\n }\n\n return slugValue\n}\n\n/**\n * Computes a deterministic page ID for a subpage node.\n *\n * Priority:\n * - explicit `node.pageId`\n * - derived from breadcrumb ids/values + node id/value (slugified)\n */\nexport function getSubpagePageId(\n node: SubpageDef,\n breadcrumbs: BreadcrumbNode[],\n): string {\n if (node.pageId) {\n return node.pageId\n }\n\n const breadcrumbSegments = breadcrumbs\n .map((breadcrumb) => slugify(breadcrumb.id ?? breadcrumb.value))\n .filter(Boolean)\n const leafSegment = slugify(node.id ?? node.value)\n const path = [...breadcrumbSegments, leafSegment].filter(Boolean).join('.')\n\n return path ? `subpage.${path}` : 'subpage'\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport function isItemDef(node: NodeDef): node is ItemDef {\n return node.kind === 'item'\n}\n\nexport function isRadioItemDef(node: NodeDef): node is RadioItemDef {\n return node.kind === 'radio-item'\n}\n\nexport function isCheckboxItemDef(node: NodeDef): node is CheckboxItemDef {\n return node.kind === 'checkbox-item'\n}\n\nexport function isSubmenuDef(node: NodeDef): node is SubmenuDef {\n return node.kind === 'submenu'\n}\n\nexport function isSubpageDef(node: NodeDef): node is SubpageDef {\n return node.kind === 'subpage'\n}\n\nexport function isGroupDef(node: NodeDef): node is GroupDef {\n return node.kind === 'group'\n}\n\nexport function isRadioGroupDef(node: NodeDef): node is RadioGroupDef {\n return node.kind === 'radio-group'\n}\n\nexport function isSeparatorDef(\n node: NodeDef,\n): node is { kind: 'separator'; id?: string } {\n return node.kind === 'separator'\n}\n\n// ============================================================================\n// Flatten Nodes for Search\n// ============================================================================\n\ninterface FlattenOptions {\n /** Whether to include children of branch nodes (submenu/subpage) */\n deep?: boolean\n /** Default include mode for descendant branch nodes */\n includeInDeepSearch?: IncludeInDeepSearch\n /** Whether ancestors allow this subtree to participate in deep search */\n descendantsIncluded?: boolean\n /** Parent breadcrumb nodes (branch nodes from root to parent) */\n breadcrumbs?: BreadcrumbNode[]\n /** Current group context (nested groups not supported) */\n group?: { id: string; label?: string; groupDef: GroupDef } | null\n /** Current radio group context */\n radioGroup?: {\n id: string\n label?: string\n radioGroupDef: RadioGroupDef\n } | null\n}\n\ninterface FlattenedNode {\n node: ItemDef | RadioItemDef | CheckboxItemDef | SubmenuDef | SubpageDef\n /** Breadcrumb nodes (branch nodes from root to parent) */\n breadcrumbs: BreadcrumbNode[]\n /** The group this node belongs to, if any */\n group: { id: string; label?: string; groupDef: GroupDef } | null\n /** The radio group this node belongs to, if any */\n radioGroup: {\n id: string\n label?: string\n radioGroupDef: RadioGroupDef\n } | null\n}\n\n/**\n * Flattens a tree of node definitions into a flat array.\n * When deep=true, includes children of branch nodes with their breadcrumb paths.\n * Tracks group and radio group membership for each node.\n */\nexport function flattenNodes(\n nodes: NodeDef[],\n options: FlattenOptions = {},\n): FlattenedNode[] {\n const {\n deep = false,\n includeInDeepSearch = true,\n descendantsIncluded = true,\n breadcrumbs = [],\n group = null,\n radioGroup = null,\n } = options\n const result: FlattenedNode[] = []\n\n for (const node of nodes) {\n if (node.kind === 'separator') {\n // Skip separators during search\n continue\n }\n\n if (node.kind === 'group') {\n // Groups are containers - recurse into their children with group context\n // Note: Nested groups are not supported, so we pass this group directly\n const groupInfo = { id: node.id, label: node.label, groupDef: node }\n result.push(\n ...flattenNodes(node.nodes, {\n deep,\n includeInDeepSearch,\n descendantsIncluded,\n breadcrumbs,\n group: groupInfo,\n radioGroup: null, // Reset radio group when entering a regular group\n }),\n )\n continue\n }\n\n if (node.kind === 'radio-group') {\n // Radio groups are containers - recurse into their children with radio group context\n if (node.hidden) continue\n\n const radioGroupInfo = {\n id: node.id,\n label: node.label,\n radioGroupDef: node,\n }\n result.push(\n ...flattenNodes(node.nodes, {\n deep,\n includeInDeepSearch,\n descendantsIncluded,\n breadcrumbs,\n group: null, // Reset regular group when entering a radio group\n radioGroup: radioGroupInfo,\n }),\n )\n continue\n }\n\n if (node.hidden) {\n continue\n }\n\n if (\n node.kind === 'item' ||\n node.kind === 'radio-item' ||\n node.kind === 'checkbox-item'\n ) {\n result.push({\n node,\n breadcrumbs,\n group,\n radioGroup,\n })\n continue\n }\n\n if (node.kind === 'submenu' || node.kind === 'subpage') {\n const branchIncludeMode = node.includeInDeepSearch ?? includeInDeepSearch\n\n // includeInDeepSearch only affects deep search results.\n // In shallow mode, branch triggers remain searchable as normal rows.\n const shouldIncludeBranchTrigger =\n !deep || (descendantsIncluded && branchIncludeMode !== false)\n\n if (shouldIncludeBranchTrigger) {\n result.push({\n node,\n breadcrumbs,\n group,\n radioGroup,\n })\n }\n\n // If deep search enabled and branch allows descendants, include children.\n const shouldIncludeBranchDescendants =\n deep &&\n descendantsIncluded &&\n branchIncludeMode === true &&\n node.deepSearch !== false\n\n if (shouldIncludeBranchDescendants && node.nodes) {\n const branchBreadcrumb: BreadcrumbNode = {\n node,\n value: node.value,\n id: node.id,\n }\n const childBreadcrumbs: BreadcrumbNode[] = [\n ...breadcrumbs,\n branchBreadcrumb,\n ]\n\n result.push(\n ...flattenNodes(node.nodes, {\n deep,\n includeInDeepSearch,\n descendantsIncluded: true,\n breadcrumbs: childBreadcrumbs,\n // Reset group and radio group context when entering a branch node\n group: null,\n radioGroup: null,\n }),\n )\n }\n }\n }\n\n return result\n}\n\n// ============================================================================\n// Score Nodes\n// ============================================================================\n\n/**\n * Scores nodes against a search query.\n * Returns only nodes with a score > 0.\n */\nexport function scoreNodes(\n flattenedNodes: FlattenedNode[],\n query: string,\n normalizeQuery: (query: string) => string = normalizeValue,\n): ScoredNode[] {\n const normalizedQuery = normalizeQuery(query)\n\n if (!normalizedQuery) {\n // No query - return all nodes with score 1\n return flattenedNodes.map(\n ({ node, breadcrumbs, group, radioGroup }): ScoredNode => ({\n node,\n score: 1,\n breadcrumbs,\n group,\n radioGroup,\n }),\n )\n }\n\n const results: ScoredNode[] = []\n\n for (const { node, breadcrumbs, group, radioGroup } of flattenedNodes) {\n // Normalize value and keywords to match cmdk's behavior\n const normalizedValue = normalizeValue(node.value)\n const normalizedKeywords = node.keywords\n ?.map((k) => normalizeValue(k))\n .filter(Boolean)\n\n const fuzzyScore = commandScore(\n normalizedValue,\n normalizedQuery,\n normalizedKeywords,\n )\n const score = node.forceScore ?? fuzzyScore\n\n if (score > 0) {\n results.push({\n node,\n score,\n breadcrumbs,\n group,\n radioGroup,\n })\n }\n }\n\n return results\n}\n\n// ============================================================================\n// Sort Nodes\n// ============================================================================\n\nfunction getNodeForceOrder(node: { forceOrder?: number }): number {\n return node.forceOrder ?? 0\n}\n\nfunction compareScoredNodesByForceOrderAndScore(\n a: ScoredNode,\n b: ScoredNode,\n): number {\n const orderDiff = getNodeForceOrder(a.node) - getNodeForceOrder(b.node)\n if (orderDiff !== 0) {\n return orderDiff\n }\n\n return b.score - a.score\n}\n\nfunction getRowKindSortRank(\n kind: 'item' | 'radio-item' | 'checkbox-item' | 'submenu' | 'subpage',\n): number {\n return kind === 'submenu' || kind === 'subpage' ? 1 : 0\n}\n\nfunction sortByForceOrderThenKindThenScore(\n a: { forceOrder: number; kindRank: number; score: number },\n b: { forceOrder: number; kindRank: number; score: number },\n): number {\n const orderDiff = a.forceOrder - b.forceOrder\n if (orderDiff !== 0) {\n return orderDiff\n }\n\n const kindDiff = a.kindRank - b.kindRank\n if (kindDiff !== 0) {\n return kindDiff\n }\n\n return b.score - a.score\n}\n\nfunction getMinForceOrderFromDisplayRows(nodes: DisplayRowNode[]): number {\n if (nodes.length === 0) {\n return 0\n }\n\n let minForceOrder = Number.POSITIVE_INFINITY\n\n for (const item of nodes) {\n const forceOrder = getNodeForceOrder(item.node)\n if (forceOrder < minForceOrder) {\n minForceOrder = forceOrder\n }\n }\n\n return minForceOrder === Number.POSITIVE_INFINITY ? 0 : minForceOrder\n}\n\n/**\n * Sorts scored nodes by forced order, then score (descending).\n */\nexport function sortByScore(nodes: ScoredNode[]): ScoredNode[] {\n return [...nodes].sort(compareScoredNodesByForceOrderAndScore)\n}\n\n/**\n * Partitions nodes by forced order bucket, then kind.\n * Within each forceOrder bucket, items are shown before submenu/subpage triggers.\n */\nexport function partitionByKind(nodes: ScoredNode[]): ScoredNode[] {\n const byForceOrder = new Map<\n number,\n {\n items: ScoredNode[]\n branches: ScoredNode[]\n }\n >()\n\n for (const node of nodes) {\n const forceOrder = getNodeForceOrder(node.node)\n const bucket = byForceOrder.get(forceOrder) ?? {\n items: [],\n branches: [],\n }\n\n if (\n node.node.kind === 'item' ||\n node.node.kind === 'radio-item' ||\n node.node.kind === 'checkbox-item'\n ) {\n bucket.items.push(node)\n } else {\n bucket.branches.push(node)\n }\n\n byForceOrder.set(forceOrder, bucket)\n }\n\n const sortedForceOrders = [...byForceOrder.keys()].sort((a, b) => a - b)\n\n const result: ScoredNode[] = []\n\n for (const forceOrder of sortedForceOrders) {\n const bucket = byForceOrder.get(forceOrder)\n if (!bucket) {\n continue\n }\n\n result.push(...bucket.items, ...bucket.branches)\n }\n\n return result\n}\n\n/**\n * Deduplicates nodes by their composite ID (breadcrumbs + node.value).\n * This handles the case where the same node appears multiple times in the tree.\n * Values are normalized (trimmed) for consistent deduplication.\n */\nexport function deduplicateNodes(nodes: ScoredNode[]): ScoredNode[] {\n const seen = new Set<string>()\n const result: ScoredNode[] = []\n\n for (const scoredNode of nodes) {\n // Normalize value for consistent deduplication\n // Note: breadcrumbs are already normalized in flattenNodes\n const compositeId = [\n ...scoredNode.breadcrumbs,\n normalizeValue(scoredNode.node.value),\n ].join('.')\n if (!seen.has(compositeId)) {\n seen.add(compositeId)\n result.push(scoredNode)\n }\n }\n\n return result\n}\n\n// ============================================================================\n// Build Display Nodes\n// ============================================================================\n\n/**\n * Converts scored nodes to display row nodes with render context.\n * Used for flatten mode where groups are invisible.\n */\nexport function buildDisplayRowNodes(\n scoredNodes: ScoredNode[],\n query: string,\n highlightedId: string | null,\n): DisplayRowNode[] {\n return scoredNodes.map((scoredNode) => {\n const isDeepSearchResult = scoredNode.breadcrumbs.length > 0\n\n const context: RowRenderContext = {\n search: query\n ? {\n query,\n score: scoredNode.score,\n }\n : null,\n breadcrumbs: scoredNode.breadcrumbs,\n // breadcrumbs already set above\n isDeepSearchResult,\n highlighted: scoredNode.node.id === highlightedId,\n disabled: scoredNode.node.disabled ?? false,\n group: scoredNode.group\n ? { id: scoredNode.group.id, label: scoredNode.group.label }\n : null,\n }\n\n return {\n node: scoredNode.node,\n context,\n radioGroup: scoredNode.radioGroup\n ? { id: scoredNode.radioGroup.id, label: scoredNode.radioGroup.label }\n : undefined,\n }\n })\n}\n\n/**\n * Builds a single DisplayRowNode from a ScoredNode.\n * Helper function for building row nodes.\n */\nfunction buildDisplayRowNode(\n scoredNode: ScoredNode,\n query: string,\n highlightedId: string | null,\n): DisplayRowNode {\n const isDeepSearchResult = scoredNode.breadcrumbs.length > 0\n\n const context: RowRenderContext = {\n search: query\n ? {\n query,\n score: scoredNode.score,\n }\n : null,\n breadcrumbs: scoredNode.breadcrumbs,\n isDeepSearchResult,\n highlighted: scoredNode.node.id === highlightedId,\n disabled: scoredNode.node.disabled ?? false,\n group: scoredNode.group\n ? { id: scoredNode.group.id, label: scoredNode.group.label }\n : null,\n }\n\n return {\n node: scoredNode.node,\n context,\n radioGroup: scoredNode.radioGroup\n ? { id: scoredNode.radioGroup.id, label: scoredNode.radioGroup.label }\n : undefined,\n }\n}\n\n// ============================================================================\n// Browse Mode - Get Shallow Nodes\n// ============================================================================\n\n/**\n * Gets nodes for browse mode (no search) with flatten behavior.\n * Returns only top-level items and submenu triggers, flattening groups.\n */\nexport function getBrowseNodesFlatten(\n nodes: NodeDef[],\n highlightedId: string | null,\n group: { id: string; label?: string } | null = null,\n): DisplayRowNode[] {\n const result: DisplayRowNode[] = []\n\n for (const node of nodes) {\n if (node.kind === 'separator') {\n // Skip separators - they're not focusable\n continue\n }\n\n if (node.kind === 'group') {\n // Recurse into groups, passing group context\n const groupInfo = { id: node.id, label: node.label }\n result.push(\n ...getBrowseNodesFlatten(node.nodes, highlightedId, groupInfo),\n )\n continue\n }\n\n if (node.kind === 'radio-group') {\n // Radio groups should not be flattened - skip in flatten mode\n // They will be handled by getBrowseNodesPreserve\n continue\n }\n\n if (node.hidden) {\n continue\n }\n\n const context: RowRenderContext = {\n search: null,\n breadcrumbs: [],\n isDeepSearchResult: false,\n highlighted: node.id === highlightedId,\n disabled: node.disabled ?? false,\n group,\n }\n\n result.push({ node, context })\n }\n\n return result\n}\n\n/**\n * Gets nodes for browse mode (no search) with preserve behavior.\n * Keeps group structure intact, showing group containers with their items.\n */\nexport function getBrowseNodesPreserve(\n nodes: NodeDef[],\n highlightedId: string | null,\n): DisplayNode[] {\n const result: DisplayNode[] = []\n\n for (const node of nodes) {\n if (node.kind === 'separator') {\n // Include separators in browse mode for visual separation\n result.push({ kind: 'separator', separator: node })\n continue\n }\n\n if (node.kind === 'group') {\n // Build group items\n const groupItems: DisplayRowNode[] = []\n for (const child of node.nodes) {\n // Skip non-row nodes\n if (\n child.kind === 'separator' ||\n child.kind === 'group' ||\n child.kind === 'radio-group'\n ) {\n continue\n }\n if (child.hidden) continue\n\n const itemContext: RowRenderContext = {\n search: null,\n breadcrumbs: [],\n isDeepSearchResult: false,\n highlighted: child.id === highlightedId,\n disabled: child.disabled ?? false,\n group: { id: node.id, label: node.label },\n }\n\n groupItems.push({ node: child, context: itemContext })\n }\n\n // Only include group if it has items\n if (groupItems.length > 0) {\n const groupContext: GroupRenderContext = {\n search: null,\n matchCount: groupItems.length,\n breadcrumbs: [],\n isDeepSearchResult: false,\n }\n\n result.push({\n kind: 'group',\n group: node,\n context: groupContext,\n items: groupItems,\n bestScore: 1,\n })\n }\n continue\n }\n\n if (node.kind === 'radio-group') {\n if (node.hidden) continue\n\n // Build radio group items\n const radioItems: DisplayRowNode[] = []\n for (const child of node.nodes) {\n // RadioGroupDef.nodes only contains ItemDef | SubmenuDef | CheckboxItemDef\n if (child.hidden) continue\n\n const itemContext: RowRenderContext = {\n search: null,\n breadcrumbs: [],\n isDeepSearchResult: false,\n highlighted: child.id === highlightedId,\n disabled: child.disabled ?? false,\n group: null, // Radio items don't belong to a regular group\n }\n\n radioItems.push({\n node: child,\n context: itemContext,\n radioGroup: { id: node.id, label: node.label },\n })\n }\n\n // Only include radio group if it has items\n if (radioItems.length > 0) {\n const groupContext: GroupRenderContext = {\n search: null,\n matchCount: radioItems.length,\n breadcrumbs: [],\n isDeepSearchResult: false,\n }\n\n result.push({\n kind: 'radio-group',\n radioGroup: node,\n context: groupContext,\n items: radioItems,\n bestScore: 1,\n })\n }\n continue\n }\n\n if (node.hidden) {\n continue\n }\n\n // Ungrouped item/submenu/subpage\n const context: RowRenderContext = {\n search: null,\n breadcrumbs: [],\n isDeepSearchResult: false,\n highlighted: node.id === highlightedId,\n disabled: node.disabled ?? false,\n group: null,\n }\n\n result.push({ node, context })\n }\n\n return result\n}\n\n// ============================================================================\n// Full Pipeline\n// ============================================================================\n\nexport interface FilterNodesOptions {\n /** The search query */\n query: string\n /** Optional query normalizer. Defaults to trimming whitespace. */\n normalizeQuery?: (query: string) => string\n /** The node definitions to filter */\n nodes: NodeDef[]\n /** Currently highlighted node ID */\n highlightedId: string | null\n /** Whether deep search is enabled */\n deepSearch?: boolean\n /** Default include mode for descendant submenus during deep search */\n includeInDeepSearch?: IncludeInDeepSearch\n /** Minimum query length for deep search */\n minLength?: number\n /** How groups behave during search (only applies when searching, not browse mode) */\n groupSearchBehavior?: GroupBehavior\n /** How radio groups behave during search */\n radioGroupSearchBehavior?: RadioGroupBehavior\n /** Whether to sort groups by best score */\n sortGroups?: boolean\n}\n\n/**\n * Filters nodes with 'flatten' group behavior.\n * Groups are invisible, items shown in flat list.\n * Radio group behavior is controlled by radioGroupSearchBehavior.\n */\nfunction filterNodesFlatten(options: FilterNodesOptions): {\n displayNodes: DisplayNode[]\n isDeepSearching: boolean\n} {\n const {\n query,\n normalizeQuery,\n nodes,\n highlightedId,\n deepSearch = true,\n includeInDeepSearch = true,\n minLength = 0,\n radioGroupSearchBehavior = 'preserve',\n } = options\n\n // Determine if deep search should activate\n const shouldDeepSearch = deepSearch && query.length >= minLength\n\n // Flatten nodes\n const flattened = flattenNodes(nodes, {\n deep: shouldDeepSearch,\n includeInDeepSearch,\n })\n\n // For preserve-show-all, we need to track ALL radio group items before scoring\n // Maps radio group ID -> all flattened nodes for that group\n const allRadioGroupItems = new Map<\n string,\n {\n radioGroupDef: RadioGroupDef\n items: FlattenedNode[]\n breadcrumbs: BreadcrumbNode[]\n }\n >()\n\n if (radioGroupSearchBehavior === 'preserve-show-all') {\n for (const flatNode of flattened) {\n if (flatNode.radioGroup) {\n const existing = allRadioGroupItems.get(flatNode.radioGroup.id)\n if (existing) {\n existing.items.push(flatNode)\n } else {\n allRadioGroupItems.set(flatNode.radioGroup.id, {\n radioGroupDef: flatNode.radioGroup.radioGroupDef,\n items: [flatNode],\n breadcrumbs: flatNode.breadcrumbs,\n })\n }\n }\n }\n }\n\n // Score nodes\n const scored = scoreNodes(flattened, query, normalizeQuery)\n\n // Separate radio group items from regular items\n const radioGroupItems = new Map<\n string,\n {\n radioGroupDef: RadioGroupDef\n items: ScoredNode[]\n breadcrumbs: BreadcrumbNode[]\n }\n >()\n const regularItems: ScoredNode[] = []\n\n for (const scoredNode of scored) {\n if (scoredNode.radioGroup) {\n // For 'flatten' behavior, treat radio items as regular items\n if (radioGroupSearchBehavior === 'flatten') {\n regularItems.push(scoredNode)\n } else {\n // For 'preserve' and 'preserve-show-all', group them\n const existing = radioGroupItems.get(scoredNode.radioGroup.id)\n if (existing) {\n existing.items.push(scoredNode)\n } else {\n radioGroupItems.set(scoredNode.radioGroup.id, {\n radioGroupDef: scoredNode.radioGroup.radioGroupDef,\n items: [scoredNode],\n breadcrumbs: scoredNode.breadcrumbs,\n })\n }\n }\n } else {\n regularItems.push(scoredNode)\n }\n }\n\n // Sort regular items by score\n const sorted = sortByScore(regularItems)\n\n // Partition (items first, then submenus)\n const partitioned = partitionByKind(sorted)\n\n // Deduplicate\n const unique = deduplicateNodes(partitioned)\n\n // Build display nodes for regular items\n const regularDisplayNodes: DisplayRowNode[] = buildDisplayRowNodes(\n unique,\n query,\n highlightedId,\n )\n\n // Build display nodes for radio groups\n const radioGroupDisplayNodes: DisplayRadioGroupNode[] = []\n\n if (radioGroupSearchBehavior !== 'flatten') {\n for (const [\n radioGroupId,\n { radioGroupDef, items: matchingItems, breadcrumbs },\n ] of radioGroupItems) {\n let itemsToDisplay: ScoredNode[]\n\n if (radioGroupSearchBehavior === 'preserve-show-all') {\n // Include ALL items from this radio group, not just matching ones\n const allItems = allRadioGroupItems.get(radioGroupId)\n if (allItems) {\n // Create scored nodes for all items, using 0 for non-matching\n const matchingScores = new Map(\n matchingItems.map((item) => [item.node.id, item.score]),\n )\n\n itemsToDisplay = allItems.items.map((flatNode) => ({\n node: flatNode.node,\n score: matchingScores.get(flatNode.node.id) ?? 0,\n breadcrumbs: flatNode.breadcrumbs,\n group: flatNode.group,\n radioGroup: flatNode.radioGroup,\n }))\n } else {\n itemsToDisplay = matchingItems\n }\n } else {\n // 'preserve' - only show matching items\n itemsToDisplay = matchingItems\n }\n\n // Sort items by forced order, then score.\n itemsToDisplay.sort(compareScoredNodesByForceOrderAndScore)\n\n const bestScore = Math.max(...itemsToDisplay.map((item) => item.score), 0)\n const isDeepSearchResult = breadcrumbs.length > 0\n\n const groupContext: GroupRenderContext = {\n search: query ? { query, bestScore } : null,\n matchCount: matchingItems.length,\n breadcrumbs,\n isDeepSearchResult,\n }\n\n radioGroupDisplayNodes.push({\n kind: 'radio-group',\n radioGroup: radioGroupDef,\n context: groupContext,\n items: itemsToDisplay.map((item) =>\n buildDisplayRowNode(item, query, highlightedId),\n ),\n bestScore,\n })\n }\n }\n\n // Merge regular items and radio groups, sorted by forced order then score.\n type SortableNode = {\n node: DisplayNode\n score: number\n forceOrder: number\n kindRank: number\n }\n\n const allNodes: SortableNode[] = [\n ...regularDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.context.search?.score ?? 0,\n forceOrder: getNodeForceOrder(r.node),\n kindRank: getRowKindSortRank(r.node.kind),\n })),\n ...radioGroupDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.bestScore,\n forceOrder: getMinForceOrderFromDisplayRows(r.items),\n kindRank: 0,\n })),\n ]\n\n allNodes.sort(sortByForceOrderThenKindThenScore)\n\n return {\n displayNodes: allNodes.map((n) => n.node),\n isDeepSearching: shouldDeepSearch,\n }\n}\n\n/**\n * Filters nodes with 'preserve' group behavior.\n * Groups are shown as containers with their matching items.\n * Groups and ungrouped items are mixed by score.\n * Radio group behavior is controlled by radioGroupSearchBehavior.\n */\nfunction filterNodesPreserve(options: FilterNodesOptions): {\n displayNodes: DisplayNode[]\n isDeepSearching: boolean\n} {\n const {\n query,\n normalizeQuery,\n nodes,\n highlightedId,\n deepSearch = true,\n includeInDeepSearch = true,\n minLength = 0,\n sortGroups = true,\n radioGroupSearchBehavior = 'preserve',\n } = options\n\n // Determine if deep search should activate\n const shouldDeepSearch = deepSearch && query.length >= minLength\n\n // Flatten nodes (tracking group and radio group membership)\n const flattened = flattenNodes(nodes, {\n deep: shouldDeepSearch,\n includeInDeepSearch,\n })\n\n // For preserve-show-all, we need to track ALL radio group items before scoring\n const allRadioGroupItems = new Map<\n string,\n {\n radioGroupDef: RadioGroupDef\n items: FlattenedNode[]\n breadcrumbs: BreadcrumbNode[]\n }\n >()\n\n if (radioGroupSearchBehavior === 'preserve-show-all') {\n for (const flatNode of flattened) {\n if (flatNode.radioGroup) {\n const existing = allRadioGroupItems.get(flatNode.radioGroup.id)\n if (existing) {\n existing.items.push(flatNode)\n } else {\n allRadioGroupItems.set(flatNode.radioGroup.id, {\n radioGroupDef: flatNode.radioGroup.radioGroupDef,\n items: [flatNode],\n breadcrumbs: flatNode.breadcrumbs,\n })\n }\n }\n }\n }\n\n // Score nodes\n const scored = scoreNodes(flattened, query, normalizeQuery)\n\n // Partition into groups, radio groups, and ungrouped\n const groupedItems = new Map<\n string,\n { groupDef: GroupDef; items: ScoredNode[]; breadcrumbs: BreadcrumbNode[] }\n >()\n const radioGroupedItems = new Map<\n string,\n {\n radioGroupDef: RadioGroupDef\n items: ScoredNode[]\n breadcrumbs: BreadcrumbNode[]\n }\n >()\n const ungroupedItems: ScoredNode[] = []\n\n for (const scoredNode of scored) {\n if (scoredNode.radioGroup) {\n // For 'flatten' behavior, treat radio items as ungrouped\n if (radioGroupSearchBehavior === 'flatten') {\n ungroupedItems.push(scoredNode)\n } else {\n const existing = radioGroupedItems.get(scoredNode.radioGroup.id)\n if (existing) {\n existing.items.push(scoredNode)\n } else {\n radioGroupedItems.set(scoredNode.radioGroup.id, {\n radioGroupDef: scoredNode.radioGroup.radioGroupDef,\n items: [scoredNode],\n breadcrumbs: scoredNode.breadcrumbs,\n })\n }\n }\n } else if (scoredNode.group) {\n const existing = groupedItems.get(scoredNode.group.id)\n if (existing) {\n existing.items.push(scoredNode)\n } else {\n groupedItems.set(scoredNode.group.id, {\n groupDef: scoredNode.group.groupDef,\n items: [scoredNode],\n breadcrumbs: scoredNode.breadcrumbs,\n })\n }\n } else {\n ungroupedItems.push(scoredNode)\n }\n }\n\n // Build display nodes for groups (with items sorted by score)\n const groupDisplayNodes: DisplayGroupNode[] = []\n for (const [_groupId, { groupDef, items, breadcrumbs }] of groupedItems) {\n // Sort items within group by forced order, then score.\n items.sort(compareScoredNodesByForceOrderAndScore)\n\n const bestScore = Math.max(...items.map((item) => item.score), 0)\n const isDeepSearchResult = breadcrumbs.length > 0\n\n const groupContext: GroupRenderContext = {\n search: query ? { query, bestScore } : null,\n matchCount: items.length,\n breadcrumbs,\n isDeepSearchResult,\n }\n\n groupDisplayNodes.push({\n kind: 'group',\n group: groupDef,\n context: groupContext,\n items: items.map((item) =>\n buildDisplayRowNode(item, query, highlightedId),\n ),\n bestScore,\n })\n }\n\n // Build display nodes for radio groups\n const radioGroupDisplayNodes: DisplayRadioGroupNode[] = []\n\n if (radioGroupSearchBehavior !== 'flatten') {\n for (const [\n radioGroupId,\n { radioGroupDef, items: matchingItems, breadcrumbs },\n ] of radioGroupedItems) {\n let itemsToDisplay: ScoredNode[]\n\n if (radioGroupSearchBehavior === 'preserve-show-all') {\n // Include ALL items from this radio group, not just matching ones\n const allItems = allRadioGroupItems.get(radioGroupId)\n if (allItems) {\n // Create scored nodes for all items, using 0 for non-matching\n const matchingScores = new Map(\n matchingItems.map((item) => [item.node.id, item.score]),\n )\n\n itemsToDisplay = allItems.items.map((flatNode) => ({\n node: flatNode.node,\n score: matchingScores.get(flatNode.node.id) ?? 0,\n breadcrumbs: flatNode.breadcrumbs,\n group: flatNode.group,\n radioGroup: flatNode.radioGroup,\n }))\n } else {\n itemsToDisplay = matchingItems\n }\n } else {\n // 'preserve' - only show matching items\n itemsToDisplay = matchingItems\n }\n\n // Sort items by forced order, then score.\n itemsToDisplay.sort(compareScoredNodesByForceOrderAndScore)\n\n const bestScore = Math.max(...itemsToDisplay.map((item) => item.score), 0)\n const isDeepSearchResult = breadcrumbs.length > 0\n\n const groupContext: GroupRenderContext = {\n search: query ? { query, bestScore } : null,\n matchCount: matchingItems.length,\n breadcrumbs,\n isDeepSearchResult,\n }\n\n radioGroupDisplayNodes.push({\n kind: 'radio-group',\n radioGroup: radioGroupDef,\n context: groupContext,\n items: itemsToDisplay.map((item) =>\n buildDisplayRowNode(item, query, highlightedId),\n ),\n bestScore,\n })\n }\n }\n\n // Build display nodes for ungrouped items\n const ungroupedDisplayNodes: DisplayRowNode[] = ungroupedItems\n .sort(compareScoredNodesByForceOrderAndScore)\n .map((item) => buildDisplayRowNode(item, query, highlightedId))\n\n // Merge groups, radio groups, and ungrouped items, sorted by forced order then score.\n type SortableNode = {\n node: DisplayNode\n score: number\n forceOrder: number\n kindRank: number\n }\n\n const allNodes: SortableNode[] = [\n ...groupDisplayNodes.map((g) => ({\n node: g as DisplayNode,\n score: g.bestScore,\n forceOrder: getMinForceOrderFromDisplayRows(g.items),\n kindRank: 0,\n })),\n ...radioGroupDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.bestScore,\n forceOrder: getMinForceOrderFromDisplayRows(r.items),\n kindRank: 0,\n })),\n ...ungroupedDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.context.search?.score ?? 0,\n forceOrder: getNodeForceOrder(r.node),\n kindRank: getRowKindSortRank(r.node.kind),\n })),\n ]\n\n if (sortGroups) {\n allNodes.sort(sortByForceOrderThenKindThenScore)\n }\n\n return {\n displayNodes: allNodes.map((n) => n.node),\n isDeepSearching: shouldDeepSearch,\n }\n}\n\n/**\n * Main filtering pipeline.\n * Handles both browse mode and search mode (shallow and deep).\n * Respects groupSearchBehavior configuration (only applies during search).\n * Note: Radio groups are ALWAYS preserved regardless of groupSearchBehavior.\n */\nexport function filterNodes(options: FilterNodesOptions): {\n displayNodes: DisplayNode[]\n isDeepSearching: boolean\n} {\n const {\n query,\n nodes,\n highlightedId,\n groupSearchBehavior = 'preserve',\n } = options\n const normalizeQuery = options.normalizeQuery ?? normalizeValue\n const normalizedQuery = normalizeQuery(query)\n const normalizedOptions =\n normalizedQuery === query\n ? { ...options, normalizeQuery: identityQuery }\n : {\n ...options,\n query: normalizedQuery,\n normalizeQuery: identityQuery,\n }\n\n // Browse mode - no query\n // Always preserve groups in browse mode (groupSearchBehavior only affects search)\n if (!normalizedQuery) {\n return {\n displayNodes: getBrowseNodesPreserve(nodes, highlightedId),\n isDeepSearching: false,\n }\n }\n\n // Search mode - dispatch based on group search behavior\n if (groupSearchBehavior === 'preserve') {\n return filterNodesPreserve(normalizedOptions)\n }\n\n return filterNodesFlatten(normalizedOptions)\n}\n\n// ============================================================================\n// Get Navigable IDs\n// ============================================================================\n\n/**\n * Gets the IDs of all navigable (non-disabled) nodes.\n * Handles row nodes, group nodes, and radio group nodes (extracts item IDs).\n * Separators are skipped as they're not navigable.\n * Used for keyboard navigation.\n *\n * Note: Uses `node.id ?? node.value` as the identifier. For proper ID handling\n * with custom getItemId functions, use `getOrderedItemIds` from DataList instead.\n */\nexport function getNavigableIds(displayNodes: DisplayNode[]): string[] {\n const ids: string[] = []\n\n for (const node of displayNodes) {\n if (isDisplayGroupNode(node)) {\n // Add IDs of items within the group\n for (const item of node.items) {\n if (!item.node.disabled) {\n ids.push(item.node.id ?? item.node.value)\n }\n }\n } else if (isDisplayRadioGroupNode(node)) {\n // Add IDs of items within the radio group\n for (const item of node.items) {\n if (!item.node.disabled) {\n ids.push(item.node.id ?? item.node.value)\n }\n }\n } else if (isDisplaySeparatorNode(node)) {\n // Separators are not navigable\n } else {\n // Row node (item, checkbox item, submenu, or subpage)\n if (!node.node.disabled) {\n ids.push(node.node.id ?? node.node.value)\n }\n }\n }\n\n return ids\n}\n\n/**\n * Gets the first navigable node ID.\n */\nexport function getFirstNavigableId(\n displayNodes: DisplayNode[],\n): string | null {\n const ids = getNavigableIds(displayNodes)\n return ids[0] ?? null\n}\n\n// ============================================================================\n// Async Node Collection & Merging\n// ============================================================================\n\n/**\n * Info about an async branch node (submenu/subpage) for registration.\n */\nexport interface AsyncSubmenuInfo {\n /** Unique identifier (uses node value and breadcrumbs) */\n id: string\n /** Breadcrumbs path to this branch node */\n breadcrumbs: string[]\n /** The branch node definition */\n node: SubmenuDef | SubpageDef\n /** The async configuration */\n config: AsyncNodesConfig\n}\n\n/**\n * Collects all async branch nodes from a node tree.\n * Recursively traverses groups and branches to find all async configurations.\n */\nexport function collectAsyncSubmenus(\n nodes: NodeDef[],\n breadcrumbs: string[] = [],\n includeInDeepSearch: IncludeInDeepSearch = true,\n descendantsIncluded = true,\n): AsyncSubmenuInfo[] {\n const result: AsyncSubmenuInfo[] = []\n\n for (const node of nodes) {\n if (node.kind === 'separator') {\n continue\n }\n\n if (node.kind === 'group') {\n // Recurse into groups\n result.push(\n ...collectAsyncSubmenus(\n node.nodes,\n breadcrumbs,\n includeInDeepSearch,\n descendantsIncluded,\n ),\n )\n continue\n }\n\n if (node.kind === 'radio-group') {\n if (node.hidden) continue\n // Recurse into radio groups\n result.push(\n ...collectAsyncSubmenus(\n node.nodes,\n breadcrumbs,\n includeInDeepSearch,\n descendantsIncluded,\n ),\n )\n continue\n }\n\n if (node.kind === 'submenu' || node.kind === 'subpage') {\n if (node.hidden) continue\n\n const branchIncludeMode = node.includeInDeepSearch ?? includeInDeepSearch\n const shouldIncludeBranchDescendants =\n descendantsIncluded &&\n branchIncludeMode === true &&\n node.deepSearch !== false\n\n // If this branch has async nodes, add it to the result\n if (node.asyncNodes && shouldIncludeBranchDescendants) {\n const id = [...breadcrumbs, normalizeValue(node.value)].join('.')\n result.push({\n id,\n breadcrumbs,\n node,\n config: node.asyncNodes,\n })\n }\n\n // Recurse into branch node's static nodes\n if (node.nodes && shouldIncludeBranchDescendants) {\n const childBreadcrumbs = [...breadcrumbs, normalizeValue(node.value)]\n result.push(\n ...collectAsyncSubmenus(\n node.nodes,\n childBreadcrumbs,\n includeInDeepSearch,\n true,\n ),\n )\n }\n }\n }\n\n return result\n}\n\n/**\n * Merges async nodes into a submenu's node list.\n * Static nodes come first, async nodes are appended.\n */\nexport function mergeSubmenuNodes(\n staticNodes: NodeDef[] | undefined,\n asyncNodes: NodeDef[] | undefined,\n): NodeDef[] {\n const static_ = staticNodes ?? []\n const async_ = asyncNodes ?? []\n return [...static_, ...async_]\n}\n\n/**\n * Async data from the coordinator ready for merging.\n */\ninterface AsyncNodeData {\n id: string\n breadcrumbs: string[]\n nodes: NodeDef[]\n}\n\n/**\n * Creates a merged content tree with async nodes injected at their proper locations.\n * This function modifies the tree to include async nodes where they belong.\n */\nexport function mergeAsyncNodesIntoTree(\n staticContent: NodeDef[],\n asyncData: AsyncNodeData[],\n): NodeDef[] {\n // If no async data, return static content as-is\n if (asyncData.length === 0) {\n return staticContent\n }\n\n // Build a map of async data by breadcrumb path\n const asyncMap = new Map<string, NodeDef[]>()\n for (const data of asyncData) {\n // The id is the full path including the submenu value\n // We need to find the parent path to inject into\n asyncMap.set(data.id, data.nodes)\n }\n\n // Recursively merge async nodes into the tree\n function mergeRecursive(\n nodes: NodeDef[],\n currentBreadcrumbs: string[],\n ): NodeDef[] {\n return nodes.map((node) => {\n if (node.kind === 'submenu' || node.kind === 'subpage') {\n const branchPath = [\n ...currentBreadcrumbs,\n normalizeValue(node.value),\n ].join('.')\n const asyncNodes = asyncMap.get(branchPath)\n\n // Get merged child nodes\n const mergedStaticChildren = node.nodes\n ? mergeRecursive(node.nodes, [\n ...currentBreadcrumbs,\n normalizeValue(node.value),\n ])\n : undefined\n\n // If there are async nodes for this submenu, merge them\n if (asyncNodes) {\n return {\n ...node,\n nodes: mergeSubmenuNodes(mergedStaticChildren, asyncNodes),\n }\n }\n\n // If children were modified, return updated node\n if (mergedStaticChildren !== node.nodes) {\n return { ...node, nodes: mergedStaticChildren }\n }\n }\n\n if (node.kind === 'group') {\n const mergedChildren = mergeRecursive(node.nodes, currentBreadcrumbs)\n if (mergedChildren !== node.nodes) {\n return { ...node, nodes: mergedChildren }\n }\n }\n\n // Radio groups contain static RadioItemDef[] and don't support async loading,\n // so we skip processing them in the async merge\n if (node.kind === 'radio-group') {\n return node\n }\n\n return node\n })\n }\n\n return mergeRecursive(staticContent, [])\n}\n\n/**\n * Checks if a submenu should appear in deep search results.\n * `trigger-only` still includes the submenu trigger row.\n */\nexport function shouldIncludeInDeepSearch(\n includeInDeepSearch: IncludeInDeepSearch | undefined,\n): boolean {\n return includeInDeepSearch !== false\n}\n\n/**\n * Checks if submenu descendants (rows inside submenu) should be included.\n * `trigger-only` excludes descendants.\n */\nexport function shouldIncludeSubmenuRowsInDeepSearch(\n includeInDeepSearch: IncludeInDeepSearch | undefined,\n): boolean {\n return includeInDeepSearch === true\n}\n\n/**\n * Checks if an async loader should be rendered eagerly.\n * Eager loaders mount when the root menu opens (before their submenu is opened).\n */\nexport function shouldLoadEagerly(config: AsyncNodesConfig): boolean {\n if (config.type === 'query') {\n const initialLoadWhen =\n config.initialQueryBehavior === false\n ? 'needed'\n : (config.initialQueryBehavior?.loadWhen ?? 'needed')\n\n if (initialLoadWhen === 'parent-open') {\n return true\n }\n }\n\n // Both static and query loaders can still opt into legacy eager strategy.\n return config.loadStrategy === 'eager'\n}\n","'use client'\n\nimport * as React from 'react'\nimport { normalizeValue } from '../../listbox/utils/normalize.js'\nimport { useAsyncMenuCoordinator } from './async-coordinator.js'\nimport { useDataPopupContext } from './context.js'\nimport type {\n AsyncRenderState,\n BreadcrumbNode,\n CheckboxItemDef,\n DataSubpagesChildrenState,\n DataSubpagesProps,\n DisplaySubpageNode,\n GroupRenderContext,\n ItemDef,\n NodeDef,\n QueryDependentLoaderConfig,\n RadioGroupDef,\n RadioItemDef,\n RowRenderContext,\n SubmenuDef,\n SubpageDef,\n} from './types.js'\nimport { getSubpagePageId, mergeAsyncNodesIntoTree } from './utils.js'\n\ninterface QueryExecutionState {\n effectiveQuery: string\n enabled: boolean\n isBelowMinLength: boolean\n}\n\nfunction resolveInitialQueryBehavior(config: QueryDependentLoaderConfig):\n | {\n value: string\n loadWhen: 'needed' | 'parent-open'\n }\n | false {\n if (config.initialQueryBehavior !== undefined) {\n if (config.initialQueryBehavior === false) {\n return false\n }\n return {\n value: config.initialQueryBehavior.value ?? '',\n loadWhen: config.initialQueryBehavior.loadWhen ?? 'needed',\n }\n }\n\n if (config.initialQuery !== undefined) {\n return { value: config.initialQuery, loadWhen: 'needed' }\n }\n\n return { value: '', loadWhen: 'needed' }\n}\n\nfunction resolveQueryExecutionState(\n config: QueryDependentLoaderConfig,\n query: string,\n): QueryExecutionState {\n const minLength = config.minQueryLength ?? 1\n const initialQueryBehavior = resolveInitialQueryBehavior(config)\n\n if (query.length >= minLength) {\n return {\n effectiveQuery: query,\n enabled: true,\n isBelowMinLength: false,\n }\n }\n\n if (initialQueryBehavior !== false) {\n return {\n effectiveQuery: initialQueryBehavior.value,\n enabled: true,\n isBelowMinLength: false,\n }\n }\n\n return {\n effectiveQuery: '',\n enabled: false,\n isBelowMinLength: true,\n }\n}\n\nfunction getAsyncLoaderIdForBranch(\n node: SubmenuDef | SubpageDef,\n breadcrumbs: BreadcrumbNode[],\n): string {\n return [\n ...breadcrumbs.map((breadcrumb) => normalizeValue(breadcrumb.value)),\n normalizeValue(node.value),\n ].join('.')\n}\n\nfunction getBranchAsyncState(\n node: SubmenuDef | SubpageDef,\n breadcrumbs: BreadcrumbNode[],\n searchQuery: string,\n coordinator: ReturnType<typeof useAsyncMenuCoordinator>,\n): AsyncRenderState | undefined {\n if (!node.asyncNodes || !coordinator) {\n return undefined\n }\n\n const asyncLoaderId = getAsyncLoaderIdForBranch(node, breadcrumbs)\n const asyncResult = coordinator.loaders.get(asyncLoaderId)\n\n if (!asyncResult) {\n return undefined\n }\n\n const isBelowMinLength =\n node.asyncNodes.type === 'query'\n ? resolveQueryExecutionState(node.asyncNodes, searchQuery)\n .isBelowMinLength\n : false\n\n return {\n status: asyncResult.result.status,\n fetchStatus: asyncResult.result.fetchStatus,\n loadingPhase: asyncResult.result.loadingPhase,\n isLoading: asyncResult.result.isLoading,\n isFetching: asyncResult.result.isFetching,\n isInitialLoading: asyncResult.result.isInitialLoading,\n isRefetching: asyncResult.result.isRefetching,\n isError: asyncResult.result.isError,\n error: asyncResult.result.error,\n isBelowMinLength,\n }\n}\n\nfunction collectDisplaySubpages(\n nodes: NodeDef[],\n breadcrumbs: BreadcrumbNode[] = [],\n group: { id: string; label?: string } | null = null,\n): DisplaySubpageNode[] {\n const result: DisplaySubpageNode[] = []\n\n for (const node of nodes) {\n if (node.kind === 'separator') {\n continue\n }\n\n if (node.kind === 'group') {\n result.push(\n ...collectDisplaySubpages(node.nodes, breadcrumbs, {\n id: node.id,\n label: node.label,\n }),\n )\n continue\n }\n\n if (node.kind === 'radio-group') {\n if (node.hidden) continue\n result.push(...collectDisplaySubpages(node.nodes, breadcrumbs, null))\n continue\n }\n\n if (node.hidden) {\n continue\n }\n\n if (node.kind === 'submenu' || node.kind === 'subpage') {\n if (node.kind === 'subpage') {\n result.push({\n node,\n pageId: getSubpagePageId(node, breadcrumbs),\n context: {\n search: null,\n breadcrumbs,\n isDeepSearchResult: false,\n highlighted: false,\n disabled: node.disabled ?? false,\n group,\n },\n })\n }\n\n if (node.nodes) {\n const breadcrumb: BreadcrumbNode = {\n node,\n value: node.value,\n id: node.id,\n }\n\n result.push(\n ...collectDisplaySubpages(\n node.nodes,\n [...breadcrumbs, breadcrumb],\n null,\n ),\n )\n }\n }\n }\n\n return result\n}\n\nexport interface PopupMenuDataSubpagesProps extends DataSubpagesProps {}\n\n/**\n * DataSubpages renders subpage content alongside the root Surface inside Popup.\n *\n * Place it as a sibling to DataSurface within Popup:\n *\n * ```tsx\n * <Popup>\n * <DataSurface ...>\n * ...\n * </DataSurface>\n * <DataSubpages />\n * </Popup>\n * ```\n */\nexport function PopupMenuDataSubpages(props: PopupMenuDataSubpagesProps) {\n const { children } = props\n\n const coordinator = useAsyncMenuCoordinator()\n const searchQuery = coordinator?.searchQuery ?? ''\n\n const { dataSurfaceContext } = useDataPopupContext()\n\n const content = dataSurfaceContext?.content ?? []\n\n const asyncNodes = React.useMemo(() => {\n if (!coordinator) return []\n return coordinator.getAsyncNodes()\n }, [coordinator, coordinator?.loaders])\n\n const mergedContent = React.useMemo(() => {\n if (asyncNodes.length === 0) return content\n return mergeAsyncNodesIntoTree(content, asyncNodes)\n }, [content, asyncNodes])\n\n const subpages = React.useMemo(\n () => collectDisplaySubpages(mergedContent),\n [mergedContent],\n )\n\n const renderSubpageContent = React.useCallback(\n (displaySubpage: DisplaySubpageNode): React.ReactNode => {\n const { node, context, pageId } = displaySubpage\n\n const renderRowNode = (\n rowNode:\n | ItemDef\n | RadioItemDef\n | CheckboxItemDef\n | SubmenuDef\n | SubpageDef,\n rowContext: RowRenderContext,\n ): React.ReactNode => {\n const rowId = rowNode.id ?? rowNode.value\n\n if (rowNode.kind === 'item') {\n return (\n <React.Fragment key={rowId}>\n {rowNode.render({\n props: {\n id: rowId,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n closeOnClick: rowNode.closeOnClick,\n onSelect: rowNode.onSelect,\n shortcut: rowNode.shortcut,\n },\n context: {\n ...rowContext,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n },\n })}\n </React.Fragment>\n )\n }\n\n if (rowNode.kind === 'checkbox-item') {\n return (\n <React.Fragment key={rowId}>\n {rowNode.render({\n props: {\n id: rowId,\n value: rowNode.value,\n checked: rowNode.checked,\n onCheckedChange: rowNode.onCheckedChange,\n disabled: rowNode.disabled ?? false,\n closeOnClick: rowNode.closeOnClick,\n },\n context: {\n ...rowContext,\n value: rowNode.value,\n checked: rowNode.checked,\n disabled: rowNode.disabled ?? false,\n },\n })}\n </React.Fragment>\n )\n }\n\n if (rowNode.kind === 'radio-item') {\n return (\n <React.Fragment key={rowId}>\n {rowNode.render({\n props: {\n id: rowId,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n closeOnClick: rowNode.closeOnClick,\n onSelect: rowNode.onSelect,\n shortcut: rowNode.shortcut,\n },\n context: {\n ...rowContext,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n },\n })}\n </React.Fragment>\n )\n }\n\n if (rowNode.kind === 'submenu') {\n const submenuAsyncState = getBranchAsyncState(\n rowNode,\n rowContext.breadcrumbs,\n searchQuery,\n coordinator,\n )\n const staticNodes = rowNode.nodes ?? []\n const submenuBreadcrumb: BreadcrumbNode = {\n node: rowNode,\n value: rowNode.value,\n id: rowNode.id,\n }\n\n const submenuRenderNode = (childNode: NodeDef) => {\n if (childNode.kind === 'separator') {\n return null\n }\n\n if (childNode.kind === 'group') {\n const groupItems = childNode.nodes.filter(\n (n): n is ItemDef | CheckboxItemDef | SubmenuDef | SubpageDef =>\n (n.kind === 'item' ||\n n.kind === 'checkbox-item' ||\n n.kind === 'submenu' ||\n n.kind === 'subpage') &&\n !n.hidden,\n )\n\n if (groupItems.length === 0) {\n return null\n }\n\n const groupChildren = groupItems.map((item) =>\n renderRowNode(item, {\n search: null,\n breadcrumbs: [...rowContext.breadcrumbs, submenuBreadcrumb],\n isDeepSearchResult: false,\n highlighted: false,\n disabled: item.disabled ?? false,\n group: { id: childNode.id, label: childNode.label },\n }),\n )\n\n if (childNode.render) {\n const groupContext: GroupRenderContext = {\n search: null,\n matchCount: groupItems.length,\n breadcrumbs: [...rowContext.breadcrumbs, submenuBreadcrumb],\n isDeepSearchResult: false,\n }\n\n return (\n <React.Fragment key={childNode.id}>\n {childNode.render({\n props: {},\n context: {\n ...groupContext,\n label: childNode.label,\n },\n children: <>{groupChildren}</>,\n })}\n </React.Fragment>\n )\n }\n\n return (\n // biome-ignore lint/a11y/useSemanticElements: ignore for now\n <div\n key={childNode.id}\n role=\"group\"\n aria-label={childNode.label}\n >\n {groupChildren}\n </div>\n )\n }\n\n if (childNode.kind === 'radio-group') {\n return renderRadioGroup(childNode, [\n ...rowContext.breadcrumbs,\n submenuBreadcrumb,\n ])\n }\n\n if (\n childNode.kind !== 'item' &&\n childNode.kind !== 'checkbox-item' &&\n childNode.kind !== 'submenu' &&\n childNode.kind !== 'subpage'\n ) {\n return null\n }\n\n return renderRowNode(childNode, {\n search: null,\n breadcrumbs: [...rowContext.breadcrumbs, submenuBreadcrumb],\n isDeepSearchResult: false,\n highlighted: false,\n disabled: childNode.disabled ?? false,\n group: null,\n })\n }\n\n return (\n <React.Fragment key={rowId}>\n {rowNode.render({\n props: {\n id: rowId,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n },\n context: {\n ...rowContext,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n async: submenuAsyncState,\n },\n nodes: staticNodes,\n asyncContent: rowNode.asyncNodes,\n renderNode: submenuRenderNode,\n })}\n </React.Fragment>\n )\n }\n\n const subpageAsyncState = getBranchAsyncState(\n rowNode,\n rowContext.breadcrumbs,\n searchQuery,\n coordinator,\n )\n const targetPageId = getSubpagePageId(rowNode, rowContext.breadcrumbs)\n\n return (\n <React.Fragment key={targetPageId}>\n {rowNode.renderTrigger({\n props: {\n id: rowId,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n targetPageId,\n },\n context: {\n ...rowContext,\n value: rowNode.value,\n disabled: rowNode.disabled ?? false,\n async: subpageAsyncState,\n },\n })}\n </React.Fragment>\n )\n }\n\n const renderRadioGroup = (\n radioGroup: RadioGroupDef,\n breadcrumbs: BreadcrumbNode[] = [],\n ): React.ReactNode => {\n const isDeepSearchResult = breadcrumbs.length > 0\n\n const groupContext: GroupRenderContext = {\n search: null,\n matchCount: radioGroup.nodes.length,\n breadcrumbs,\n isDeepSearchResult,\n }\n\n const childElements = radioGroup.nodes.map((item) => {\n if (item.hidden) return null\n\n return renderRowNode(item, {\n search: null,\n breadcrumbs,\n isDeepSearchResult,\n highlighted: false,\n disabled: item.disabled ?? false,\n group: null,\n })\n })\n\n if (radioGroup.render) {\n return (\n <React.Fragment key={radioGroup.id}>\n {radioGroup.render({\n props: {\n value: radioGroup.value,\n onValueChange: radioGroup.onValueChange,\n disabled: radioGroup.disabled ?? false,\n },\n context: {\n ...groupContext,\n label: radioGroup.label,\n value: radioGroup.value,\n disabled: radioGroup.disabled ?? false,\n },\n children: <>{childElements}</>,\n })}\n </React.Fragment>\n )\n }\n\n return (\n <div\n key={radioGroup.id}\n role=\"radiogroup\"\n aria-label={radioGroup.label}\n >\n {childElements}\n </div>\n )\n }\n\n return (\n <React.Fragment key={pageId}>\n {node.renderContent({\n pageId,\n context: {\n ...context,\n value: node.value,\n disabled: node.disabled ?? false,\n async: getBranchAsyncState(\n node,\n context.breadcrumbs,\n searchQuery,\n coordinator,\n ),\n },\n nodes: node.nodes ?? [],\n asyncContent: node.asyncNodes,\n renderNode: (childNode) => {\n if (childNode.kind === 'separator') {\n return null\n }\n\n if (childNode.kind === 'group') {\n const groupItems = childNode.nodes.filter(\n (\n n,\n ): n is ItemDef | CheckboxItemDef | SubmenuDef | SubpageDef =>\n (n.kind === 'item' ||\n n.kind === 'checkbox-item' ||\n n.kind === 'submenu' ||\n n.kind === 'subpage') &&\n !n.hidden,\n )\n\n if (groupItems.length === 0) {\n return null\n }\n\n const groupChildren = groupItems.map((item) =>\n renderRowNode(item, {\n search: null,\n breadcrumbs: [\n ...context.breadcrumbs,\n {\n node,\n value: node.value,\n id: node.id,\n },\n ],\n isDeepSearchResult: false,\n highlighted: false,\n disabled: item.disabled ?? false,\n group: { id: childNode.id, label: childNode.label },\n }),\n )\n\n if (childNode.render) {\n const groupContext: GroupRenderContext = {\n search: null,\n matchCount: groupItems.length,\n breadcrumbs: [\n ...context.breadcrumbs,\n {\n node,\n value: node.value,\n id: node.id,\n },\n ],\n isDeepSearchResult: false,\n }\n\n return (\n <React.Fragment key={childNode.id}>\n {childNode.render({\n props: {},\n context: {\n ...groupContext,\n label: childNode.label,\n },\n children: <>{groupChildren}</>,\n })}\n </React.Fragment>\n )\n }\n\n return (\n // biome-ignore lint/a11y/useSemanticElements: ignore for now\n <div\n key={childNode.id}\n role=\"group\"\n aria-label={childNode.label}\n >\n {groupChildren}\n </div>\n )\n }\n\n if (childNode.kind === 'radio-group') {\n return renderRadioGroup(childNode, [\n ...context.breadcrumbs,\n {\n node,\n value: node.value,\n id: node.id,\n },\n ])\n }\n\n if (\n childNode.kind !== 'item' &&\n childNode.kind !== 'checkbox-item' &&\n childNode.kind !== 'submenu' &&\n childNode.kind !== 'subpage'\n ) {\n return null\n }\n\n return renderRowNode(childNode, {\n search: null,\n breadcrumbs: [\n ...context.breadcrumbs,\n {\n node,\n value: node.value,\n id: node.id,\n },\n ],\n isDeepSearchResult: false,\n highlighted: false,\n disabled: childNode.disabled ?? false,\n group: null,\n })\n },\n })}\n </React.Fragment>\n )\n },\n [coordinator, searchQuery],\n )\n\n if (!dataSurfaceContext) {\n return null\n }\n\n const childrenState: DataSubpagesChildrenState = {\n subpages,\n renderSubpageContent,\n }\n\n if (children) {\n return <>{children(childrenState)}</>\n }\n\n return <>{subpages.map(renderSubpageContent)}</>\n}\n\nexport namespace PopupMenuDataSubpages {\n export interface Props extends PopupMenuDataSubpagesProps {}\n export type ChildrenState = DataSubpagesChildrenState\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useSurfaceContext } from '../../listbox/index.js'\nimport { PopupMenuSurface } from '../components/surface/surface.js'\nimport { usePopupMenuContext } from '../contexts/popup-menu-context.js'\nimport { AsyncMenuCoordinatorProvider } from './async-coordinator.js'\nimport {\n DataSurfaceContext,\n type DataSurfaceContextValue,\n useMaybeDataPopupContext,\n} from './context.js'\nimport type { DataSurfaceProps, DeepSearchConfig } from './types.js'\nimport { defaultGetQualifiedRowId } from './utils.js'\n\nfunction DataSurfaceAsyncCoordinatorScope({\n children,\n}: {\n children: React.ReactNode\n}) {\n const { store } = useSurfaceContext()\n const searchQuery = store.useState('normalizedSearch')\n\n return (\n <AsyncMenuCoordinatorProvider searchQuery={searchQuery}>\n {children}\n </AsyncMenuCoordinatorProvider>\n )\n}\n\n// ============================================================================\n// DataSurface Component\n// ============================================================================\n\nexport interface PopupMenuDataSurfaceProps extends DataSurfaceProps {\n /** Custom class name */\n className?: string\n /** Custom styles */\n style?: React.CSSProperties\n /** Render function for custom element */\n render?: React.ReactElement\n}\n\n/**\n * DataSurface provides deep search functionality for popup menus.\n * It wraps the standard Surface and adds data-first search capabilities.\n *\n * Place inside PopupMenu.Popup to enable deep search functionality.\n * Renders a `<div>` element.\n */\nexport const PopupMenuDataSurface = React.forwardRef<\n HTMLDivElement,\n PopupMenuDataSurface.Props\n>(function PopupMenuDataSurface(props, forwardedRef) {\n const {\n content,\n asyncContent,\n deepSearch = true,\n includeInDeepSearch = true,\n filter: _filter,\n search: searchProp,\n normalizeSearch,\n onSearchChange,\n defaultSearch = '',\n loop = true,\n autoHighlightFirst = true,\n clearSearchOnClose = true,\n getQualifiedRowId: getQualifiedRowIdProp,\n className,\n style,\n render,\n children,\n } = props\n\n // Get getQualifiedRowId from popup menu context (set at Root level), or use prop, or use default\n const popupMenuContext = usePopupMenuContext()\n const getQualifiedRowId =\n getQualifiedRowIdProp ??\n popupMenuContext.getQualifiedRowId ??\n defaultGetQualifiedRowId\n\n // Parse deep search config\n const deepSearchConfig: DeepSearchConfig = React.useMemo(() => {\n if (typeof deepSearch === 'boolean') {\n return {\n enabled: deepSearch,\n minLength: 0,\n groupSearchBehavior: 'preserve',\n radioGroupSearchBehavior: 'preserve',\n sortGroups: true,\n asyncResultBehavior: 'stream',\n }\n }\n return {\n enabled: deepSearch.enabled ?? true,\n minLength: deepSearch.minLength ?? 0,\n groupSearchBehavior: deepSearch.groupSearchBehavior ?? 'preserve',\n radioGroupSearchBehavior:\n deepSearch.radioGroupSearchBehavior ?? 'preserve',\n sortGroups: deepSearch.sortGroups ?? true,\n asyncResultBehavior: deepSearch.asyncResultBehavior ?? 'stream',\n }\n }, [deepSearch])\n\n // Generate stable list ID\n const listId = React.useId()\n\n // Create DataSurface context value\n // Note: The actual filtering happens in DataList which has access to the store's search\n const contextValue: DataSurfaceContextValue = React.useMemo(\n () => ({\n content: content ?? [],\n asyncContent,\n deepSearchConfig,\n includeInDeepSearch,\n listId,\n getQualifiedRowId,\n }),\n [\n content,\n asyncContent,\n deepSearchConfig,\n includeInDeepSearch,\n listId,\n getQualifiedRowId,\n ],\n )\n\n const dataPopupContext = useMaybeDataPopupContext()\n const setDataSurfaceContext = dataPopupContext?.setDataSurfaceContext\n\n React.useEffect(() => {\n if (!setDataSurfaceContext) {\n return\n }\n\n setDataSurfaceContext(contextValue)\n\n return () => {\n setDataSurfaceContext((current) =>\n current === contextValue ? null : current,\n )\n }\n }, [setDataSurfaceContext, contextValue])\n\n return (\n <DataSurfaceContext.Provider value={contextValue}>\n <PopupMenuSurface\n ref={forwardedRef}\n // Disable Surface's built-in filtering - DataList handles filtering via filterNodes()\n filter={false}\n search={searchProp}\n normalizeSearch={normalizeSearch}\n onSearchChange={onSearchChange}\n defaultSearch={defaultSearch}\n loop={loop}\n autoHighlightFirst={autoHighlightFirst}\n clearSearchOnClose={clearSearchOnClose}\n className={className}\n style={style}\n render={render}\n >\n <DataSurfaceAsyncCoordinatorScope>\n {children}\n </DataSurfaceAsyncCoordinatorScope>\n </PopupMenuSurface>\n </DataSurfaceContext.Provider>\n )\n})\n\nexport namespace PopupMenuDataSurface {\n export interface Props extends PopupMenuDataSurfaceProps {}\n}\n"],"mappings":"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","names":["React","ComponentNameContext","useComponentName","context","useMaybeComponentName","getSlotAttribute","componentName","partName","React","FocusOwnerContext","useFocusOwner","context","useMaybeFocusOwner","React","OpenChainContext","useOpenChain","context","useMaybeOpenChain","React","PopupMenuContext","usePopupMenuContext","context","useMaybePopupMenuContext","React","clampNumber","value","min","max","toNumberOrDefault","defaultValue","defaultPopupMenuSafeTriangleAreaDebugSettings","resolvePopupMenuSafeTriangleAreaDebugConfig","config","legacyEnabled","defaults","triangleFillOpacity","overlayOpacity","strokeWidth","dotRadius","missFreezeDuration","defaultPopupMenuDebugContextValue","PopupMenuDebugContext","usePopupMenuDebug","React","PopupSurfaceIdContext","usePopupSurfaceId","React","SubmenuContext","useSubmenuContext","context","useMaybeSubmenuContext","React","SubpageContext","useSubpageContext","context","useMaybeSubpageContext","React","ROOT_SUBPAGE_ID","SubpageStackContext","useSubpageStack","context","useMaybeSubpageStack","React","jsx","AimGuardCtx","useAimGuard","AimGuardProvider","children","logAimGuardEvents","usePopupMenuDebug","aimGuardActive","setAimGuardActive","guardedTriggerId","setGuardedTriggerId","guardedDepth","setGuardedDepth","guardedSubmenuSurfaceId","setGuardedSubmenuSurfaceId","aimGuardActiveRef","guardedTriggerIdRef","guardedDepthRef","guardedSubmenuSurfaceIdRef","guardTimerRef","logAimGuard","eventName","details","resetAimGuardState","clearAimGuard","activateAimGuard","triggerId","depth","submenuSurfaceId","timeoutMs","isGuardBlocking","rowId","value","createSelector","ReactStore","selectors","state","surfaceId","FocusOwnerStore","id","createSelector","ReactStore","selectors","state","surfaceId","depth","OpenChainStore","newChain","id","resolveSideFromPoint","rect","x","y","outsideCandidates","leftGap","rightGap","topGap","bottomGap","a","b","insideDistances","resolveAnchorSide","tRect","mx","my","tx","ty","centerX","getSmoothedHeading","trail","exitX","exitY","anchor","dx","dy","n","i","x1","y1","x2","y2","edgeX","edgeCy","edgeY","willHitSubmenu","heading","triggerRect","isHorizontal","primary","t","projected","triggerCrossSize","baseBand","extra","min","max","React","mouseTrailSubscribers","removeMouseTrailListener","ensureMouseTrailListener","onMove","event","subscriber","trail","cleanupMouseTrailListenerIfIdle","useMouseTrail","n","trailRef","React","usePopupMenuRoot","params","onOpenChange","defaultOpen","virtualized","itemsProp","onHighlightChange","closeOnOutsidePress","disabledProp","defaultDisabled","imperativeDisabled","setImperativeDisabled","disabled","setDisabled","nextDisabled","outsidePointerEventRef","stableOnOpenChange","open","eventDetails","reason_parts_exports","pointerEvent","convertedDetails","createChangeEventDetails","store","ListboxStore","isOpen","focusOwnerStoreRef","FocusOwnerStore","focusOwnerStore","openChainStoreRef","OpenChainStore","openChainStore","surfaceRegistryRef","registerSurface","depth","setOpen","id","closeAll","reason","event","surfaces","a","b","surface","closeAllRef","handlePointerDown","target","isInsidePopup","isInsideTrigger","handleOpenChange","newOpen","isImperativeAction","virtualization","PopupMenuArrowDataAttributes","Popover","React","jsx","PopupMenuArrow","props","forwardedRef","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","Popover","PopupMenuBackdropDataAttributes","Popover","React","jsx","PopupMenuBackdrop","props","forwardedRef","showOnProp","rest","submenuContext","useMaybeSubmenuContext","openChainStore","useOpenChain","focusOwnerStore","useFocusOwner","isSubmenu","surfaceId","showOn","isInOpenChain","isLastInChain","isFocusOwner","shouldShow","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","style","Popover","PopupMenuPopupDataAttributes","Popover","React","React","ComboboxContext","useComboboxContext","context","useMaybeComboboxContext","React","DataSurfaceContext","DataPopupContext","useDataSurfaceContext","context","useMaybeDataSurfaceContext","useDataPopupContext","useMaybeDataPopupContext","jsx","SUBPAGE_NAVIGATING_MS","PopupMenuPopup","props","forwardedRef","children","classNameProp","renderProp","rest","submenuContext","useMaybeSubmenuContext","clearAimGuard","aimGuardActiveRef","guardedSubmenuSurfaceIdRef","useAimGuard","focusOwnerStore","useFocusOwner","openChainStore","useOpenChain","popupMenuContext","useMaybePopupMenuContext","depth","comboboxContext","useMaybeComboboxContext","generatedSurfaceId","surfaceId","subpageStack","setSubpageStack","ROOT_SUBPAGE_ID","dataSurfaceContext","setDataSurfaceContext","subpageStackRef","subpagesRef","setSubpageRegistryVersion","isSubpageNavigating","setIsSubpageNavigating","subpageNavigatingTimerRef","clearSubpageNavigatingTimer","beginSubpageNavigation","v","registerPage","registration","prev","next","id","openPage","pageId","currentStack","goBack","getSurfaceId","resetSubpageNavigationState","store","previous","handlePopupCloseComplete","activePageId","activePageRegistration","activeSurfaceId","shouldCloseRootOnEsc","canGoBack","openSubpageIds","subpageId","hasOpenSubpage","openTimeRef","isFocused","hasOpenSubmenu","popupRef","combinedRef","node","handlePointerMove","handleFocusTransferOnMove","event","target","targetElement","closestPopup","initialFocus","finalFocus","isInputEmbedded","isSubmenu","toPopupState","baseState","className","render","popupProps","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","subpageStackContextValue","dataPopupContextValue","PopupSurfaceIdContext","SubpageStackContext","DataPopupContext","Popover","Popover","PopupMenuPortal","PopupMenuPositionerCssVars","PopupMenuPositionerDataAttributes","Popover","React","flushSync","jsx","LIST_START_OFFSET_EPSILON","getDefaultCollisionAvoidance","side","isHorizontalSide","PopupMenuPositioner","props","ref","sideProp","alignProp","alignOffsetProp","collisionAvoidanceProp","virtualAnchorProp","styleProp","rest","store","depth","contextVirtualAnchor","menuType","usePopupMenuContext","submenuContext","useMaybeSubmenuContext","listStartOffsetRef","hasMeasuredRef","forceUpdate","x","suppressResizeMeasurementRef","suppressionRafIdsRef","clearSuppressionRafs","clearInputActivationSuppression","suppressResizeForInputActivation","isSubmenu","virtualAnchor","align","useListStartAlign","baseUIAlign","isOpen","inputActive","hideUntilActive","prevInputActiveRef","measureListStartOffset","contentEl","contentRect","listEl","previousOffset","listRect","listStyles","listPaddingTop","nextOffset","resizeObserver","flushSync","wasInputActive","effectiveAlignOffset","collisionAvoidance","anchorProps","style","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","Popover","React","jsx","PopupMenuProviders","props","store","focusOwnerStore","openChainStore","disabled","depth","closeAll","registerSurface","virtualization","debug","virtualAnchor","menuType","closeOnOutsidePress","getQualifiedRowId","componentName","children","popupMenuContextValue","listboxContextValue","popupMenuDebugContextValue","resolvePopupMenuSafeTriangleAreaDebugConfig","ComponentNameContext","PopupMenuDebugContext","PopupMenuContext","ListboxContext","AimGuardProvider","FocusOwnerContext","OpenChainContext","React","usePopupMenuItem","params","closeOnClick","disabled","rest","aimGuardActiveRef","guardedDepthRef","useAimGuard","closeAll","useListboxContext","menuDisabled","useMaybePopupMenuContext","effectiveDisabled","aimGuard","handleAfterSelect","itemId","item","useListboxItem","React","usePopupMenuKeyboard","params","store","surfaceId","focusOwnerStore","depth","submenuContext","subpageContext","enabled","disabled","enableTypeToSearch","onKeyDown","closeAll","skipFocusOwnerCheck","submenuInterface","subpageInterface","handleSelect","details","useListboxKeyboard","PopupMenuIconDataAttributes","useRender","React","resolveLabel","value","itemToStringLabel","label","stringifyAsValue","itemToStringValue","stateAttributesMapping","value","PopupMenuIconDataAttributes","PopupMenuIcon","props","forwardedRef","render","className","style","children","onPointerDown","onClick","rest","store","usePopupMenuContext","open","comboboxContext","useMaybeComboboxContext","state","handlePointerDown","event","handleClick","valueKey","stringifyAsValue","labelValue","resolveLabel","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","useRender","React","React","jsx","AsyncMenuCoordinatorContext","useAsyncMenuCoordinator","useMaybeAsyncMenuCoordinator","AsyncMenuCoordinatorProvider","props","children","searchQuery","loaders","setLoaders","erroredLoaders","setErroredLoaders","registerLoader","state","prev","next","unregisterLoader","id","updateLoaderResult","result","existing","isStaticFetching","isStaticLoading","isStaticInitialLoading","isStaticRefetching","isQueryFetching","isQueryLoading","isQueryInitialLoading","isQueryRefetching","isAnyFetching","isAnyLoading","isAnyInitialLoading","isAnyRefetching","isAllRefetching","isRootLoading","allResolved","getAsyncNodes","getAsyncState","skippedMenus","contextValue","PopupMenuEmpty","props","forwardedRef","render","className","style","children","rest","store","useSurfaceContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","asyncCoordinator","useMaybeAsyncMenuCoordinator","isLoading","hasNoResults","useRender","React","PopupMenuInput","props","forwardedRef","controlledValue","onValueChange","hideUntilActive","disabledProp","render","className","style","onKeyDown","rest","store","surfaceId","useSurfaceContext","depth","closeAll","useListboxContext","submenuContext","useMaybeSubmenuContext","subpageContext","useMaybeSubpageContext","popupMenuDisabled","usePopupMenuContext","disabled","focusOwnerStore","useFocusOwner","internalRef","search","highlightedId","listId","inputId","inputActive","pendingSearch","shouldRender","displayValue","handleChange","event","newValue","handleKeyDown","usePopupMenuKeyboard","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","useRender","React","PopupMenuListCssVars","PopupMenuListDataAttributes","jsx","PopupMenuList","props","forwardedRef","children","label","measureRowWidth","maxRowWidth","render","className","style","onKeyDown","onPointerDown","rest","store","surfaceId","useSurfaceContext","depth","closeAll","useListboxContext","submenuContext","useMaybeSubmenuContext","subpageContext","useMaybeSubpageContext","popupMenuDisabled","usePopupMenuContext","focusOwnerStore","useFocusOwner","comboboxContext","useMaybeComboboxContext","internalRef","popupRef","popup","queueMeasurement","resetMeasurements","useStickyRowWidth","rowWidthContextValue","search","filteredCount","hasInput","highlightedId","listId","shouldHandleKeyboard","handleKeyDown","usePopupMenuKeyboard","handlePointerDown","event","childrenState","renderedChildren","wrappedChildren","jsx","RowWidthContext","isInputEmbedded","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","useRender","React","PopupMenuLoading","props","forwardedRef","forceMount","render","className","style","children","rest","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","asyncCoordinator","useMaybeAsyncMenuCoordinator","isLoading","PopupMenuScrollArrowDataAttributes","useRender","React","jsx","stateAttributesMapping","value","PopupMenuScrollArrowDataAttributes","PopupMenuScrollArrow","props","forwardedRef","direction","keepMounted","scrollSpeed","render","className","style","children","rest","store","useSurfaceContext","visible","setVisible","scrollingRef","rafRef","checkVisibility","list","atBottom","resizeObserver","filteredCount","startScrolling","scroll","delta","stopScrolling","state","shouldRender","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","event","PopupMenuScrollUpArrow","jsx","PopupMenuScrollDownArrow","useRender","useStableCallback","React","jsx","PopupMenuSurface","props","forwardedRef","filter","defaultFilter","normalizeSearch","normalizeValue","searchProp","onSearchChange","defaultSearch","loop","autoHighlightFirst","clearSearchOnClose","skipAutoFocus","orderedItems","render","className","style","onPointerDown","onPointerMove","children","rest","store","depth","virtualization","useListboxContext","submenuContext","useMaybeSubmenuContext","subpageContext","useMaybeSubpageContext","subpageStack","useMaybeSubpageStack","focusOwnerStore","useFocusOwner","openTimeRef","listId","inputId","generatedSurfaceId","surfaceId","usePopupSurfaceId","isSurfaceActive","ROOT_SUBPAGE_ID","isOwner","handleSearchChange","useStableCallback","search","open","surfaceRef","timeoutId","input","list","focusTarget","contextValue","handlePointerDown","event","handlePointerMove","target","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","SurfaceContext","useRender","React","PopupMenuCheckboxItemDataAttributes","React","CheckboxItemContext","useCheckboxItemContext","context","jsx","stateAttributesMapping","value","PopupMenuCheckboxItem","props","forwardedRef","id","checkedProp","defaultChecked","onCheckedChange","keywords","disabledProp","onSelect","forceMount","closeOnClick","shortcut","forceOrder","forceScore","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","internalChecked","setInternalChecked","isControlled","checked","toggleChecked","reason","reason_parts_exports","event","newChecked","eventDetails","createChangeEventDetails","item","usePopupMenuItem","disabled","handleSelect","state","checkboxItemContextValue","handleClick","handlePointerDown","handlePointerMove","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","jsx","ItemContext","CheckboxItemContext","useRender","React","stateAttributesMapping","value","PopupMenuCheckboxItemIndicator","props","forwardedRef","keepMounted","render","className","style","children","rest","checked","highlighted","disabled","toggle","useCheckboxItemContext","state","shouldRender","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","useRender","React","PopupMenuItemDataAttributes","jsx","stateAttributesMapping","value","PopupMenuItem","props","forwardedRef","id","keywords","disabledProp","onSelect","forceMount","closeOnClick","shortcut","forceOrder","forceScore","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","item","usePopupMenuItem","disabled","state","handleClick","event","handlePointerDown","handlePointerMove","wrappedChildren","jsx","ItemContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","useRender","React","PopupMenuRadioGroupDataAttributes","React","RadioGroupContext","useRadioGroupContext","context","jsx","stateAttributesMapping","value","PopupMenuRadioGroup","props","forwardedRef","valueProp","defaultValue","onValueChange","disabledProp","forceMount","render","className","style","children","rest","store","useSurfaceContext","popupMenuContext","usePopupMenuContext","groupId","disabled","internalValue","setInternalValue","isControlled","setValue","newValue","reason","reason_parts_exports","event","eventDetails","createChangeEventDetails","isGroupVisible","isVisible","radioGroupContextValue","groupContextValue","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","jsx","RadioGroupContext","GroupContext","React","jsx","PopupMenuRadioGroupValue","props","value","onValueChange","disabled","children","setValue","newValue","reason","reason_parts_exports","event","eventDetails","createChangeEventDetails","contextValue","RadioGroupContext","useRender","React","PopupMenuRadioItemDataAttributes","React","RadioItemContext","useRadioItemContext","context","jsx","stateAttributesMapping","value","PopupMenuRadioItem","props","forwardedRef","id","keywords","disabledProp","onSelect","forceMount","closeOnClick","shortcut","forceOrder","forceScore","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","radioGroupContext","useRadioGroupContext","localDisabled","checked","item","usePopupMenuItem","disabled","handleSelect","state","radioItemContextValue","handleClick","event","handlePointerDown","handlePointerMove","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","jsx","ItemContext","RadioItemContext","useRender","React","stateAttributesMapping","value","PopupMenuRadioItemIndicator","props","forwardedRef","keepMounted","render","className","style","children","rest","checked","highlighted","disabled","useRadioItemContext","state","shouldRender","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","useRender","React","jsx","PopupMenuGroup","props","forwardedRef","forceMount","render","className","style","children","rest","store","useSurfaceContext","groupId","isGroupVisible","isVisible","groupContextValue","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","GroupContext","useRender","React","PopupMenuGroupLabel","props","forwardedRef","render","className","style","children","rest","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","useRender","React","PopupMenuSeparator","props","forwardedRef","alwaysRender","render","className","style","rest","store","useSurfaceContext","isHidden","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","useRender","React","PopupMenuShortcutDataAttributes","stateAttributesMapping","value","PopupMenuShortcut","props","forwardedRef","children","render","className","style","rest","shortcut","highlighted","useItemContext","state","renderedChildren","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","Popover","React","jsx","PopupMenuSubmenuRoot","props","openProp","onOpenChange","defaultOpen","closeRootOnEsc","virtualized","itemsProp","onHighlightChange","onOpenChangeCompleteProp","disabledProp","actionsRef","children","rest","parentListboxContext","useMaybeListboxContext","parentPopupMenuContext","useMaybePopupMenuContext","parentDepth","parentCloseAll","parentRegisterSurface","parentSurfaceId","useSurfaceContext","childSurfaceId","triggerRef","contentRef","store","ListboxStore","imperativeDisabled","setImperativeDisabled","disabled","setDisabled","nextDisabled","setOpen","newOpen","openChainStore","useOpenChain","open","handlePopoverOpenChange","eventDetails","handleOpenChangeComplete","nextOpen","parentOpen","setParentOpen","parentStore","checkParentOpen","isOpen","depth","popoverActionsRef","submenuContextValue","fallbackRegisterSurface","virtualization","listboxContextValue","popupMenuContextValue","SubmenuContext","PopupMenuContext","ListboxContext","Popover","Popover","useRender","React","isMouseLikePointerType","pointerType","strict","mouseLikeTypes","React","createPortal","React","useMousePosition","position","setPosition","onMove","event","jsx","jsxs","PopupMenuSubmenuSafeTriangleArea","props","config","contentRef","triggerRef","tone","contentRectOverride","triggerRectOverride","mousePointOverride","liveMouseX","liveMouseY","useMousePosition","isCoarse","contentElement","rect","triggerRect","mouseX","mouseY","x","y","width","height","anchor","resolveAnchorSide","inset","yPct","triangleWidth","overlayOpacity","triangleFillOpacity","borderStrokeWidth","requestedDotRadius","maxAllowedInset","borderInset","cornerDotRadius","apexY","left","toneColor","trianglePoints","polygonPoints","px","py","triangle","cx","cy","createPortal","useRender","React","PopupMenuSubmenuTriggerDataAttributes","stateAttributesMapping","value","PopupMenuSubmenuTriggerIndicator","props","forwardedRef","render","className","style","children","rest","open","childSurfaceId","useSubmenuContext","isPopupFocused","useFocusOwner","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","Fragment","jsx","jsxs","stateAttributesMapping","value","PopupMenuSubmenuTrigger","props","forwardedRef","idProp","keywords","disabledProp","forceMount","openOnHighlight","delayProp","closeDelay","forceOrder","forceScore","render","className","style","onPointerDown","onPointerMove","onPointerEnter","onPointerLeave","children","rest","delay","parentStore","useSurfaceContext","depth","useListboxContext","parentDepth","submenuContext","useSubmenuContext","open","setOpen","triggerRef","contentRef","childSurfaceId","openTimerRef","closeTimerRef","leaveMonitorCleanupRef","leaveMonitorTimerRef","clearOpenTimer","clearCloseTimer","scheduleClose","clearLeaveMonitor","suppressAutoOpenRef","focusOwnerStore","useFocusOwner","aimGuardActive","guardedTriggerId","guardedDepth","aimGuardActiveRef","guardedTriggerIdRef","guardedDepthRef","activateAimGuard","clearAimGuard","useAimGuard","mouseTrailRef","useMouseTrail","showSafeTriangleArea","logAimGuardEvents","usePopupMenuDebug","showSafeTriangleAreaEnabled","submenuSafeTriangleDebugState","setSubmenuSafeTriangleDebugState","submenuSafeTriangleDebugSnapshot","setSubmenuSafeTriangleDebugSnapshot","missSafeTriangleTimerRef","item","usePopupMenuItem","disabled","logAimTrace","eventName","details","clearMissSafeTriangleTimer","showActivatedSafeTriangle","snapshot","showMissedSafeTriangle","hideAfter","startLeaveMonitor","anchor","triggerRect","initialHit","timeoutMs","initialPointerX","initialPointerY","lastHit","previousPointerX","previousPointerY","onWindowPointerMove","pointerEvent","isMouseLikePointerType","contentRect","clientX","clientY","isInsidePopup","axisDelta","movedAwayFromSubmenu","debugSnapshot","heading","getSmoothedHeading","hit","willHitSubmenu","contentEl","handlePointerEnterContent","handlePointerMoveContent","input","list","focusTarget","isPopupFocused","prevOpenRef","keyboardDelay","handlePointerDown","event","handlePointerMove","pointerDelay","handlePointerEnter","handlePointerLeave","tRect","resolveAnchorSide","state","wrappedChildren","ItemContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","useRender","safeTriangleTone","trigger","Popover","PopupMenuSubmenuSafeTriangleArea","React","jsx","PopupMenuSubpage","props","pageId","closeRootOnEsc","children","parentListboxContext","useMaybeListboxContext","parentPopupMenuContext","useMaybePopupMenuContext","subpageStack","useSubpageStack","ROOT_SUBPAGE_ID","store","ListboxStore","surfaceId","parentOpen","activePageId","stack","registerPage","goBack","getSurfaceId","isActive","nextOpen","parentSurfaceId","currentIndex","previousPageId","subpageContextValue","listboxContextValue","popupMenuContextValue","shouldRenderChildren","SubpageContext","PopupSurfaceIdContext","PopupMenuContext","ListboxContext","PopupMenuSubpageBackDataAttributes","useRender","React","stateAttributesMapping","value","PopupMenuSubpageBack","props","forwardedRef","disabledProp","render","className","style","onClick","children","rest","subpageContext","useSubpageContext","subpageStack","useSubpageStack","focusOwnerStore","useFocusOwner","popupMenuContext","usePopupMenuContext","disabled","handleClick","event","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","PopupMenuSubpageBackItemDataAttributes","useRender","React","jsx","stateAttributesMapping","value","PopupMenuSubpageBackItem","props","forwardedRef","id","keywords","disabledProp","forceMount","onSelect","onSelectAsync","render","className","style","onClick","onPointerMove","onPointerDown","children","rest","subpageContext","useSubpageContext","focusOwnerStore","useFocusOwner","isPending","setIsPending","abortControllerRef","goBack","didGoBack","handleBack","controller","didNavigate","context","result","item","usePopupMenuItem","disabled","state","handleClick","event","handlePointerDown","handlePointerMove","wrappedChildren","jsx","ItemContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","PopupMenuSubpageTriggerDataAttributes","useRender","React","jsx","stateAttributesMapping","value","PopupMenuSubpageTrigger","props","forwardedRef","idProp","keywords","disabledProp","forceMount","forceOrder","forceScore","targetPageId","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","focusOwnerStore","useFocusOwner","subpageStack","useSubpageStack","activePageId","openPage","getSurfaceId","openTargetPage","targetSurfaceId","item","usePopupMenuItem","disabled","isTargetOpen","isPopupFocused","handlePointerDown","event","handleClick","handlePointerMove","state","wrappedChildren","jsx","ItemContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","useRender","React","defineRadioGroup","def","isDisplayGroupNode","node","isDisplayRadioGroupNode","isDisplaySeparatorNode","isDisplayRowNode","identityQuery","query","defaultGetQualifiedRowId","ctx","slugValue","slugify","slugBreadcrumbs","b","getSubpagePageId","node","breadcrumbs","breadcrumbSegments","breadcrumb","leafSegment","path","isItemDef","isRadioItemDef","isCheckboxItemDef","isSubmenuDef","isSubpageDef","isGroupDef","isRadioGroupDef","isSeparatorDef","flattenNodes","nodes","options","deep","includeInDeepSearch","descendantsIncluded","group","radioGroup","result","groupInfo","radioGroupInfo","branchIncludeMode","branchBreadcrumb","childBreadcrumbs","scoreNodes","flattenedNodes","normalizeQuery","normalizeValue","normalizedQuery","results","normalizedValue","normalizedKeywords","k","fuzzyScore","commandScore","score","getNodeForceOrder","compareScoredNodesByForceOrderAndScore","a","orderDiff","getRowKindSortRank","kind","sortByForceOrderThenKindThenScore","kindDiff","getMinForceOrderFromDisplayRows","minForceOrder","item","forceOrder","sortByScore","partitionByKind","byForceOrder","bucket","sortedForceOrders","deduplicateNodes","seen","scoredNode","compositeId","buildDisplayRowNodes","scoredNodes","highlightedId","isDeepSearchResult","context","buildDisplayRowNode","getBrowseNodesFlatten","getBrowseNodesPreserve","groupItems","child","itemContext","groupContext","radioItems","filterNodesFlatten","deepSearch","minLength","radioGroupSearchBehavior","shouldDeepSearch","flattened","allRadioGroupItems","flatNode","existing","scored","radioGroupItems","regularItems","sorted","partitioned","unique","regularDisplayNodes","radioGroupDisplayNodes","radioGroupId","radioGroupDef","matchingItems","itemsToDisplay","allItems","matchingScores","bestScore","allNodes","r","n","filterNodesPreserve","sortGroups","groupedItems","radioGroupedItems","ungroupedItems","groupDisplayNodes","_groupId","groupDef","items","ungroupedDisplayNodes","g","filterNodes","groupSearchBehavior","normalizedOptions","getNavigableIds","displayNodes","ids","isDisplayGroupNode","isDisplayRadioGroupNode","isDisplaySeparatorNode","getFirstNavigableId","collectAsyncSubmenus","shouldIncludeBranchDescendants","id","mergeSubmenuNodes","staticNodes","asyncNodes","static_","async_","mergeAsyncNodesIntoTree","staticContent","asyncData","asyncMap","data","mergeRecursive","currentBreadcrumbs","branchPath","mergedStaticChildren","mergedChildren","shouldIncludeInDeepSearch","shouldIncludeSubmenuRowsInDeepSearch","shouldLoadEagerly","config","Fragment","jsx","jsxs","computeItemIds","displayNodes","getQualifiedRowId","isDeepSearching","index","displayNode","isDisplayGroupNode","item","isDisplayRadioGroupNode","isDisplaySeparatorNode","getOrderedItemIds","ids","isAppendOnlyOrderedItemsUpdate","previousIds","nextIds","i","getBreadcrumbStreamKey","breadcrumbs","breadcrumb","getDisplayNodeStreamKey","identityQuery","query","orderDisplayNodesForStreaming","previousOrder","currentEntries","node","currentByKey","currentOrder","key","preservedOrder","preservedKeysSet","appendedOrder","nextOrder","resolveInitialQueryBehavior","config","resolveQueryExecutionState","minLength","initialQueryBehavior","getAsyncLoaderIdForBranch","normalizeValue","AsyncLoaderRenderer","info","enabled","coordinator","useAsyncMenuCoordinator","id","Loader","queryExecution","effectiveQuery","shouldFetch","shouldLoadEagerly","result","AsyncLoaderResultHandler","breadcrumbsRef","configRef","coordinatorRef","resultRef","prevResultRef","coord","state","prev","RootAsyncLoader","dataSurfaceCtx","useDataSurfaceContext","asyncContent","PopupMenuDataList","props","forwardedRef","content","deepSearchConfig","includeInDeepSearch","store","useSurfaceContext","search","normalizedSearch","DataListInner","children","label","className","style","render","measureRowWidth","maxRowWidth","asyncSubmenus","collectAsyncSubmenus","isDeepSearchActive","shouldRenderAsyncLoaders","s","asyncNodes","mergedContent","mergeAsyncNodesIntoTree","contentWithRootAsync","rootAsyncData","n","streamOrderRef","filterNodes","asyncResultBehavior","expectedAsyncLoaderCount","hasAsyncSources","shouldBlockAsyncResults","displayNodesToRender","previousStreamState","orderedNodes","prevOrderedItemIdsRef","prevOrderedItemsSearchRef","orderedItemsUpdateReasonRef","newOrderedItemIds","orderedItemIds","current","shouldUseAppendReason","renderRowNode","context","compositeId","getBranchAsyncState","branchNode","asyncLoaderId","asyncResult","isBelowMinLength","submenuAsyncState","staticNodes","submenuBreadcrumb","submenuRenderNode","childNode","groupItems","groupChildren","itemContext","groupContext","renderRadioGroup","childContext","subpageAsyncState","pageId","getSubpagePageId","radioGroup","isDeepSearchResult","childElements","renderNode","group","items","separator","asyncState","childrenState","renderedChildren","PopupMenuList","React","Fragment","jsx","resolveInitialQueryBehavior","config","resolveQueryExecutionState","query","minLength","initialQueryBehavior","getAsyncLoaderIdForBranch","node","breadcrumbs","breadcrumb","normalizeValue","getBranchAsyncState","searchQuery","coordinator","asyncLoaderId","asyncResult","isBelowMinLength","collectDisplaySubpages","nodes","group","result","getSubpagePageId","PopupMenuDataSubpages","props","children","useAsyncMenuCoordinator","dataSurfaceContext","useDataPopupContext","content","asyncNodes","mergedContent","mergeAsyncNodesIntoTree","subpages","renderSubpageContent","displaySubpage","context","pageId","renderRowNode","rowNode","rowContext","rowId","submenuAsyncState","staticNodes","submenuBreadcrumb","submenuRenderNode","childNode","groupItems","n","groupChildren","item","groupContext","renderRadioGroup","subpageAsyncState","targetPageId","radioGroup","isDeepSearchResult","childElements","childrenState","React","jsx","DataSurfaceAsyncCoordinatorScope","children","store","useSurfaceContext","searchQuery","AsyncMenuCoordinatorProvider","PopupMenuDataSurface","props","forwardedRef","content","asyncContent","deepSearch","includeInDeepSearch","_filter","searchProp","normalizeSearch","onSearchChange","defaultSearch","loop","autoHighlightFirst","clearSearchOnClose","getQualifiedRowIdProp","className","style","render","popupMenuContext","usePopupMenuContext","getQualifiedRowId","defaultGetQualifiedRowId","deepSearchConfig","listId","contextValue","setDataSurfaceContext","useMaybeDataPopupContext","current","DataSurfaceContext","PopupMenuSurface"]}