@bazza-ui/react 0.0.0-snapshot-20260205122957
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.
- package/dist/command-score-BuKQkUmS.d.cts +36 -0
- package/dist/command-score-C6nHV08C.d.ts +36 -0
- package/dist/data-surface-Dki7544r.d.ts +2136 -0
- package/dist/data-surface-Dyb-d-72.d.cts +2136 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3296 -0
- package/dist/index.d.ts +3296 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/listbox/index.cjs +2 -0
- package/dist/internal/listbox/index.cjs.map +1 -0
- package/dist/internal/listbox/index.d.cts +253 -0
- package/dist/internal/listbox/index.d.ts +253 -0
- package/dist/internal/listbox/index.js +2 -0
- package/dist/internal/listbox/index.js.map +1 -0
- package/dist/internal/popup-menu/index.cjs +2 -0
- package/dist/internal/popup-menu/index.cjs.map +1 -0
- package/dist/internal/popup-menu/index.d.cts +925 -0
- package/dist/internal/popup-menu/index.d.ts +925 -0
- package/dist/internal/popup-menu/index.js +2 -0
- package/dist/internal/popup-menu/index.js.map +1 -0
- package/dist/use-listbox-item-bi01_uzf.d.cts +659 -0
- package/dist/use-listbox-item-bi01_uzf.d.ts +659 -0
- package/package.json +62 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/adapters/tanstack-query.tsx","../src/adapters/vanilla.tsx","../src/combobox/index.parts.ts","../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-surface-id-context.ts","../src/internal/popup-menu/contexts/submenu-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/utils/events/reason-parts.ts","../src/utils/events/create-event-details.ts","../src/internal/listbox/contexts/group-context.ts","../src/internal/listbox/contexts/item-context.ts","../src/internal/listbox/contexts/listbox-context.ts","../src/internal/listbox/contexts/row-width-context.ts","../src/internal/listbox/contexts/surface-context.ts","../src/internal/listbox/hooks/use-listbox-item.ts","../src/internal/listbox/utils/normalize.ts","../src/internal/listbox/hooks/use-listbox-keyboard.ts","../src/internal/listbox/hooks/use-sticky-row-width.ts","../src/internal/listbox/store/ListboxStore.ts","../src/internal/listbox/utils/command-score.ts","../src/internal/popup-menu/components/arrow/arrow.tsx","../src/internal/popup-menu/components/backdrop/backdrop.tsx","../src/internal/popup-menu/components/popup/popup.tsx","../src/combobox/contexts/combobox-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.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/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/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-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/radio-group/radio-group.tsx","../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-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/submenu-root/submenu-root.tsx","../src/internal/popup-menu/components/submenu-trigger/submenu-trigger.tsx","../src/internal/popup-menu/components/submenu-trigger/submenu-trigger-indicator.tsx","../src/internal/popup-menu/deep-search/async-coordinator.tsx","../src/internal/popup-menu/deep-search/context.ts","../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-surface.tsx","../src/combobox/clear/clear.tsx","../src/combobox/clear/clear.data-attrs.ts","../src/combobox/contexts/combobox-positioner-context.ts","../src/combobox/input/input.tsx","../src/combobox/input-wrapper/input-wrapper-context.ts","../src/combobox/input/input.data-attrs.ts","../src/combobox/input/use-combobox-display-value.ts","../src/combobox/input/use-combobox-input-behavior.ts","../src/combobox/input-wrapper/input-wrapper.tsx","../src/combobox/input-wrapper/input-wrapper.data-attrs.ts","../src/combobox/item/item.tsx","../src/utils/item-equality.ts","../src/combobox/item/item.data-attrs.ts","../src/combobox/item/item-context.ts","../src/combobox/item-indicator/item-indicator.tsx","../src/combobox/item-indicator/item-indicator.data-attrs.ts","../src/combobox/item-label/item-label.tsx","../src/combobox/item-label/item-label.data-attrs.ts","../src/combobox/positioner/positioner.tsx","../src/combobox/positioner/positioner.data-attrs.ts","../src/combobox/root/root.tsx","../src/combobox/surface/surface.tsx","../src/combobox/surface/surface.data-attrs.ts","../src/combobox/arrow/arrow.data-attrs.ts","../src/combobox/backdrop/backdrop.data-attrs.ts","../src/combobox/empty/empty.data-attrs.ts","../src/combobox/group/group.data-attrs.ts","../src/combobox/group-label/group-label.data-attrs.ts","../src/combobox/icon/icon.data-attrs.ts","../src/combobox/list/list.data-attrs.ts","../src/combobox/popup/popup.data-attrs.ts","../src/combobox/scroll-arrow/scroll-arrow.data-attrs.ts","../src/combobox/separator/separator.data-attrs.ts","../src/context-menu/index.parts.ts","../src/context-menu/root/root.tsx","../src/context-menu/trigger/trigger.tsx","../src/context-menu/trigger/trigger.data-attrs.ts","../src/context-menu/arrow/arrow.data-attrs.ts","../src/context-menu/backdrop/backdrop.data-attrs.ts","../src/context-menu/checkbox-item/checkbox-item.data-attrs.ts","../src/context-menu/empty/empty.data-attrs.ts","../src/context-menu/group/group.data-attrs.ts","../src/context-menu/group-label/group-label.data-attrs.ts","../src/context-menu/icon/icon.data-attrs.ts","../src/context-menu/input/input.data-attrs.ts","../src/context-menu/item/item.data-attrs.ts","../src/context-menu/list/list.data-attrs.ts","../src/context-menu/popup/popup.data-attrs.ts","../src/context-menu/positioner/positioner.data-attrs.ts","../src/context-menu/radio-group/radio-group.data-attrs.ts","../src/context-menu/radio-item/radio-item.data-attrs.ts","../src/context-menu/scroll-arrow/scroll-arrow.data-attrs.ts","../src/context-menu/separator/separator.data-attrs.ts","../src/context-menu/shortcut/shortcut.data-attrs.ts","../src/context-menu/submenu-trigger/submenu-trigger.data-attrs.ts","../src/context-menu/surface/surface.data-attrs.ts","../src/dropdown-menu/index.parts.ts","../src/dropdown-menu/root/root.tsx","../src/dropdown-menu/trigger/trigger.tsx","../src/dropdown-menu/trigger/trigger.data-attrs.ts","../src/dropdown-menu/arrow/arrow.data-attrs.ts","../src/dropdown-menu/backdrop/backdrop.data-attrs.ts","../src/dropdown-menu/checkbox-item/checkbox-item.data-attrs.ts","../src/dropdown-menu/empty/empty.data-attrs.ts","../src/dropdown-menu/group/group.data-attrs.ts","../src/dropdown-menu/group-label/group-label.data-attrs.ts","../src/dropdown-menu/icon/icon.data-attrs.ts","../src/dropdown-menu/input/input.data-attrs.ts","../src/dropdown-menu/item/item.data-attrs.ts","../src/dropdown-menu/list/list.data-attrs.ts","../src/dropdown-menu/popup/popup.data-attrs.ts","../src/dropdown-menu/positioner/positioner.data-attrs.ts","../src/dropdown-menu/radio-group/radio-group.data-attrs.ts","../src/dropdown-menu/radio-item/radio-item.data-attrs.ts","../src/dropdown-menu/scroll-arrow/scroll-arrow.data-attrs.ts","../src/dropdown-menu/separator/separator.data-attrs.ts","../src/dropdown-menu/shortcut/shortcut.data-attrs.ts","../src/dropdown-menu/submenu-trigger/submenu-trigger.data-attrs.ts","../src/dropdown-menu/surface/surface.data-attrs.ts","../src/select/index.parts.ts","../src/select/item/item.tsx","../src/select/contexts/select-context.ts","../src/select/item/item.data-attrs.ts","../src/select/item/item-context.ts","../src/select/item-indicator/item-indicator.tsx","../src/select/item-indicator/item-indicator.data-attrs.ts","../src/select/item-label/item-label.tsx","../src/select/item-label/item-label.data-attrs.ts","../src/select/popup/popup.tsx","../src/select/contexts/select-positioner-context.ts","../src/select/positioner/positioner.tsx","../src/select/positioner/positioner.data-attrs.ts","../src/select/root/root.tsx","../src/select/surface/surface.tsx","../src/select/surface/surface.data-attrs.ts","../src/select/trigger/trigger.tsx","../src/select/trigger/trigger.data-attrs.ts","../src/select/value/value.tsx","../src/select/value/value.data-attrs.ts","../src/select/arrow/arrow.data-attrs.ts","../src/select/backdrop/backdrop.data-attrs.ts","../src/select/empty/empty.data-attrs.ts","../src/select/group/group.data-attrs.ts","../src/select/group-label/group-label.data-attrs.ts","../src/select/icon/icon.data-attrs.ts","../src/select/input/input.data-attrs.ts","../src/select/list/list.data-attrs.ts","../src/select/popup/popup.data-attrs.ts","../src/select/scroll-arrow/scroll-arrow.data-attrs.ts","../src/select/separator/separator.data-attrs.ts"],"sourcesContent":["// Combobox\n\n// Adapters for async menus\nexport * from './adapters/index.js'\nexport * from './combobox/index.js'\n// Context Menu\nexport * from './context-menu/index.js'\n// Dropdown Menu\nexport * from './dropdown-menu/index.js'\n// Select\nexport * from './select/index.js'\n","'use client'\n\nimport type * as React from 'react'\nimport type {\n AsyncLoaderResult,\n LoaderComponentProps,\n NodeDef,\n QueryDependentLoaderConfig,\n StaticLoaderConfig,\n} from '../internal/popup-menu/deep-search/types.js'\n\n// ============================================================================\n// TanStack Query Adapter\n// ============================================================================\n\n/**\n * TanStack Query result shape (subset of UseQueryResult).\n * This allows the adapter to work without requiring @tanstack/react-query as a dependency.\n */\nexport interface TanStackQueryResult<TData, TError = Error> {\n data: TData | undefined\n error: TError | null\n isLoading: boolean\n isError: boolean\n isFetching?: boolean\n refetch: () => void\n}\n\n/**\n * Converts a TanStack Query result to an AsyncLoaderResult.\n * Use this to wrap your useQuery hook result.\n *\n * @example\n * ```tsx\n * function MyLoader({ query, children }) {\n * const result = useQuery({\n * queryKey: ['items', query],\n * queryFn: () => fetchItems(query),\n * })\n * return children(toAsyncLoaderResult(result))\n * }\n * ```\n */\nexport function toAsyncLoaderResult<T>(\n result: TanStackQueryResult<T>,\n): AsyncLoaderResult<T> {\n return {\n data: result.data,\n error: result.error,\n isLoading: result.isLoading || (result.isFetching ?? false),\n isError: result.isError,\n refetch: result.refetch,\n }\n}\n\n/**\n * Props for creating a static loader component.\n */\nexport interface CreateStaticLoaderProps {\n /**\n * Hook that returns a TanStack Query result.\n * This hook will be called inside the loader component.\n */\n useQuery: () => TanStackQueryResult<NodeDef[]>\n}\n\n/**\n * Creates a static loader configuration for use with async menus.\n * The hook is called inside a component, so it follows React's rules of hooks.\n *\n * @example\n * ```tsx\n * const recentFilesLoader = createStaticLoader({\n * useQuery: () => useQuery({\n * queryKey: ['recent-files'],\n * queryFn: fetchRecentFiles,\n * staleTime: 5 * 60 * 1000,\n * }),\n * })\n *\n * // Use in submenu\n * {\n * kind: 'submenu',\n * value: 'Recent Files',\n * asyncNodes: {\n * ...recentFilesLoader,\n * loadStrategy: 'eager',\n * },\n * render: ...\n * }\n * ```\n */\nexport function createStaticLoader(\n props: CreateStaticLoaderProps,\n): StaticLoaderConfig {\n const { useQuery } = props\n\n const Loader: React.FC<LoaderComponentProps> = ({ children }) => {\n const result = useQuery()\n return <>{children(toAsyncLoaderResult(result))}</>\n }\n\n return {\n type: 'static',\n Loader,\n }\n}\n\n/**\n * Props for creating a query-dependent loader component.\n */\nexport interface CreateQueryLoaderProps {\n /**\n * Hook that returns a TanStack Query result based on the search query.\n * This hook will be called inside the loader component with the current query.\n */\n useQuery: (query: string) => TanStackQueryResult<NodeDef[]>\n /**\n * Minimum query length before fetching.\n * @default 1\n */\n minQueryLength?: number\n /**\n * Initial query to use when the loader becomes active.\n * Set to '' to fetch all items immediately when the submenu opens.\n * If undefined, waits for user to type before fetching.\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 * @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 * Creates a query-dependent loader configuration for use with async menus.\n * The loader will re-fetch when the search query changes.\n *\n * @example\n * ```tsx\n * const searchLoader = createQueryLoader({\n * useQuery: (query) => useQuery({\n * queryKey: ['search', query],\n * queryFn: () => searchItems(query),\n * enabled: query.length >= 2,\n * }),\n * minQueryLength: 2,\n * })\n *\n * // Use in submenu\n * {\n * kind: 'submenu',\n * value: 'Search',\n * asyncNodes: {\n * ...searchLoader,\n * includeInDeepSearch: true,\n * },\n * render: ...\n * }\n * ```\n */\nexport function createQueryLoader(\n props: CreateQueryLoaderProps,\n): QueryDependentLoaderConfig {\n const {\n useQuery,\n minQueryLength = 1,\n initialQuery,\n loadStrategy,\n belowMinBehavior = 'empty',\n placeholderNodes,\n } = props\n\n const Loader: React.FC<LoaderComponentProps> = ({ query, children }) => {\n const result = useQuery(query)\n return <>{children(toAsyncLoaderResult(result))}</>\n }\n\n return {\n type: 'query',\n Loader,\n minQueryLength,\n initialQuery,\n loadStrategy,\n belowMinBehavior,\n placeholderNodes,\n }\n}\n\n/**\n * Creates a loader component that wraps a TanStack Query hook.\n * This is a lower-level utility for custom loader implementations.\n *\n * @example\n * ```tsx\n * const MyLoader = createLoaderComponent((query) =>\n * useQuery({\n * queryKey: ['items', query],\n * queryFn: () => fetchItems(query),\n * })\n * )\n * ```\n */\nexport function createLoaderComponent(\n useQueryFn: (query: string) => TanStackQueryResult<NodeDef[]>,\n): React.FC<LoaderComponentProps> {\n return function TanStackLoader({ query, children }) {\n const result = useQueryFn(query)\n return <>{children(toAsyncLoaderResult(result))}</>\n }\n}\n","'use client'\n\nimport * as React from 'react'\nimport type {\n AsyncLoaderResult,\n LoaderComponentProps,\n NodeDef,\n QueryDependentLoaderConfig,\n StaticLoaderConfig,\n} from '../internal/popup-menu/deep-search/types.js'\n\n// ============================================================================\n// Vanilla Async Adapter (no external dependencies)\n// ============================================================================\n\n/**\n * Internal hook for managing async state with plain promises.\n * Use this when you don't have TanStack Query or SWR.\n */\nfunction useAsyncState<T>(\n fetcher: () => Promise<T>,\n options?: { enabled?: boolean },\n): AsyncLoaderResult<T> {\n const { enabled = true } = options ?? {}\n const [state, setState] = React.useState<AsyncLoaderResult<T>>({\n data: undefined,\n error: null,\n isLoading: enabled,\n isError: false,\n })\n\n const fetcherRef = React.useRef(fetcher)\n fetcherRef.current = fetcher\n\n const refetch = React.useCallback(() => {\n setState((s) => ({ ...s, isLoading: true, error: null, isError: false }))\n fetcherRef\n .current()\n .then((data) => {\n setState({ data, error: null, isLoading: false, isError: false })\n })\n .catch((error) => {\n setState((s) => ({\n ...s,\n error: error instanceof Error ? error : new Error(String(error)),\n isLoading: false,\n isError: true,\n }))\n })\n }, [])\n\n React.useEffect(() => {\n if (enabled) {\n refetch()\n }\n }, [enabled, refetch])\n\n return React.useMemo(() => ({ ...state, refetch }), [state, refetch])\n}\n\n/**\n * Props for creating a static loader with vanilla fetch.\n */\nexport interface CreateVanillaStaticLoaderProps {\n /**\n * Async function that fetches the menu items.\n */\n fetcher: () => Promise<NodeDef[]>\n}\n\n/**\n * Creates a static loader configuration using plain fetch/promises.\n * No external data library required.\n *\n * @example\n * ```tsx\n * const recentFilesLoader = createVanillaStaticLoader({\n * fetcher: async () => {\n * const res = await fetch('/api/recent-files')\n * const data = await res.json()\n * return data.map(file => ({\n * kind: 'item',\n * value: file.name,\n * render: ...\n * }))\n * },\n * })\n * ```\n */\nexport function createVanillaStaticLoader(\n props: CreateVanillaStaticLoaderProps,\n): StaticLoaderConfig {\n const { fetcher } = props\n\n const Loader: React.FC<LoaderComponentProps> = ({ children }) => {\n const result = useAsyncState(fetcher)\n return <>{children(result)}</>\n }\n\n return {\n type: 'static',\n Loader,\n }\n}\n\n/**\n * Props for creating a query-dependent loader with vanilla fetch.\n */\nexport interface CreateVanillaQueryLoaderProps {\n /**\n * Async function that fetches menu items based on the search query.\n */\n fetcher: (query: string) => Promise<NodeDef[]>\n /**\n * Minimum query length before fetching.\n * @default 1\n */\n minQueryLength?: number\n /**\n * Initial query to pre-fetch on menu open.\n */\n initialQuery?: string\n /**\n * What to show when query is below minQueryLength.\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 * Creates a query-dependent loader configuration using plain fetch/promises.\n * No external data library required.\n *\n * @example\n * ```tsx\n * const searchLoader = createVanillaQueryLoader({\n * fetcher: async (query) => {\n * const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`)\n * const data = await res.json()\n * return data.map(item => ({\n * kind: 'item',\n * value: item.name,\n * render: ...\n * }))\n * },\n * minQueryLength: 2,\n * })\n * ```\n */\nexport function createVanillaQueryLoader(\n props: CreateVanillaQueryLoaderProps,\n): QueryDependentLoaderConfig {\n const {\n fetcher,\n minQueryLength = 1,\n initialQuery,\n belowMinBehavior = 'empty',\n placeholderNodes,\n } = props\n\n const Loader: React.FC<LoaderComponentProps> = ({ query, children }) => {\n const enabled = query.length >= minQueryLength\n const result = useAsyncState(() => fetcher(query), { enabled })\n return <>{children(result)}</>\n }\n\n return {\n type: 'query',\n Loader,\n minQueryLength,\n initialQuery,\n belowMinBehavior,\n placeholderNodes,\n }\n}\n","// ============================================================================\n// Combobox Parts\n// ============================================================================\n// Re-exports shared components from internal/popup-menu with Combobox-specific\n// Root, Input, Item, ItemLabel, and ItemIndicator components.\n\n// Re-export VirtualItem type from internal/listbox\nexport type { VirtualItem } from '../internal/listbox/index.js'\n\n// Re-export shared components from internal/popup-menu\nexport {\n PopupMenuArrow as Arrow,\n PopupMenuBackdrop as Backdrop,\n PopupMenuEmpty as Empty,\n // Structure\n PopupMenuGroup as Group,\n PopupMenuGroupLabel as GroupLabel,\n // Icon\n PopupMenuIcon as Icon,\n PopupMenuList as List,\n PopupMenuPopup as Popup,\n // Positioning & Container\n PopupMenuPortal as Portal,\n // Scroll indicators\n PopupMenuScrollDownArrow as ScrollDownArrow,\n PopupMenuScrollUpArrow as ScrollUpArrow,\n PopupMenuSeparator as Separator,\n} from '../internal/popup-menu/index.js'\nexport { ComboboxClear as Clear } from './clear/clear.js'\nexport { useComboboxPositionerContext } from './contexts/combobox-positioner-context.js'\nexport { ComboboxInput as Input } from './input/input.js'\nexport { ComboboxInputWrapper as InputWrapper } from './input-wrapper/input-wrapper.js'\nexport { ComboboxItem as Item } from './item/item.js'\nexport { ComboboxItemIndicator as ItemIndicator } from './item-indicator/item-indicator.js'\nexport { ComboboxItemLabel as ItemLabel } from './item-label/item-label.js'\nexport { ComboboxPositioner as Positioner } from './positioner/positioner.js'\n// Combobox-specific components\nexport { ComboboxRoot as Root } from './root/root.js'\nexport { ComboboxSurface as Surface } from './surface/surface.js'\n","'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 /** 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\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 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 [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 clearAimGuard = React.useCallback(() => {\n if (guardTimerRef.current) {\n window.clearTimeout(guardTimerRef.current)\n guardTimerRef.current = null\n }\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 activateAimGuard = React.useCallback(\n (\n triggerId: string,\n depth: number,\n submenuSurfaceId: string,\n timeoutMs = 450,\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) window.clearTimeout(guardTimerRef.current)\n guardTimerRef.current = window.setTimeout(() => {\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 guardTimerRef.current = null\n }, timeoutMs) as unknown as number\n },\n [],\n )\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'\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): AnchorSide {\n if (tRect) {\n const tx = (tRect.left + tRect.right) / 2\n const dL = Math.abs(tx - rect.left)\n const dR = Math.abs(tx - rect.right)\n return dL <= dR ? 'left' : 'right'\n }\n return mx < rect.left ? 'left' : 'right'\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 const edgeX = anchor === 'right' ? rect.left : rect.right\n const edgeCy = (rect.top + rect.bottom) / 2\n dx = edgeX - tx\n dy = edgeCy - ty\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 if (Math.abs(dx) < 0.01) return false\n if (anchor === 'left' && dx <= 0) return false\n if (anchor === 'right' && dx >= 0) return false\n const edgeX = anchor === 'left' ? rect.left : rect.right\n const t = (edgeX - exitX) / dx\n if (t <= 0) return false\n const yAtEdge = exitY + t * dy\n const baseBand = triggerRect ? triggerRect.height * 0.75 : 28\n const extra = Math.max(12, Math.min(36, baseBand))\n const top = rect.top - extra * 0.25\n const bottom = rect.bottom + extra * 0.25\n return yAtEdge >= top && yAtEdge <= bottom\n}\n","import * as React from 'react'\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<[number, number][]>([])\n\n React.useEffect(() => {\n const onMove = (e: PointerEvent) => {\n const a = trailRef.current\n a.push([e.clientX, e.clientY])\n if (a.length > n) a.shift()\n }\n window.addEventListener('pointermove', onMove, { passive: true })\n return () => window.removeEventListener('pointermove', onMove)\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\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}\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 } = params\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) {\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])\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 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],\n )\n\n // Memoize virtualization config\n const virtualization = React.useMemo(() => {\n if (!virtualized) return undefined\n return {\n virtualized: true as const,\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 }\n}\n","// ============================================================================\n// Event Reason Constants\n// ============================================================================\n// Centralized reason constants for all UI event handlers.\n// These provide type-safe reasons for WHY a state change occurred.\n\n// Trigger interactions\nexport const triggerPress = 'trigger-press' as const\nexport const triggerHover = 'trigger-hover' as const\nexport const triggerFocus = 'trigger-focus' as const\nexport const triggerContextMenu = 'trigger-context-menu' as const\n\n// Dismissal reasons\nexport const escapeKey = 'escape-key' as const\nexport const outsidePress = 'outside-press' as const\nexport const focusOut = 'focus-out' as const\n\n// Item interactions\nexport const itemPress = 'item-press' as const\nexport const itemKeyboardSelect = 'item-keyboard-select' as const\nexport const closePress = 'close-press' as const\n\n// Input interactions (Combobox)\nexport const inputChange = 'input-change' as const\nexport const inputClear = 'input-clear' as const\nexport const clearPress = 'clear-press' as const\n\n// Navigation\nexport const listNavigation = 'list-navigation' as const\n\n// Submenu/menu management\nexport const submenuTrigger = 'submenu-trigger' as const\nexport const siblingOpen = 'sibling-open' as const\n\n// Highlight changes\nexport const pointer = 'pointer' as const\nexport const keyboard = 'keyboard' as const\nexport const auto = 'auto' as const\n\n// Programmatic/other\nexport const imperativeAction = 'imperative-action' as const\nexport const none = 'none' as const\n","import { REASONS } from './reasons.js'\n\n// ============================================================================\n// Reason to Native Event Type Mapping\n// ============================================================================\n\n/**\n * Maps event reason strings to their corresponding native DOM event types.\n * This provides type-safe access to the native event based on the reason.\n */\ninterface ReasonToEventMap {\n [REASONS.none]: Event\n\n // Trigger interactions\n [REASONS.triggerPress]: MouseEvent | PointerEvent | TouchEvent | KeyboardEvent\n [REASONS.triggerHover]: MouseEvent | PointerEvent\n [REASONS.triggerFocus]: FocusEvent\n [REASONS.triggerContextMenu]: MouseEvent\n\n // Dismissal reasons\n [REASONS.escapeKey]: KeyboardEvent\n [REASONS.outsidePress]: MouseEvent | PointerEvent | TouchEvent\n [REASONS.focusOut]: FocusEvent | KeyboardEvent\n\n // Item interactions\n [REASONS.itemPress]: MouseEvent | PointerEvent | KeyboardEvent\n [REASONS.itemKeyboardSelect]: KeyboardEvent\n [REASONS.closePress]: MouseEvent | PointerEvent | KeyboardEvent\n\n // Input interactions\n [REASONS.inputChange]: InputEvent | Event\n [REASONS.inputClear]: InputEvent | FocusEvent | Event\n [REASONS.clearPress]: MouseEvent | PointerEvent | KeyboardEvent\n\n // Navigation\n [REASONS.listNavigation]: KeyboardEvent\n\n // Submenu/menu management\n [REASONS.submenuTrigger]: MouseEvent | PointerEvent | KeyboardEvent\n [REASONS.siblingOpen]: Event\n\n // Highlight changes\n [REASONS.pointer]: MouseEvent | PointerEvent\n [REASONS.keyboard]: KeyboardEvent\n\n // Programmatic\n [REASONS.imperativeAction]: Event\n}\n\n/**\n * Maps a reason string to the corresponding native event type.\n * Falls back to `Event` for unknown reasons.\n */\nexport type ReasonToEvent<Reason extends string> =\n Reason extends keyof ReasonToEventMap ? ReasonToEventMap[Reason] : Event\n\n// ============================================================================\n// Change Event Details\n// ============================================================================\n\n/**\n * Details object passed to change event handlers (onOpenChange, onValueChange, etc.)\n *\n * @template Reason - The union of allowed reason strings for this event\n * @template CustomProperties - Additional component-specific properties\n */\nexport interface ChangeEventDetails<\n Reason extends string,\n CustomProperties extends object = {},\n> {\n /**\n * The reason why this state change occurred.\n * Use this to conditionally handle different scenarios.\n *\n * @example\n * ```tsx\n * onOpenChange={(open, details) => {\n * if (details.reason === 'escape-key') {\n * // Handle escape key differently\n * }\n * }}\n * ```\n */\n reason: Reason\n\n /**\n * The native DOM event that triggered this change.\n * May be a synthetic event in some cases.\n */\n event: ReasonToEvent<Reason>\n\n /**\n * Cancels the state change.\n * When called, the component's internal state will not update.\n *\n * @example\n * ```tsx\n * onOpenChange={(open, details) => {\n * if (!open && details.reason === 'outside-press') {\n * details.cancel() // Prevent closing on outside press\n * }\n * }}\n * ```\n */\n cancel: () => void\n\n /**\n * Allows the native event to propagate.\n * By default, some events (like Escape key) stop propagation\n * to prevent parent popups from closing simultaneously.\n */\n allowPropagation: () => void\n\n /**\n * Whether `cancel()` has been called.\n */\n readonly isCanceled: boolean\n\n /**\n * Whether `allowPropagation()` has been called.\n */\n readonly isPropagationAllowed: boolean\n\n /**\n * The element that triggered this event, if applicable.\n */\n trigger: Element | undefined\n}\n\n/**\n * Creates a change event details object.\n *\n * @param reason - The reason for the state change\n * @param event - The native DOM event (optional)\n * @param trigger - The element that triggered the event (optional)\n * @param customProperties - Additional component-specific properties (optional)\n */\nexport function createChangeEventDetails<\n Reason extends string,\n CustomProperties extends object = {},\n>(\n reason: Reason,\n event?: ReasonToEvent<Reason> | Event,\n trigger?: Element,\n customProperties?: CustomProperties,\n): ChangeEventDetails<Reason, CustomProperties> {\n let canceled = false\n let propagationAllowed = false\n\n const details: ChangeEventDetails<Reason, CustomProperties> = {\n reason,\n event: (event ?? new Event('ui-event')) as ReasonToEvent<Reason>,\n cancel() {\n canceled = true\n },\n allowPropagation() {\n propagationAllowed = true\n },\n get isCanceled() {\n return canceled\n },\n get isPropagationAllowed() {\n return propagationAllowed\n },\n trigger,\n ...(customProperties as CustomProperties),\n }\n\n return details\n}\n\n// ============================================================================\n// Generic Event Details (for non-change events)\n// ============================================================================\n\n/**\n * Details object for generic events that don't support cancellation.\n * Used for events like onHighlightChange where cancellation doesn't make sense.\n *\n * @template Reason - The union of allowed reason strings for this event\n * @template CustomProperties - Additional component-specific properties\n */\nexport interface GenericEventDetails<\n Reason extends string,\n CustomProperties extends object = {},\n> {\n /**\n * The reason why this event occurred.\n */\n reason: Reason\n\n /**\n * The native DOM event that triggered this event.\n */\n event: ReasonToEvent<Reason>\n}\n\n/**\n * Creates a generic event details object (without cancel/propagation methods).\n */\nexport function createGenericEventDetails<\n Reason extends string,\n CustomProperties extends object = {},\n>(\n reason: Reason,\n event?: ReasonToEvent<Reason> | Event,\n customProperties?: CustomProperties,\n): GenericEventDetails<Reason, CustomProperties> {\n return {\n reason,\n event: (event ?? new Event('ui-event')) as ReasonToEvent<Reason>,\n ...(customProperties as CustomProperties),\n }\n}\n","'use client'\n\nimport * as React from 'react'\n\n// ============================================================================\n// Group Context (for items to know their parent group)\n// ============================================================================\n\nexport interface GroupContextValue {\n groupId: string\n}\n\nconst GroupContext = React.createContext<GroupContextValue | null>(null)\n\nexport function useGroupContext(): GroupContextValue | null {\n return React.useContext(GroupContext)\n}\n\nexport { GroupContext }\n","'use client'\n\nimport * as React from 'react'\n\n// ============================================================================\n// Item Context (for child components like indicators to access item state)\n// ============================================================================\n\nexport interface ItemContextValue {\n /** Unique ID for this item (for DOM id attribute) */\n id: string\n /** Whether the item is highlighted */\n highlighted: boolean\n /** Whether the item is disabled */\n disabled: boolean\n /** Keyboard shortcut for this item */\n shortcut?: string\n}\n\nconst ItemContext = React.createContext<ItemContextValue | null>(null)\n\nexport function useItemContext(): ItemContextValue {\n const context = React.useContext(ItemContext)\n if (!context) {\n throw new Error('Item child components must be used within an Item')\n }\n return context\n}\n\nexport function useMaybeItemContext(): ItemContextValue | null {\n return React.useContext(ItemContext)\n}\n\nexport { ItemContext }\n","'use client'\n\nimport * as React from 'react'\nimport type { HighlightChangeEventDetails } from '../../popup-menu/events.js'\nimport type { ListboxStore, VirtualItem } from '../store/ListboxStore.js'\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\nexport interface ListboxContextValue {\n /** The Listbox store instance */\n store: ListboxStore\n /** Nesting depth: 0 = root menu, 1+ = submenu */\n depth: number\n /** Close the entire menu tree (deepest submenu to root, sequentially) */\n closeAll: () => 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\nconst ListboxContext = React.createContext<ListboxContextValue | null>(null)\n\nexport function useListboxContext(): ListboxContextValue {\n const context = React.useContext(ListboxContext)\n if (!context) {\n throw new Error('Listbox components must be used within a Listbox provider')\n }\n return context\n}\n\nexport function useMaybeListboxContext(): ListboxContextValue | null {\n return React.useContext(ListboxContext)\n}\n\nexport { ListboxContext }\n","'use client'\n\nimport * as React from 'react'\n\n/**\n * Context value for row width measurement.\n * Provided by List when `measureRowWidth` is enabled.\n */\nexport interface RowWidthContextValue {\n /**\n * Queue a row element for width measurement.\n * Call this when a row mounts or becomes visible.\n *\n * @param element - The DOM element to measure\n * @param id - Unique identifier for this row (used to avoid re-measuring)\n */\n queueMeasurement: (element: HTMLElement, id: string) => void\n}\n\n/**\n * Context for row width measurement.\n * Items use this to self-register for measurement.\n */\nexport const RowWidthContext = React.createContext<RowWidthContextValue | null>(\n null,\n)\n\nif (process.env.NODE_ENV !== 'production') {\n RowWidthContext.displayName = 'RowWidthContext'\n}\n\n/**\n * Hook to get the row width context.\n * Throws an error if used outside of a List with `measureRowWidth` enabled.\n */\nexport function useRowWidthContext(): RowWidthContextValue {\n const context = React.useContext(RowWidthContext)\n if (!context) {\n throw new Error(\n 'useRowWidthContext must be used within a List with measureRowWidth enabled',\n )\n }\n return context\n}\n\n/**\n * Hook to optionally get the row width context.\n * Returns null if not within a List with `measureRowWidth` enabled.\n * This is the preferred hook for items that should work both with and without measurement.\n */\nexport function useMaybeRowWidthContext(): RowWidthContextValue | null {\n return React.useContext(RowWidthContext)\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ListboxStore } from '../store/ListboxStore.js'\n\n// Re-export types from the store for convenience\nexport type {\n FilterFn,\n ItemRegistration,\n} from '../store/ListboxStore.js'\n\n// ============================================================================\n// Surface Context\n// ============================================================================\n\nexport interface SurfaceContextValue {\n /** The Listbox store instance */\n store: ListboxStore\n /** Unique identifier for this surface */\n surfaceId: string\n}\n\nconst SurfaceContext = React.createContext<SurfaceContextValue | null>(null)\n\nexport function useSurfaceContext(): SurfaceContextValue {\n const context = React.useContext(SurfaceContext)\n if (!context) {\n throw new Error('Listbox components must be used within a Surface provider')\n }\n return context\n}\n\nexport function useMaybeSurfaceContext(): SurfaceContextValue | null {\n return React.useContext(SurfaceContext)\n}\n\nexport { SurfaceContext }\n","'use client'\n\nimport * as React from 'react'\nimport { useGroupContext } from '../contexts/group-context.js'\nimport type { ItemContextValue } from '../contexts/item-context.js'\nimport { useListboxContext } from '../contexts/listbox-context.js'\nimport { useMaybeRowWidthContext } from '../contexts/row-width-context.js'\nimport { useSurfaceContext } from '../contexts/surface-context.js'\nimport { normalizeValue } from '../utils/normalize.js'\n\n/**\n * Aim guard refs for submenu navigation.\n * Optional - only needed for popup menus with submenus.\n */\nexport interface AimGuardRefs {\n /** Whether aim guard is currently active */\n aimGuardActiveRef: React.RefObject<boolean>\n /** The depth at which aim guard is active (null when not guarding) */\n guardedDepthRef: React.RefObject<number | null>\n}\n\n/**\n * Parameters for the useListboxItem hook.\n */\nexport interface UseListboxItemParams {\n /**\n * Explicit unique identifier for this item in the store.\n * Takes highest priority for item registration.\n * Used by data-first APIs to ensure consistent IDs.\n */\n id?: string\n\n /**\n * Unique value for this item used as identifier and for filtering.\n * If not provided, will be inferred from textContent.\n * Used for registration when `id` is not provided.\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 * 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 * Whether this item is a submenu trigger (for store registration).\n * @default false\n */\n isSubmenuTrigger?: boolean\n\n /**\n * Callback when this item is selected (via click or Enter key).\n * For simple items, pass this directly. For checkbox/radio items,\n * use registerSelect() to register a dynamic handler.\n */\n onSelect?: () => void\n\n /**\n * Whether selecting this item should close the menu.\n * @default true\n */\n closeOnClick?: boolean\n\n /**\n * Callback invoked after selection occurs (via click).\n * Called with the item's ID. The consumer handles any\n * post-selection behavior like closing menus.\n */\n onAfterSelect?: (itemId: string) => void\n\n /**\n * Children (used for text content inference when value is not provided).\n */\n children?: React.ReactNode\n\n /**\n * Optional aim guard refs for popup menu navigation.\n * When provided, pointer move events will respect the aim guard.\n */\n aimGuard?: AimGuardRefs\n}\n\n/**\n * Return value from the useListboxItem hook.\n */\nexport interface UseListboxItemReturn {\n /** Unique ID for this item (DOM ID for aria-activedescendant) */\n id: string\n\n /**\n * Store identifier for this item.\n * Use this when calling store methods like setHighlightedId, registerSubmenuOpen, etc.\n * This is the `value` prop (or inferred from textContent).\n */\n storeId: string\n\n /** Ref to attach to the item element */\n ref: React.RefObject<HTMLDivElement | null>\n\n /** Whether item is currently highlighted */\n isHighlighted: boolean\n\n /** Whether item should be rendered (passes filter) */\n isVisible: boolean\n\n /** Context value to provide to children via ItemContext.Provider */\n contextValue: ItemContextValue\n\n /**\n * Event handlers to spread on the element.\n * These handle click, pointer move, and pointer down events.\n */\n handlers: {\n onClick: React.MouseEventHandler<HTMLDivElement>\n onPointerMove: React.PointerEventHandler<HTMLDivElement>\n onPointerDown: React.PointerEventHandler<HTMLDivElement>\n }\n\n /**\n * Register a custom onSelect handler.\n * This is useful for checkbox/radio items where the select behavior\n * needs to be customized (e.g., toggle checked state).\n * Returns an unregister function.\n */\n registerSelect: (handler: (() => void) | undefined) => () => void\n}\n\n/**\n * Hook that provides all shared logic for navigatable/highlightable listbox items.\n *\n * This hook handles:\n * - Item registration with the listbox store\n * - Highlight state management (keyboard and pointer)\n * - Filter/search visibility\n * - Scroll into view on keyboard navigation\n * - Click, pointer move, and pointer down event handlers\n * - Optional aim guard integration (for submenu navigation)\n *\n * @example\n * ```tsx\n * function CustomItem(props) {\n * const item = useListboxItem({\n * value: props.value,\n * disabled: props.disabled,\n * onSelect: props.onSelect,\n * })\n *\n * if (!item.isVisible) return null\n *\n * return (\n * <ItemContext.Provider value={item.contextValue}>\n * <div\n * ref={item.ref}\n * {...item.handlers}\n * data-highlighted={item.isHighlighted || undefined}\n * >\n * {props.children}\n * </div>\n * </ItemContext.Provider>\n * )\n * }\n * ```\n */\nexport function useListboxItem(\n params: UseListboxItemParams,\n): UseListboxItemReturn {\n const {\n id: idProp,\n value: valueProp,\n keywords,\n disabled = false,\n forceMount = false,\n shortcut,\n isSubmenuTrigger = false,\n onSelect,\n closeOnClick = true,\n onAfterSelect,\n children,\n aimGuard,\n } = params\n\n const { store } = useSurfaceContext()\n const groupContext = useGroupContext()\n const { depth } = useListboxContext()\n\n const ref = React.useRef<HTMLDivElement>(null)\n\n // Infer value from textContent if not provided\n const [inferredValue, setInferredValue] = React.useState<string>('')\n\n React.useLayoutEffect(() => {\n if (idProp === undefined && valueProp === undefined && ref.current) {\n const textContent = ref.current.textContent?.trim() ?? ''\n setInferredValue(textContent)\n }\n }, [idProp, valueProp, children])\n\n // Registration ID priority: id prop > value prop > textContent inference\n // This ensures data-first APIs can provide explicit IDs that match their internal tracking\n // Note: valueProp is normalized (trimmed) to match cmdk's behavior\n const registrationId = idProp ?? (normalizeValue(valueProp) || inferredValue)\n\n // Generate a stable ID for DOM id attribute (aria-activedescendant, etc.)\n // When id prop is provided (data-first APIs), use it directly for DOM ID\n // This ensures aria-activedescendant works correctly with composite IDs\n const generatedDomId = React.useId()\n const domId = idProp ?? `item-${generatedDomId}`\n\n // Stabilize keywords to prevent infinite loops when passed as inline arrays\n // We use JSON.stringify to compare by value rather than reference\n // Keywords are also normalized (trimmed) to match cmdk's behavior\n const normalizedKeywords = keywords\n ?.map((k) => normalizeValue(k))\n .filter(Boolean)\n const keywordsKey = normalizedKeywords\n ? JSON.stringify(normalizedKeywords)\n : undefined\n\n // Register item with store (using registrationId as the unique identifier)\n React.useEffect(() => {\n if (!registrationId && !forceMount) return\n\n const unregister = store.registerItem(registrationId, {\n value: registrationId,\n keywords: normalizedKeywords,\n groupId: groupContext?.groupId,\n disabled,\n isSubmenuTrigger,\n shortcut,\n closeOnClick,\n })\n\n return unregister\n // eslint-disable-next-line react-hooks/exhaustive-deps -- keywordsKey is a stable representation of keywords\n }, [\n registrationId,\n keywordsKey,\n groupContext?.groupId,\n disabled,\n isSubmenuTrigger,\n shortcut,\n closeOnClick,\n store,\n forceMount,\n ])\n\n // Register DOM ref with store for scroll behavior\n React.useEffect(() => {\n if (!registrationId) return\n return store.registerItemRef(registrationId, ref)\n }, [registrationId, store])\n\n // Register for row width measurement if enabled\n const rowWidthContext = useMaybeRowWidthContext()\n\n React.useLayoutEffect(() => {\n if (rowWidthContext && ref.current && registrationId) {\n rowWidthContext.queueMeasurement(ref.current, registrationId)\n }\n }, [rowWidthContext, registrationId])\n\n // Register onSelect handler if provided directly\n React.useEffect(() => {\n if (!onSelect || !registrationId) return\n return store.registerItemSelect(registrationId, onSelect)\n }, [registrationId, onSelect, store])\n\n // Use selectors to get derived state (using registrationId as identifier)\n const search = store.useState('search')\n const isHighlighted = store.useState('isHighlighted', registrationId)\n const score = store.useState('getItemScore', registrationId)\n\n // Check if filtering is disabled (consumer handles filtering externally)\n const filterDisabled = store.isFilterDisabled()\n\n // Determine visibility based on filter score\n // When filterDisabled, consumer handles filtering so all items are visible\n const hasSearch = search.length > 0\n const isVisible = forceMount || filterDisabled || !hasSearch || score > 0\n\n // Note: Scroll behavior is now handled by the store's setHighlightedId method.\n // It uses the registered DOM refs to call scrollIntoView when the element exists,\n // or falls back to onHighlightChange for virtualizer sync.\n\n // Event handlers\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (event.defaultPrevented) return\n if (disabled) return\n if (!registrationId) return\n\n event.preventDefault()\n\n // Call the registered onSelect handler via store\n const registeredHandler = store.context.itemSelects.get(registrationId)\n registeredHandler?.()\n\n // Notify consumer that selection occurred (for closing menus, etc.)\n onAfterSelect?.(registrationId)\n },\n [disabled, store, registrationId, onAfterSelect],\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault()\n },\n [],\n )\n\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n if (event.defaultPrevented) return\n if (disabled) return\n if (!registrationId) return\n\n // Don't highlight if aim guard is active at this depth (user is moving toward submenu)\n // Only block highlighting in the same menu where the trigger is located\n if (aimGuard) {\n const { aimGuardActiveRef, guardedDepthRef } = aimGuard\n if (aimGuardActiveRef.current && guardedDepthRef.current === depth)\n return\n }\n\n // Check if pointer has actually moved - prevents phantom highlights when\n // content shifts under a stationary pointer (e.g., search results changing)\n if (!store.shouldAllowPointerHighlight(event.clientX, event.clientY)) {\n return\n }\n\n // Highlight on hover (using registrationId as identifier)\n store.setHighlightedId(registrationId)\n },\n [disabled, aimGuard, depth, store, registrationId],\n )\n\n // Context value for child components\n const contextValue: ItemContextValue = React.useMemo(\n () => ({\n id: domId,\n highlighted: isHighlighted,\n disabled,\n shortcut,\n }),\n [domId, isHighlighted, disabled, shortcut],\n )\n\n // Register a custom select handler (for checkbox/radio items)\n const registerSelect = React.useCallback(\n (handler: (() => void) | undefined) => {\n if (!registrationId) return () => {}\n return store.registerItemSelect(registrationId, handler)\n },\n [store, registrationId],\n )\n\n const handlers = React.useMemo(\n () => ({\n onClick: handleClick,\n onPointerMove: handlePointerMove,\n onPointerDown: handlePointerDown,\n }),\n [handleClick, handlePointerMove, handlePointerDown],\n )\n\n return {\n id: domId,\n storeId: registrationId,\n ref,\n isHighlighted,\n isVisible,\n contextValue,\n handlers,\n registerSelect,\n }\n}\n","/**\n * Normalizes a value string for use in filtering and identification.\n * Trims leading/trailing whitespace to match cmdk's behavior.\n *\n * @param value - The value to normalize\n * @returns The trimmed value, or empty string if value is nullish\n */\nexport function normalizeValue(value: string | undefined | null): string {\n return value?.trim() ?? ''\n}\n\n/**\n * Converts a value string to a URL-safe slug for use in IDs.\n * - Trims whitespace\n * - Converts to lowercase\n * - Replaces spaces with hyphens\n * - Removes non-alphanumeric characters (except hyphens)\n * - Collapses multiple hyphens into one\n * - Removes leading/trailing hyphens\n *\n * @example\n * slugify(\"User Settings\") // \"user-settings\"\n * slugify(\" Hello World! \") // \"hello-world\"\n * slugify(\"Café & Co.\") // \"caf-co\"\n *\n * @param value - The value to slugify\n * @returns The slugified value, or empty string if value is nullish\n */\nexport function slugify(value: string | undefined | null): string {\n if (!value) return ''\n\n return (\n value\n .trim()\n .toLowerCase()\n // Replace spaces with hyphens\n .replace(/\\s+/g, '-')\n // Remove non-alphanumeric characters (except hyphens)\n .replace(/[^a-z0-9-]/g, '')\n // Collapse multiple hyphens into one\n .replace(/-+/g, '-')\n // Remove leading/trailing hyphens\n .replace(/^-|-$/g, '')\n )\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ListboxStore } from '../store/ListboxStore.js'\n\n/**\n * Focus owner interface for keyboard handling.\n * Optional - only needed for popup menus with multiple surfaces.\n */\nexport interface FocusOwnerInterface {\n /** Check if a surface is the current owner */\n useState: (selector: 'isOwner', surfaceId: string) => boolean\n /** Set the owner surface ID */\n setOwnerId: (id: string | null) => void\n}\n\n/**\n * Submenu context interface for keyboard handling.\n * Optional - only needed for popup menus with submenus.\n */\nexport interface SubmenuInterface {\n /** Close this submenu */\n setOpen: (open: boolean) => void\n /** Parent surface ID for focus transfer */\n parentSurfaceId: string\n /** Whether Escape closes the root menu or just this submenu */\n closeRootOnEsc?: boolean\n}\n\nexport interface UseListboxKeyboardParams {\n /** The Listbox store instance */\n store: ListboxStore\n /** Unique identifier for this surface */\n surfaceId: string\n /** Whether keyboard handling is enabled */\n enabled: boolean\n /** User's onKeyDown handler to compose with */\n onKeyDown?: React.KeyboardEventHandler\n /**\n * Callback when an item is selected via keyboard (Enter or shortcut).\n * Called with selection details. The consumer handles any\n * post-selection behavior like closing menus.\n */\n onSelect?: (details: { itemId: string | null; closeOnClick: boolean }) => void\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 // Optional popup-menu features\n\n /** The FocusOwner store for managing focus ownership (optional) */\n focusOwner?: FocusOwnerInterface\n /** Menu depth (0 for root, >0 for submenus) - defaults to 0 */\n depth?: number\n /** Submenu context for ArrowLeft navigation back to parent (optional) */\n submenuContext?: SubmenuInterface | null\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 /**\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 UseListboxKeyboardReturn {\n /** Keyboard event handler to attach to the element */\n handleKeyDown: React.KeyboardEventHandler\n}\n\n/**\n * Centralized keyboard navigation hook for listbox-like components.\n * Handles arrow navigation, vim bindings, submenu open/close, and selection.\n *\n * This hook can be used standalone (for simple listboxes like Select/Command)\n * or with focus owner and submenu support (for popup menus with nested menus).\n */\nexport function useListboxKeyboard(\n params: UseListboxKeyboardParams,\n): UseListboxKeyboardReturn {\n const {\n store,\n surfaceId,\n enabled,\n onKeyDown,\n onSelect,\n closeAll,\n focusOwner,\n depth = 0,\n submenuContext,\n enableTypeToSearch = false,\n skipFocusOwnerCheck = false,\n } = params\n\n // Subscribe to focus ownership if available\n const focusOwnerIsOwner = focusOwner?.useState('isOwner', surfaceId) ?? true\n // Skip this check for Combobox where input is outside Surface\n const isOwner = skipFocusOwnerCheck ? true : focusOwnerIsOwner\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n // Call user's handler first\n onKeyDown?.(event)\n\n if (event.defaultPrevented) return\n\n // Only handle keyboard if enabled and this surface owns focus\n if (!enabled) return\n if (!isOwner) return\n\n // Check for IME composition\n if (event.nativeEvent.isComposing || event.keyCode === 229) return\n\n // Type-to-search: detect printable characters when enabled\n // Note: Shortcuts take priority over type-to-search, so we check for shortcuts first\n if (enableTypeToSearch) {\n const hideUntilActive = store.context.hideUntilActive\n const inputActive = store.state.inputActive\n\n if (hideUntilActive && !inputActive) {\n const isPrintable =\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n\n if (isPrintable) {\n // Check if this key is a registered shortcut first\n const shortcutItemId = store.context.shortcuts.get(\n event.key.toLowerCase(),\n )\n if (shortcutItemId && store.selectByShortcut(event.key)) {\n event.preventDefault()\n const item = store.context.items.get(shortcutItemId)\n onSelect?.({\n itemId: shortcutItemId,\n closeOnClick: item?.closeOnClick ?? true,\n })\n return\n }\n\n // No shortcut match, trigger type-to-search\n event.preventDefault()\n store.setPendingSearch(event.key)\n store.setInputActive(true)\n return\n }\n }\n }\n\n switch (event.key) {\n case 'ArrowDown': {\n event.preventDefault()\n store.highlightNext()\n break\n }\n case 'ArrowUp': {\n event.preventDefault()\n store.highlightPrev()\n break\n }\n case 'n': {\n // Ctrl+N - next item (vim binding)\n if (event.ctrlKey) {\n event.preventDefault()\n store.highlightNext()\n }\n break\n }\n case 'p': {\n // Ctrl+P - previous item (vim binding)\n if (event.ctrlKey) {\n event.preventDefault()\n store.highlightPrev()\n }\n break\n }\n case 'ArrowRight': {\n // Open submenu if highlighted item is a submenu trigger\n // Note: Focus transfer is handled by SubmenuTrigger's registerSubmenuOpen callback\n if (store.isHighlightedSubmenuTrigger()) {\n event.preventDefault()\n store.openSubmenuForHighlighted()\n }\n break\n }\n case 'l': {\n // Ctrl+L - open submenu (vim binding)\n // Note: Focus transfer is handled by SubmenuTrigger's registerSubmenuOpen callback\n if (event.ctrlKey && store.isHighlightedSubmenuTrigger()) {\n event.preventDefault()\n store.openSubmenuForHighlighted()\n }\n break\n }\n case 'ArrowLeft': {\n // Close submenu and return to parent (only if in a submenu)\n if (depth > 0 && submenuContext && focusOwner) {\n event.preventDefault()\n submenuContext.setOpen(false)\n // Transfer focus back to parent surface\n focusOwner.setOwnerId(submenuContext.parentSurfaceId)\n }\n break\n }\n case 'h': {\n // Ctrl+H - close submenu (vim binding)\n if (event.ctrlKey && depth > 0 && submenuContext && focusOwner) {\n event.preventDefault()\n submenuContext.setOpen(false)\n // Transfer focus back to parent surface\n focusOwner.setOwnerId(submenuContext.parentSurfaceId)\n }\n break\n }\n case 'Enter': {\n event.preventDefault()\n const selectedId = store.state.highlightedId\n const item = store.getHighlightedItem()\n store.selectHighlighted()\n onSelect?.({\n itemId: selectedId,\n closeOnClick: item?.closeOnClick ?? true,\n })\n break\n }\n case 'Home': {\n // Highlight first item\n event.preventDefault()\n store.setHighlightedId(null)\n store.highlightNext()\n break\n }\n case 'End': {\n // Highlight last item\n event.preventDefault()\n store.setHighlightedId(null)\n store.highlightPrev()\n break\n }\n case 'Escape': {\n // Handle Escape based on depth and closeRootOnEsc setting\n if (depth === 0) {\n // Root menu: let parent component handle it normally\n // (closes the menu and returns focus to trigger)\n break\n }\n\n // In a submenu: always prevent default to avoid parent's focus restoration\n event.preventDefault()\n event.stopPropagation()\n\n if (submenuContext?.closeRootOnEsc !== false) {\n // closeRootOnEsc is true (default): close entire menu tree\n closeAll()\n } else {\n // closeRootOnEsc is false: close only this submenu\n submenuContext.setOpen(false)\n // Transfer focus back to parent surface\n if (focusOwner) {\n focusOwner.setOwnerId(submenuContext.parentSurfaceId)\n }\n }\n break\n }\n default: {\n // Handle single-character shortcuts (only when not typing in search input)\n // Shortcuts are disabled when there's an active search to avoid conflicts\n const hasActiveSearch = store.state.search.length > 0\n const isPrintable =\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n\n if (isPrintable && !hasActiveSearch) {\n const itemId = store.context.shortcuts.get(event.key.toLowerCase())\n if (itemId && store.selectByShortcut(event.key)) {\n event.preventDefault()\n const item = store.context.items.get(itemId)\n onSelect?.({\n itemId,\n closeOnClick: item?.closeOnClick ?? true,\n })\n }\n }\n break\n }\n }\n },\n [\n onKeyDown,\n enabled,\n isOwner,\n enableTypeToSearch,\n store,\n depth,\n submenuContext,\n focusOwner,\n onSelect,\n closeAll,\n ],\n )\n\n return { handleKeyDown }\n}\n","'use client'\n\nimport * as React from 'react'\n\n// Debug flag - set to true to enable console logging\nconst DEBUG_ROW_WIDTH = false\n\n// Debug flag - when true, keeps measurement styles applied (doesn't reset them)\n// This lets you visually inspect what elements look like during measurement\nconst DEBUG_FREEZE_MEASUREMENT = false\n\nfunction debugLog(...args: unknown[]) {\n if (DEBUG_ROW_WIDTH) {\n console.log('[useStickyRowWidth]', ...args)\n }\n}\n\nfunction px(n: number) {\n return `${Math.ceil(n)}px`\n}\n\ninterface MeasurementEntry {\n element: HTMLElement\n id: string\n}\n\nexport interface UseStickyRowWidthOptions {\n /**\n * Ref to the list container element.\n * Used to measure row widths and as a fallback target for the CSS variable.\n */\n listRef: React.RefObject<HTMLElement | null>\n /**\n * Optional ref to the element where `--row-width` CSS variable should be applied.\n * If not provided, uses the listRef element.\n * Useful for applying the variable to a parent Popup element.\n */\n targetRef?: React.RefObject<HTMLElement | null>\n /**\n * Optional maximum width cap in pixels.\n * The measured width will never exceed this value.\n */\n maxWidth?: number\n /**\n * Whether measurement is enabled.\n * @default true\n */\n enabled?: boolean\n}\n\nexport interface UseStickyRowWidthReturn {\n /**\n * Queue a row element for measurement.\n * The element's natural width will be measured and tracked.\n * Call this when a row mounts or becomes visible.\n */\n queueMeasurement: (element: HTMLElement, id: string) => void\n /**\n * Reset all measurements.\n * Call this when the menu closes to start fresh on next open.\n */\n resetMeasurements: () => void\n}\n\n/**\n * Hook that measures row widths and maintains a sticky maximum width.\n *\n * This is useful for virtualized lists where the popup width should adapt\n * to the content but never shrink as the user scrolls through items.\n *\n * The hook:\n * 1. Measures each row's natural width (using `max-content`)\n * 2. Tracks the maximum width seen across all rows\n * 3. Applies `--row-width` CSS variable to the list element\n * 4. Only grows the width, never shrinks (until reset)\n *\n * @example\n * ```tsx\n * const { queueMeasurement, resetMeasurements } = useStickyRowWidth({\n * listRef: myListRef,\n * maxWidth: 500,\n * })\n *\n * // Queue items for measurement\n * useLayoutEffect(() => {\n * if (itemRef.current) {\n * queueMeasurement(itemRef.current, itemId)\n * }\n * }, [itemId])\n *\n * // Reset on menu close\n * useEffect(() => {\n * if (!isOpen) {\n * resetMeasurements()\n * }\n * }, [isOpen])\n * ```\n */\nexport function useStickyRowWidth(\n options: UseStickyRowWidthOptions,\n): UseStickyRowWidthReturn {\n const { listRef, targetRef, maxWidth, enabled = true } = options\n\n // The element where CSS variable is applied (targetRef if provided, else listRef)\n const getTargetElement = React.useCallback(() => {\n return targetRef?.current ?? listRef.current\n }, [targetRef, listRef])\n\n // Track the maximum width seen so far\n const maxSeenRef = React.useRef(0)\n\n // RAF scheduler state\n const readQueue = React.useRef<MeasurementEntry[]>([])\n const writeQueue = React.useRef<Array<() => void>>([])\n const scheduled = React.useRef(false)\n const measuredIds = React.useRef<Set<string>>(new Set())\n\n /**\n * Apply the `--row-width` CSS variable to the target element.\n */\n const applyVar = React.useCallback(\n (width: number) => {\n const el = getTargetElement()\n if (!el) return\n\n // Apply hard cap if specified\n const capped = maxWidth !== undefined ? Math.min(width, maxWidth) : width\n\n debugLog('--row-width updated:', {\n rawWidth: width,\n cappedWidth: capped,\n cssValue: px(capped),\n maxWidthCap: maxWidth,\n targetElement:\n el.tagName +\n (el.className ? `.${el.className.split(' ').join('.')}` : ''),\n })\n\n el.style.setProperty('--row-width', px(capped))\n },\n [getTargetElement, maxWidth],\n )\n\n /**\n * RAF scheduler: batch reads, then batch writes.\n * This avoids layout thrashing by separating measurement from application.\n */\n const schedule = React.useCallback(() => {\n if (scheduled.current) return\n scheduled.current = true\n\n requestAnimationFrame(() => {\n // === READ PHASE: Measure all queued rows at once ===\n const measurements = readQueue.current\n let maxWidth = maxSeenRef.current\n let foundNewMax = false\n\n if (measurements.length > 0) {\n debugLog('Measuring batch of', measurements.length, 'rows')\n\n for (const { element, id } of measurements) {\n // Skip if already measured\n if (measuredIds.current.has(id)) continue\n\n // Skip if element is no longer in the DOM (unmounted before RAF fired)\n if (!element.isConnected) {\n debugLog('Row skipped (unmounted):', { id })\n continue\n }\n\n // Read natural width without interleaving writes\n const prevWidth = element.style.width\n const prevMaxWidth = element.style.maxWidth\n\n // Add data-measuring attribute so CSS can remove constraints on descendants\n element.setAttribute('data-measuring', '')\n\n // Temporarily remove max-width constraint to get true natural width\n element.style.maxWidth = 'none'\n element.style.width = 'max-content'\n\n const w = Math.max(element.scrollWidth, element.offsetWidth) + 1\n\n // Log computed styles to debug constraint issues\n const computed = getComputedStyle(element)\n debugLog('Row measurement details:', {\n id,\n measuredWidth: w,\n scrollWidth: element.scrollWidth,\n offsetWidth: element.offsetWidth,\n computedWidth: computed.width,\n computedMaxWidth: computed.maxWidth,\n inlineMaxWidth: prevMaxWidth,\n textContent: element.textContent?.slice(0, 50),\n })\n\n // Reset styles unless DEBUG_FREEZE_MEASUREMENT is enabled\n if (!DEBUG_FREEZE_MEASUREMENT) {\n element.style.width = prevWidth\n element.style.maxWidth = prevMaxWidth\n element.removeAttribute('data-measuring')\n }\n\n // Debug: if width is suspiciously small, log more info\n if (w <= 1) {\n const rect = element.getBoundingClientRect()\n const computed = getComputedStyle(element)\n debugLog('Row skipped (0-width, will retry):', {\n id,\n width: w,\n scrollWidth: element.scrollWidth,\n offsetWidth: element.offsetWidth,\n boundingRect: { width: rect.width, height: rect.height },\n display: computed.display,\n visibility: computed.visibility,\n innerHTML: element.innerHTML.slice(0, 100),\n isConnected: element.isConnected,\n parentElement: element.parentElement?.tagName,\n })\n // Don't mark as measured - element was likely unmounted/replaced\n // before we could measure it. It will be re-queued when it re-mounts.\n continue\n }\n\n debugLog('Row measured:', {\n id,\n width: w,\n currentMax: maxWidth,\n isNewMax: w > maxWidth,\n })\n\n if (w > maxWidth) {\n maxWidth = w\n foundNewMax = true\n }\n\n measuredIds.current.add(id)\n }\n\n readQueue.current = []\n }\n\n // === WRITE PHASE: Apply styles after all reads complete ===\n if (foundNewMax) {\n debugLog('New max width found:', {\n previousMax: maxSeenRef.current,\n newMax: maxWidth,\n totalMeasured: measuredIds.current.size,\n })\n maxSeenRef.current = maxWidth\n writeQueue.current.push(() => applyVar(maxWidth))\n }\n\n for (const write of writeQueue.current) {\n write()\n }\n writeQueue.current = []\n scheduled.current = false\n })\n }, [applyVar])\n\n /**\n * Queue a row element for measurement.\n */\n const queueMeasurement = React.useCallback(\n (element: HTMLElement, id: string) => {\n if (!enabled) {\n debugLog('queueMeasurement skipped (disabled):', id)\n return\n }\n\n // Skip if already measured\n if (measuredIds.current.has(id)) {\n debugLog('queueMeasurement skipped (already measured):', id)\n return\n }\n\n debugLog('queueMeasurement:', {\n id,\n queueSize: readQueue.current.length + 1,\n element: element.tagName,\n })\n\n // Add to read queue\n readQueue.current.push({ element, id })\n schedule()\n },\n [enabled, schedule],\n )\n\n /**\n * Reset all measurements.\n * This clears the tracked IDs and resets the max width.\n */\n const resetMeasurements = React.useCallback(() => {\n const prevMax = maxSeenRef.current\n const prevCount = measuredIds.current.size\n\n measuredIds.current.clear()\n maxSeenRef.current = 0\n\n // Clear the CSS variable\n const el = getTargetElement()\n if (el) {\n el.style.removeProperty('--row-width')\n }\n\n debugLog('Measurements reset:', {\n previousMaxWidth: prevMax,\n previousMeasuredCount: prevCount,\n targetElement: el?.tagName,\n })\n }, [getTargetElement])\n\n // Re-apply the CSS variable when the target element resizes (e.g., viewport changes)\n // Use useEffect (not useLayoutEffect) to avoid conflicts with React's commit phase\n React.useEffect(() => {\n if (!enabled) return\n\n const container = getTargetElement()\n if (!container) return\n\n // ResizeObserver may not be available in some environments (SSR, older browsers, tests)\n if (typeof ResizeObserver === 'undefined') return\n\n let rafId: number | null = null\n\n const ro = new ResizeObserver((entries) => {\n // Defer to next frame to avoid flushSync conflicts during React's commit phase\n // This prevents errors when virtualizers or other components use flushSync\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n }\n rafId = requestAnimationFrame(() => {\n rafId = null\n if (maxSeenRef.current > 0) {\n debugLog('ResizeObserver triggered re-apply:', {\n currentMax: maxSeenRef.current,\n containerSize: entries[0]?.contentRect,\n })\n applyVar(maxSeenRef.current)\n }\n })\n })\n ro.observe(container)\n\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n }\n ro.disconnect()\n }\n }, [getTargetElement, enabled, applyVar])\n\n return { queueMeasurement, resetMeasurements }\n}\n","import { createSelector, ReactStore } from '@base-ui/utils/store'\nimport { useRefWithInit } from '@base-ui/utils/useRefWithInit'\nimport {\n type ChangeEventDetails,\n createChangeEventDetails,\n createGenericEventDetails,\n type GenericEventDetails,\n REASONS,\n} from '../../../utils/events/index.js'\nimport type {\n HighlightChangeEventDetails,\n HighlightChangeReason,\n PopupMenuOpenChangeEventDetails,\n PopupMenuOpenChangeReason,\n} from '../../popup-menu/events.js'\nimport { commandScore } from '../utils/command-score.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type FilterFn = (\n value: string,\n search: string,\n keywords?: string[],\n) => number\n\nexport interface ItemRegistration {\n value: string\n keywords?: string[]\n groupId?: string\n disabled?: boolean\n /** Whether this item is a submenu trigger */\n isSubmenuTrigger?: boolean\n /** Single character keyboard shortcut to trigger this item */\n shortcut?: string\n /** Whether selecting this item should close the menu (default: true) */\n closeOnClick?: boolean\n}\n\n/**\n * Pre-registered item for virtualization.\n * This allows the store to know about all items even when they're not mounted.\n * The `value` field serves as both the unique identifier and the filtering value.\n */\nexport interface VirtualItem {\n /** Value used as unique identifier and for filtering/matching */\n value: string\n /** Additional keywords for filtering */\n keywords?: string[]\n /** Whether the item is disabled */\n disabled?: boolean\n}\n\nexport type HighlightSource = 'keyboard' | 'pointer' | 'auto' | null\n\n/**\n * Refs for DOM elements used for scroll behavior.\n * These are stored outside of reactive state to avoid unnecessary re-renders.\n */\nexport interface DOMRefs {\n /** Ref to the list/scroll container element */\n listRef: React.RefObject<HTMLElement | null>\n /** Map of item ID to ref for the item's DOM element */\n itemRefs: Map<string, React.RefObject<HTMLElement | null>>\n}\n\nexport interface ListboxState {\n /** Whether the listbox is open */\n open: boolean\n /** Current search query */\n search: string\n /** Currently highlighted item ID */\n highlightedId: string | null\n /** Source of the current highlight (keyboard or pointer) */\n highlightSource: HighlightSource\n /** Whether an Input is present in the Surface */\n hasInput: boolean\n /** Whether the input is currently active (rendered) when hideUntilActive mode is used */\n inputActive: boolean\n /** Pending search character typed before input was active */\n pendingSearch: string\n /** Filtered results: item ID to score */\n filteredItems: Map<string, number>\n /** Groups that have at least one visible item */\n visibleGroups: Set<string>\n /** Count of visible items */\n filteredCount: number\n /** Counter to trigger re-filtering when items change */\n filterTrigger: number\n /** Whether virtualization mode is enabled */\n virtualized: boolean\n /** Count of virtual items (from items prop) */\n virtualItemsCount: number\n}\n\nexport interface ListboxContext {\n /** Filter function or false to disable filtering */\n filter: FilterFn | false\n /** Whether to loop navigation */\n loop: boolean\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 */\n autoHighlightFirst: boolean | string\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 (requires Surface to call clearSearch)\n */\n clearSearchOnClose: boolean | 'after-exit'\n /** Whether hideUntilActive mode is enabled */\n hideUntilActive: boolean\n /** ID for the list element (for aria-activedescendant) */\n listId: string\n /** ID for the input element */\n inputId: string\n /** Map of item ID to registration data */\n readonly items: Map<string, ItemRegistration>\n /** Map of group ID to set of item IDs */\n readonly groups: Map<string, Set<string>>\n /** Map of item ID to onSelect callback */\n readonly itemSelects: Map<string, () => void>\n /** Map of submenu trigger ID to open callback */\n readonly submenuOpens: Map<string, () => void>\n /** Map of submenu trigger ID to close callback */\n readonly submenuCloses: Map<string, () => void>\n /** Map of shortcut key to item ID */\n readonly shortcuts: Map<string, string>\n /**\n * Callback when open state changes.\n * The second parameter contains event details including the reason for the change.\n */\n onOpenChange: (\n open: boolean,\n eventDetails: PopupMenuOpenChangeEventDetails,\n ) => void\n /** Callback when search state changes */\n onSearchChange: ((search: string) => void) | undefined\n /**\n * Pre-registered items for virtualization.\n * When provided, navigation uses this array order instead of DOM registration order.\n */\n virtualItems: VirtualItem[]\n /**\n * Consumer-provided ordered list of item values when filter={false}.\n * Used to determine correct navigation/highlight order when consumer handles filtering externally.\n * Must always be provided when filter={false}.\n */\n orderedItems: string[]\n /**\n * Callback when highlighted item changes and needs scroll sync.\n * Called only when the item is not in the DOM (virtualized out of view).\n * Useful for synchronizing with virtualizers (scrollToIndex).\n * The third parameter contains event details including the reason for the change.\n */\n onHighlightChange:\n | ((\n id: string | null,\n index: number,\n eventDetails: HighlightChangeEventDetails,\n ) => void)\n | undefined\n /**\n * DOM refs for scroll behavior.\n * Stored in context (not state) to avoid re-renders.\n */\n refs: DOMRefs\n /**\n * Callback when menu close animation completes.\n * Used for resetting row width measurements.\n */\n onCloseComplete?: () => void\n /**\n * Last known pointer position for detecting actual pointer movement.\n * Used to prevent \"phantom\" highlights when content shifts under a stationary pointer.\n */\n lastPointerPosition: { x: number; y: number } | null\n}\n\n/**\n * Options for the validateHighlight method.\n */\ninterface ValidateHighlightOptions {\n /**\n * Force highlighting the first item, even if current highlight is valid.\n * Used when the list order changes (e.g., after filtering).\n */\n forceFirst?: boolean\n /**\n * The newly computed filteredItems map. If not provided, uses state.filteredItems.\n * This is needed when calling from recomputeFilteredItems before state is updated.\n */\n filteredItems?: Map<string, number>\n /**\n * The new search query that corresponds to filteredItems.\n * Used together with prevSearch to detect when search is cleared.\n */\n newSearch?: string\n /**\n * The previous search query before the change.\n * Used together with newSearch to detect when search is cleared.\n */\n prevSearch?: string\n}\n\n// ============================================================================\n// Selectors\n// ============================================================================\n\nconst selectors = {\n open: createSelector((state: ListboxState) => state.open),\n search: createSelector((state: ListboxState) => state.search),\n highlightedId: createSelector((state: ListboxState) => state.highlightedId),\n highlightSource: createSelector(\n (state: ListboxState) => state.highlightSource,\n ),\n hasInput: createSelector((state: ListboxState) => state.hasInput),\n inputActive: createSelector((state: ListboxState) => state.inputActive),\n pendingSearch: createSelector((state: ListboxState) => state.pendingSearch),\n filteredCount: createSelector((state: ListboxState) => state.filteredCount),\n filteredItems: createSelector((state: ListboxState) => state.filteredItems),\n visibleGroups: createSelector((state: ListboxState) => state.visibleGroups),\n virtualized: createSelector((state: ListboxState) => state.virtualized),\n\n isHighlighted: createSelector(\n (state: ListboxState, itemId: string) => state.highlightedId === itemId,\n ),\n\n isGroupVisible: createSelector(\n (state: ListboxState, groupId: string) =>\n state.search.length === 0 || state.visibleGroups.has(groupId),\n ),\n\n getItemScore: createSelector((state: ListboxState, itemId: string) => {\n if (state.search.length === 0) {\n return 1 // All items visible when no search\n }\n return state.filteredItems.get(itemId) ?? 0\n }),\n\n hasSearchWithNoResults: createSelector((state: ListboxState) => {\n // Must have an active search\n if (state.search.length === 0) return false\n\n // In virtualized mode with items prop, check virtualItemsCount\n // (filteredCount won't be accurate since items aren't registered in DOM)\n if (state.virtualized && state.virtualItemsCount >= 0) {\n return state.virtualItemsCount === 0\n }\n\n // Non-virtualized mode: check filteredCount from registered items\n return state.filteredCount === 0\n }),\n}\n\n// ============================================================================\n// Store\n// ============================================================================\n\n/**\n * Core store for listbox-like components.\n * Handles item registration, filtering, navigation, and highlight state.\n *\n * Used by: DropdownMenu, ContextMenu, Select, CommandMenu\n */\nexport class ListboxStore extends ReactStore<\n ListboxState,\n ListboxContext,\n typeof selectors\n> {\n constructor(\n initialState?: Partial<ListboxState>,\n context?: Partial<ListboxContext>,\n ) {\n const defaultContext: ListboxContext = {\n filter: commandScore,\n loop: true,\n autoHighlightFirst: true,\n clearSearchOnClose: true,\n hideUntilActive: false,\n listId: '',\n inputId: '',\n items: new Map(),\n groups: new Map(),\n itemSelects: new Map(),\n submenuOpens: new Map(),\n submenuCloses: new Map(),\n shortcuts: new Map(),\n onOpenChange: () => {},\n onSearchChange: undefined,\n virtualItems: [],\n orderedItems: [],\n onHighlightChange: undefined,\n refs: {\n listRef: { current: null },\n itemRefs: new Map(),\n },\n onCloseComplete: undefined,\n lastPointerPosition: null,\n }\n\n super(\n { ...createInitialState(), ...initialState },\n { ...defaultContext, ...context },\n selectors,\n )\n\n // Handle open/close\n this.observe('open', (open) => {\n if (open) {\n // Reset pointer position tracking on open to prevent phantom highlights\n this.resetPointerPosition()\n\n // Auto-highlight is now handled by applyAutoHighlight() called from Surface\n // after it has set the context. This ensures the correct value is used.\n // We only handle the simple boolean true case here for backwards compatibility\n // with components that don't use Surface (if any).\n const autoHighlight = this.context.autoHighlightFirst\n if (autoHighlight === true) {\n // Default: highlight first item\n this.highlightFirstItem()\n }\n // String values are handled by applyAutoHighlight() from Surface\n } else {\n // Clear search and highlight on close\n // When 'after-exit', search is cleared by Root after animation completes\n if (this.context.clearSearchOnClose === true) {\n this.setSearch('')\n }\n\n // When 'after-exit', also defer hiding the input until animation completes\n // This prevents the input from disappearing before the popup animates out\n const deferInputHide = this.context.clearSearchOnClose === 'after-exit'\n\n this.update({\n highlightedId: null,\n highlightSource: null,\n inputActive: deferInputHide ? this.state.inputActive : false,\n pendingSearch: '',\n })\n }\n })\n\n // Recompute filtered items when search changes (handles controlled search via useControlledProp)\n this.observe('search', (search, prevSearch) => {\n if (search !== prevSearch) {\n // Reset pointer position when search changes - content is about to shift\n // and we don't want stationary pointers to trigger phantom highlights\n this.resetPointerPosition()\n this.recomputeFilteredItems(prevSearch)\n }\n })\n }\n\n // ============================================================================\n // Actions\n // ============================================================================\n\n /**\n * Set the open state with event details.\n *\n * @param open - The new open state\n * @param reason - The reason for the state change (default: 'none')\n * @param event - The native DOM event that triggered the change (optional)\n */\n setOpen(\n open: boolean,\n reason: PopupMenuOpenChangeReason = REASONS.none,\n event?: Event,\n ) {\n const eventDetails = createChangeEventDetails(reason, event)\n\n // Call the user's callback first\n this.context.onOpenChange(open, eventDetails)\n\n // If the user canceled, don't update internal state\n if (eventDetails.isCanceled) {\n return\n }\n\n this.set('open', open)\n }\n\n setSearch(search: string) {\n this.set('search', search)\n this.context.onSearchChange?.(search)\n // Note: recomputeFilteredItems is called by the 'search' observer\n }\n\n setHighlightedId(id: string | null, cause: HighlightSource = 'pointer') {\n const prevId = this.state.highlightedId\n if (prevId === id) return\n\n // Close any open submenus that are not the newly highlighted item\n // This ensures only one submenu is open at a time in this menu\n this.closeSiblingSubmenus(id)\n\n this.update({ highlightedId: id, highlightSource: cause })\n\n // Always notify about highlight changes (for virtualization, analytics, etc.)\n this.notifyHighlightChange(id, cause)\n\n // Handle scroll behavior for keyboard navigation\n if (cause === 'keyboard' && id !== null) {\n this.scrollItemIntoView(id)\n }\n }\n\n /**\n * Notify listeners about highlight changes.\n * Called whenever highlightedId changes, regardless of virtualization or DOM state.\n * Useful for virtualization scroll sync, analytics, or any other tracking needs.\n *\n * @param id - The newly highlighted item ID (or null if cleared)\n * @param cause - What caused the highlight change\n */\n private notifyHighlightChange(id: string | null, cause: HighlightSource) {\n const { onHighlightChange } = this.context\n if (!onHighlightChange) return\n\n // Map cause to reason\n const reason: HighlightChangeReason =\n cause === 'keyboard'\n ? REASONS.keyboard\n : cause === 'pointer'\n ? REASONS.pointer\n : REASONS.auto\n\n // Get the index of the highlighted item\n const index =\n id === null\n ? -1\n : this.state.virtualized\n ? this.getVirtualItemIndex(id)\n : this.getVisibleItemIndex(id)\n\n const eventDetails = createGenericEventDetails(reason, undefined, { index })\n onHighlightChange(id, index, eventDetails)\n }\n\n /**\n * Scroll the highlighted item into view.\n * Uses native scrollIntoView if the element is in the DOM.\n * For virtualized lists, the onHighlightChange callback (called from setHighlightedId)\n * should handle scrolling via the virtualizer.\n *\n * @param id - The item ID to scroll into view\n */\n private scrollItemIntoView(id: string) {\n const { refs } = this.context\n const listEl = refs.listRef.current\n const itemRef = refs.itemRefs.get(id)\n const itemEl = itemRef?.current\n\n // If the item element exists and is inside the list, use native scrollIntoView\n if (itemEl && listEl) {\n try {\n const isInList = listEl.contains(itemEl)\n if (isInList) {\n itemEl.scrollIntoView({ block: 'nearest' })\n }\n } catch {\n // Ignore errors from scrollIntoView\n }\n }\n // For virtualized lists where the item is not in the DOM,\n // the onHighlightChange callback handles scroll via virtualizer\n }\n\n setHasInput(hasInput: boolean) {\n this.set('hasInput', hasInput)\n }\n\n setInputActive(active: boolean) {\n this.set('inputActive', active)\n }\n\n setPendingSearch(search: string) {\n this.set('pendingSearch', search)\n }\n\n setHideUntilActive(enabled: boolean) {\n this.context.hideUntilActive = enabled\n // If enabling and there's already search content, activate immediately\n if (enabled && this.state.search.length > 0) {\n this.setInputActive(true)\n }\n }\n\n setVirtualized(virtualized: boolean) {\n this.set('virtualized', virtualized)\n }\n\n setVirtualItems(items: VirtualItem[]) {\n const prevItems = this.context.virtualItems\n this.context.virtualItems = items\n\n // Update count in state for selectors to use\n this.set('virtualItemsCount', items.length)\n\n // Pre-register all virtual items so filtering works for unmounted items\n this.preRegisterVirtualItems()\n\n // Skip if items reference didn't change (same array)\n if (items === prevItems) {\n return\n }\n\n // Skip highlight validation if not in the right state\n if (!this.state.virtualized || !this.state.open || items.length === 0) {\n return\n }\n\n // Determine if we need to force highlight the first item\n const prevFirstItem = prevItems.find((item) => !item.disabled)\n const newFirstItem = items.find((item) => !item.disabled)\n const firstItemChanged = newFirstItem?.value !== prevFirstItem?.value\n\n // Validate and potentially update the highlight\n this.validateHighlight({ forceFirst: firstItemChanged })\n }\n\n /**\n * Set the consumer-provided ordered items.\n * Used when filter={false} and consumer controls item order/visibility.\n * Must always be provided when filter={false}.\n *\n * @param items - Array of item IDs in display order\n */\n setOrderedItems(items: string[]) {\n const prevItems = this.context.orderedItems\n this.context.orderedItems = items\n\n // Skip if items reference didn't change (same array)\n if (items === prevItems) {\n return\n }\n\n // Skip highlight update if not open\n if (!this.state.open) {\n return\n }\n\n // When ordered items change, highlight the first registered item\n // Use 'auto' source to indicate this is automatic (not user-initiated)\n // This prevents submenus from auto-opening\n if (items.length > 0) {\n const firstRegisteredItem = items.find((id) => this.context.items.has(id))\n if (firstRegisteredItem !== undefined) {\n this.setHighlightedId(firstRegisteredItem, 'auto')\n } else {\n this.setHighlightedId(null)\n }\n } else {\n this.setHighlightedId(null)\n }\n }\n\n /**\n * Try to auto-highlight when an item registers.\n * This handles the case where orderedItems was set before items mounted.\n * Only highlights if:\n * - filter={false} (using orderedItems)\n * - Menu is open\n * - No item is currently highlighted\n * - autoHighlightFirst is enabled\n * - The registering item is the first in orderedItems\n */\n private maybeAutoHighlightOnRegister(id: string) {\n if (this.context.filter !== false) {\n return\n }\n if (!this.state.open) {\n return\n }\n if (this.state.highlightedId !== null) {\n return\n }\n if (!this.context.autoHighlightFirst) {\n return\n }\n\n const orderedItems = this.context.orderedItems\n if (orderedItems.length === 0) {\n return\n }\n\n // Find the first item in orderedItems that is registered\n const firstRegisteredItem = orderedItems.find((itemId) =>\n this.context.items.has(itemId),\n )\n\n // Only highlight if this is the first registered item\n // Use 'auto' source to indicate this is automatic (not user-initiated)\n if (firstRegisteredItem === id) {\n this.setHighlightedId(id, 'auto')\n }\n }\n\n setOnHighlightChange(\n callback:\n | ((\n id: string | null,\n index: number,\n eventDetails: HighlightChangeEventDetails,\n ) => void)\n | undefined,\n ) {\n this.context.onHighlightChange = callback\n }\n\n // ============================================================================\n // DOM Refs Management\n // ============================================================================\n\n /**\n * Set the list element ref for scroll container detection.\n */\n setListRef(ref: React.RefObject<HTMLElement | null>) {\n this.context.refs.listRef = ref\n }\n\n /**\n * Register an item's DOM ref for scrollIntoView behavior.\n * Returns a cleanup function.\n */\n registerItemRef(\n id: string,\n ref: React.RefObject<HTMLElement | null>,\n ): () => void {\n this.context.refs.itemRefs.set(id, ref)\n return () => {\n this.context.refs.itemRefs.delete(id)\n }\n }\n\n // ============================================================================\n // Pointer Position Tracking\n // ============================================================================\n\n /**\n * Check if pointer has moved and should allow highlight.\n * This prevents \"phantom\" highlights when content shifts under a stationary pointer\n * (e.g., when search results change or menu items reorder).\n *\n * @param x - Current pointer X position\n * @param y - Current pointer Y position\n * @returns true if pointer has actually moved and highlight should be allowed\n */\n shouldAllowPointerHighlight(x: number, y: number): boolean {\n const last = this.context.lastPointerPosition\n if (last === null) {\n // First pointer event - record position and allow highlight\n this.context.lastPointerPosition = { x, y }\n return true\n }\n\n // Check if pointer has actually moved (with small tolerance for sub-pixel movements)\n const dx = Math.abs(x - last.x)\n const dy = Math.abs(y - last.y)\n const hasMoved = dx > 1 || dy > 1\n\n if (hasMoved) {\n // Update position and allow highlight\n this.context.lastPointerPosition = { x, y }\n return true\n }\n\n // Pointer hasn't moved - don't allow highlight\n return false\n }\n\n /**\n * Reset pointer position tracking.\n * Call this when the menu opens or content changes significantly.\n */\n resetPointerPosition() {\n this.context.lastPointerPosition = null\n }\n\n /**\n * Pre-register virtual items so they appear in filteredItems.\n * This allows filtering to work for items that aren't mounted yet.\n */\n private preRegisterVirtualItems() {\n const virtualItems = this.context.virtualItems\n if (virtualItems.length === 0) return\n\n // Register each virtual item (using value as the unique identifier)\n for (const item of virtualItems) {\n if (!this.context.items.has(item.value)) {\n this.context.items.set(item.value, {\n value: item.value,\n keywords: item.keywords,\n disabled: item.disabled,\n })\n }\n }\n\n // Recompute filtered items to include virtual items\n this.recomputeFilteredItems()\n }\n\n // ============================================================================\n // Item Registration\n // ============================================================================\n\n registerItem(id: string, registration: ItemRegistration): () => void {\n // Check if this item is already registered with the same properties\n // This optimization reduces unnecessary recomputation in virtualized mode\n const existing = this.context.items.get(id)\n const isSameRegistration =\n existing &&\n existing.value === registration.value &&\n existing.disabled === registration.disabled &&\n existing.groupId === registration.groupId &&\n existing.shortcut === registration.shortcut\n\n if (isSameRegistration) {\n // Item already registered with same properties, skip recompute\n return () => {\n // Only clean up if this item is still in the map\n // (another registration might have replaced it)\n if (this.context.items.get(id) === existing) {\n this.context.items.delete(id)\n this.context.itemSelects.delete(id)\n if (registration.groupId) {\n this.context.groups.get(registration.groupId)?.delete(id)\n }\n if (registration.shortcut) {\n this.context.shortcuts.delete(registration.shortcut.toLowerCase())\n }\n this.recomputeFilteredItems()\n }\n }\n }\n\n this.context.items.set(id, registration)\n\n // Add to group if specified\n if (registration.groupId) {\n const groupItems = this.context.groups.get(registration.groupId)\n if (groupItems) {\n groupItems.add(id)\n }\n }\n\n // Register shortcut if specified\n if (registration.shortcut) {\n const key = registration.shortcut.toLowerCase()\n this.context.shortcuts.set(key, id)\n }\n\n // Trigger recompute\n this.recomputeFilteredItems()\n\n // When filter={false} and we're open with no highlight, try to highlight\n // This handles the case where orderedItems was set before items mounted\n this.maybeAutoHighlightOnRegister(id)\n\n return () => {\n this.context.items.delete(id)\n this.context.itemSelects.delete(id)\n\n if (registration.groupId) {\n const groupItems = this.context.groups.get(registration.groupId)\n if (groupItems) {\n groupItems.delete(id)\n }\n }\n\n // Unregister shortcut\n if (registration.shortcut) {\n const key = registration.shortcut.toLowerCase()\n this.context.shortcuts.delete(key)\n }\n\n this.recomputeFilteredItems()\n }\n }\n\n registerGroup(id: string): () => void {\n this.context.groups.set(id, new Set())\n\n return () => {\n this.context.groups.delete(id)\n }\n }\n\n registerItemSelect(\n id: string,\n onSelect: (() => void) | undefined,\n ): () => void {\n if (onSelect) {\n this.context.itemSelects.set(id, onSelect)\n }\n return () => {\n this.context.itemSelects.delete(id)\n }\n }\n\n registerSubmenuOpen(\n id: string,\n onOpen: (() => void) | undefined,\n ): () => void {\n if (onOpen) {\n this.context.submenuOpens.set(id, onOpen)\n }\n return () => {\n this.context.submenuOpens.delete(id)\n }\n }\n\n registerSubmenuClose(\n id: string,\n onClose: (() => void) | undefined,\n ): () => void {\n if (onClose) {\n this.context.submenuCloses.set(id, onClose)\n }\n return () => {\n this.context.submenuCloses.delete(id)\n }\n }\n\n /**\n * Close all submenus except the one with the given ID.\n * Used when hovering over a new submenu trigger to close sibling submenus.\n */\n closeSiblingSubmenus(exceptId: string | null) {\n for (const [id, onClose] of this.context.submenuCloses) {\n if (id !== exceptId) {\n try {\n onClose()\n } catch {\n // Ignore errors from closing submenus\n }\n }\n }\n }\n\n // ============================================================================\n // Navigation\n // ============================================================================\n\n highlightNext() {\n const visibleIds = this.getVisibleItemIds()\n\n if (visibleIds.length === 0) return\n\n const currentIndex = this.state.highlightedId\n ? visibleIds.indexOf(this.state.highlightedId)\n : -1\n let nextIndex = currentIndex + 1\n\n if (nextIndex >= visibleIds.length) {\n nextIndex = this.context.loop ? 0 : visibleIds.length - 1\n }\n\n const nextId = visibleIds[nextIndex]\n\n if (nextId) {\n this.setHighlightedId(nextId, 'keyboard')\n }\n }\n\n highlightPrev() {\n const visibleIds = this.getVisibleItemIds()\n\n if (visibleIds.length === 0) return\n\n const currentIndex = this.state.highlightedId\n ? visibleIds.indexOf(this.state.highlightedId)\n : visibleIds.length\n let prevIndex = currentIndex - 1\n\n if (prevIndex < 0) {\n prevIndex = this.context.loop ? visibleIds.length - 1 : 0\n }\n\n const prevId = visibleIds[prevIndex]\n\n if (prevId) {\n this.setHighlightedId(prevId, 'keyboard')\n }\n }\n\n selectHighlighted() {\n if (this.state.highlightedId) {\n const onSelect = this.context.itemSelects.get(this.state.highlightedId)\n onSelect?.()\n }\n }\n\n /**\n * Select an item by its keyboard shortcut.\n * Returns true if an item was found and selected, false otherwise.\n */\n selectByShortcut(key: string): boolean {\n const itemId = this.context.shortcuts.get(key.toLowerCase())\n if (!itemId) return false\n\n const registration = this.context.items.get(itemId)\n if (!registration || registration.disabled) return false\n\n // Check if item is visible (passes filter)\n const score = this.state.filteredItems.get(itemId) ?? 0\n const isVisible = this.state.search.length === 0 || score > 0\n if (!isVisible) return false\n\n const onSelect = this.context.itemSelects.get(itemId)\n onSelect?.()\n return true\n }\n\n openSubmenuForHighlighted() {\n if (this.state.highlightedId) {\n const onOpen = this.context.submenuOpens.get(this.state.highlightedId)\n onOpen?.()\n }\n }\n\n isHighlightedSubmenuTrigger(): boolean {\n if (!this.state.highlightedId) return false\n return (\n this.context.items.get(this.state.highlightedId)?.isSubmenuTrigger ??\n false\n )\n }\n\n /**\n * Get the item registration for the highlighted item.\n * Returns undefined if no item is highlighted.\n */\n getHighlightedItem(): ItemRegistration | undefined {\n if (!this.state.highlightedId) return undefined\n return this.context.items.get(this.state.highlightedId)\n }\n\n clearSearch() {\n this.setSearch('')\n }\n\n highlightFirstItem() {\n const visibleIds = this.getVisibleItemIds()\n if (visibleIds.length > 0 && visibleIds[0]) {\n // Don't set a cause - auto-highlight shouldn't trigger scroll\n this.update({ highlightedId: visibleIds[0], highlightSource: null })\n } else {\n this.update({ highlightedId: null, highlightSource: null })\n }\n }\n\n /**\n * Apply auto-highlight based on the current context.autoHighlightFirst value.\n * Called by Surface after updating the context to ensure correct value is used.\n */\n applyAutoHighlight() {\n if (!this.state.open) return\n\n const autoHighlight = this.context.autoHighlightFirst\n if (autoHighlight === true) {\n this.highlightFirstItem()\n } else if (typeof autoHighlight === 'string') {\n this.highlightItemByValue(autoHighlight)\n }\n // If false, don't highlight anything\n }\n\n /**\n * Highlight a specific item by its value.\n * If the item is not visible or doesn't exist, falls back to highlighting the first item.\n * Scrolls the highlighted item into view.\n */\n highlightItemByValue(value: string) {\n const visibleIds = this.getVisibleItemIds()\n let highlightedId: string | null = null\n\n if (visibleIds.includes(value)) {\n // Item exists and is visible - highlight it\n highlightedId = value\n } else if (visibleIds.length > 0 && visibleIds[0]) {\n // Fall back to first item if specified value not found\n highlightedId = visibleIds[0]\n }\n\n this.update({ highlightedId, highlightSource: null })\n\n // Scroll the highlighted item into view\n // This is important when opening a combobox with a pre-selected value\n // that may be far down the list\n if (highlightedId) {\n // Use requestAnimationFrame to ensure the DOM has updated\n requestAnimationFrame(() => {\n this.scrollItemIntoView(highlightedId)\n })\n }\n }\n\n // ============================================================================\n // Internal Helpers\n // ============================================================================\n\n /**\n * Returns whether filtering is disabled (consumer handles filtering externally).\n */\n isFilterDisabled(): boolean {\n return this.context.filter === false\n }\n\n getVisibleItemIds(): string[] {\n const result: string[] = []\n const search = this.state.search\n const filteredItems = this.state.filteredItems\n const virtualItems = this.context.virtualItems\n const orderedItems = this.context.orderedItems\n\n // When virtualized with items, use the virtualItems order\n // This ensures navigation order matches the data array order\n if (this.state.virtualized && virtualItems.length > 0) {\n for (const item of virtualItems) {\n const score = filteredItems.get(item.value) ?? 0\n const isVisible = search.length === 0 || score > 0\n if (isVisible && !item.disabled) {\n result.push(item.value)\n }\n }\n return result\n }\n\n // When consumer provides ordered items (filter={false}), use that order\n // This ensures navigation matches the consumer's intended display order\n if (this.context.filter === false && orderedItems.length > 0) {\n // Track unregistered items for warning\n const unregisteredItems: string[] = []\n\n for (const itemId of orderedItems) {\n const registration = this.context.items.get(itemId)\n // Only include if registered (mounted) and not disabled\n if (registration && !registration.disabled) {\n result.push(itemId)\n } else if (!registration) {\n unregisteredItems.push(itemId)\n }\n }\n\n // Only warn about unregistered items if SOME items are registered\n // If no items are registered, we're likely in the initial mount phase\n // and items will register shortly via maybeAutoHighlightOnRegister\n if (\n process.env.NODE_ENV !== 'production' &&\n unregisteredItems.length > 0 &&\n result.length > 0\n ) {\n for (const itemId of unregisteredItems) {\n console.warn(\n `[ListboxStore] Item \"${itemId}\" is in orderedItems but not registered. ` +\n 'This may cause keyboard navigation to skip this item. ' +\n 'Make sure the render function passes the `id` prop: <Item {...props}>...</Item>',\n )\n }\n }\n\n return result\n }\n\n // Non-virtualized: use mounted items order\n this.context.items.forEach((registration, id) => {\n const score = filteredItems.get(id) ?? 0\n const isVisible = search.length === 0 || score > 0\n if (isVisible && !registration.disabled) {\n result.push(id)\n }\n })\n\n return result\n }\n\n /**\n * Get the index of an item in the visible items list.\n * Returns -1 if the item is not found or not visible.\n */\n getVisibleItemIndex(id: string): number {\n return this.getVisibleItemIds().indexOf(id)\n }\n\n /**\n * Get the index of an item in the virtualItems array.\n * This is used for virtualizer scrollToIndex which needs the raw array index,\n * not the filtered/visible index.\n * Returns -1 if not found or not in virtualized mode.\n */\n getVirtualItemIndex(value: string): number {\n if (!this.state.virtualized) return -1\n return this.context.virtualItems.findIndex((item) => item.value === value)\n }\n\n /**\n * Validates and updates the highlighted item.\n * This is the single source of truth for highlight management.\n *\n * @param options.forceFirst - Force highlight first item even if current is valid\n * @param options.filteredItems - Use this map instead of state (for mid-update calls)\n * @param options.newSearch - The search query for filteredItems (to detect search cleared)\n */\n private validateHighlight(\n options: ValidateHighlightOptions = {},\n ): string | null {\n const {\n forceFirst = false,\n filteredItems = this.state.filteredItems,\n newSearch,\n prevSearch: optionsPrevSearch,\n } = options\n\n // Determine if search changed (requires reset to first item)\n // Use prevSearch from options if provided (from observer), otherwise fall back to state\n const prevSearch =\n optionsPrevSearch !== undefined ? optionsPrevSearch : this.state.search\n const effectiveSearch = newSearch !== undefined ? newSearch : prevSearch\n const searchChanged = newSearch !== undefined && newSearch !== prevSearch\n\n // If not open or autoHighlightFirst disabled, don't change anything\n if (!this.state.open || !this.context.autoHighlightFirst) {\n return this.state.highlightedId\n }\n\n const currentHighlight = this.state.highlightedId\n const { filter } = this.context\n\n // If search changed, force reset to first item\n const shouldForceFirst = forceFirst || searchChanged\n\n // Check if current highlight is valid\n let isCurrentValid = false\n if (currentHighlight && !shouldForceFirst) {\n // Check if item exists and passes filter\n const score = filteredItems.get(currentHighlight) ?? 0\n const isVisible =\n effectiveSearch.length === 0 || filter === false || score > 0\n\n // Check if item is disabled\n const registration = this.context.items.get(currentHighlight)\n const virtualItem = this.context.virtualItems.find(\n (v) => v.value === currentHighlight,\n )\n const isDisabled =\n registration?.disabled ?? virtualItem?.disabled ?? false\n\n // Item must be registered (in items map) for non-virtualized mode\n const isRegistered = this.state.virtualized || registration !== undefined\n\n // In virtualized mode, item must also be in virtualItems array\n const inVirtualItems =\n !this.state.virtualized ||\n this.context.virtualItems.length === 0 ||\n virtualItem !== undefined\n\n isCurrentValid =\n isVisible && !isDisabled && isRegistered && inVirtualItems\n }\n\n // If current highlight is valid and we're not forcing first, keep it\n if (isCurrentValid) {\n return currentHighlight\n }\n\n // Find the first valid item to highlight\n let newHighlightId: string | null = null\n\n if (this.state.virtualized && this.context.virtualItems.length > 0) {\n // Virtualized mode: use virtualItems order\n for (const item of this.context.virtualItems) {\n const score = filteredItems.get(item.value) ?? 0\n const isVisible =\n effectiveSearch.length === 0 || filter === false || score > 0\n if (isVisible && !item.disabled) {\n newHighlightId = item.value\n break\n }\n }\n } else if (filter === false && this.context.orderedItems.length > 0) {\n // Consumer-controlled filtering: use orderedItems order\n for (const itemId of this.context.orderedItems) {\n const registration = this.context.items.get(itemId)\n // Only include if registered (mounted) and not disabled\n if (registration && !registration.disabled) {\n newHighlightId = itemId\n break\n }\n }\n } else {\n // Non-virtualized mode: use mounted items\n for (const [id, registration] of this.context.items) {\n const score = filteredItems.get(id) ?? 0\n const isVisible = effectiveSearch.length === 0 || score > 0\n if (isVisible && !registration.disabled) {\n newHighlightId = id\n break\n }\n }\n }\n\n // Only update if highlight actually changed\n if (newHighlightId !== currentHighlight) {\n this.update({\n highlightedId: newHighlightId,\n highlightSource: null, // Auto-highlight shouldn't trigger scroll\n })\n }\n\n return newHighlightId\n }\n\n private recomputeFilteredItems(prevSearch?: string) {\n const { filter } = this.context\n const search = this.state.search\n const items = this.context.items\n const groups = this.context.groups\n\n const filteredItems = new Map<string, number>()\n const visibleGroups = new Set<string>()\n let filteredCount = 0\n\n // If no search or filtering disabled, all items are visible\n if (!search || filter === false) {\n // When virtualized with consumer-side filtering (filter === false),\n // use virtualItems as the source of truth for what's visible.\n // This ensures the scores match the consumer's filtered array,\n // not just what's currently mounted.\n if (this.state.virtualized && this.context.virtualItems.length > 0) {\n for (const item of this.context.virtualItems) {\n filteredItems.set(item.value, 1)\n filteredCount++\n }\n } else {\n items.forEach((_, id) => {\n filteredItems.set(id, 1)\n filteredCount++\n })\n }\n groups.forEach((_, groupId) => {\n visibleGroups.add(groupId)\n })\n } else {\n // Apply filter function\n const filterFn = filter || commandScore\n items.forEach((registration, id) => {\n const score = filterFn(\n registration.value,\n search,\n registration.keywords,\n )\n filteredItems.set(id, score)\n if (score > 0) {\n filteredCount++\n if (registration.groupId) {\n visibleGroups.add(registration.groupId)\n }\n }\n })\n }\n\n // When filter={false}, consumer controls highlighting via setConsumerFilteredItems.\n // Don't call validateHighlight here because consumerFilteredItems hasn't been updated yet.\n // The highlight will be set when setConsumerFilteredItems is called from the Surface effect.\n if (filter === false) {\n this.update({\n filteredItems,\n visibleGroups,\n filteredCount,\n filterTrigger: this.state.filterTrigger + 1,\n // Don't change highlight - let setConsumerFilteredItems handle it\n })\n return\n }\n\n // Validate highlight using the newly computed filteredItems\n // We pass filteredItems, newSearch, and prevSearch here because we need to detect search cleared\n const highlightedId = this.validateHighlight({\n filteredItems,\n newSearch: search,\n prevSearch,\n })\n\n this.update({\n filteredItems,\n visibleGroups,\n filteredCount,\n filterTrigger: this.state.filterTrigger + 1,\n highlightedId,\n // Auto-highlight shouldn't trigger scroll\n highlightSource: null,\n })\n }\n\n // ============================================================================\n // Static Factory\n // ============================================================================\n\n static useStore(\n externalStore: ListboxStore | undefined,\n initialState?: Partial<ListboxState>,\n context?: Partial<ListboxContext>,\n ): ListboxStore {\n const store = useRefWithInit(() => {\n return externalStore ?? new ListboxStore(initialState, context)\n }).current\n\n return store\n }\n}\n\n// ============================================================================\n// Initial State Factory\n// ============================================================================\n\nfunction createInitialState(): ListboxState {\n return {\n open: false,\n search: '',\n highlightedId: null,\n highlightSource: null,\n hasInput: false,\n inputActive: false,\n pendingSearch: '',\n filteredItems: new Map(),\n visibleGroups: new Set(),\n filteredCount: 0,\n filterTrigger: 0,\n virtualized: false,\n virtualItemsCount: 0,\n }\n}\n\n// ============================================================================\n// Re-export types for convenience\n// ============================================================================\n\nexport type { ListboxState as State, ListboxContext as Context }\n","/**\n * Fuzzy matching algorithm for command palette-style filtering.\n * Vendored from cmdk (https://github.com/pacocoursey/cmdk)\n *\n * The scores are arranged so that a continuous match of characters will\n * result in a total score of 1.\n */\n\n// The best case: this character is a match, and either this is the start\n// of the string, or the previous character was also a match.\nconst SCORE_CONTINUE_MATCH = 1\n\n// A new match at the start of a word scores better than a new match\n// elsewhere as it's more likely that the user will type the starts\n// of fragments.\n// NOTE: We score word jumps between spaces slightly higher than slashes, brackets, hyphens, etc.\nconst SCORE_SPACE_WORD_JUMP = 0.9\nconst SCORE_NON_SPACE_WORD_JUMP = 0.8\n\n// Any other match isn't ideal, but we include it for completeness.\nconst SCORE_CHARACTER_JUMP = 0.17\n\n// If the user transposed two letters, it should be significantly penalized.\n// i.e. \"ouch\" is more likely than \"curtain\" when \"uc\" is typed.\nconst SCORE_TRANSPOSITION = 0.1\n\n// The goodness of a match should decay slightly with each missing character.\n// i.e. \"bad\" is more likely than \"bard\" when \"bd\" is typed.\n// This will not change the order of suggestions based on SCORE_* until\n// 100 characters are inserted between matches.\nconst PENALTY_SKIPPED = 0.999\n\n// The goodness of an exact-case match should be higher than a\n// case-insensitive match by a small amount.\n// i.e. \"HTML\" is more likely than \"haml\" when \"HM\" is typed.\n// This will not change the order of suggestions based on SCORE_* until\n// 1000 characters are inserted between matches.\nconst PENALTY_CASE_MISMATCH = 0.9999\n\n// Match higher for letters closer to the beginning of the word\nconst PENALTY_DISTANCE_FROM_START = 0.9\n\n// If the word has more characters than the user typed, it should\n// be penalised slightly.\n// i.e. \"html\" is more likely than \"html5\" if I type \"html\".\n// However, it may well be the case that there's a sensible secondary\n// ordering (like alphabetical) that it makes sense to rely on when\n// there are many prefix matches, so we don't make the penalty increase\n// with the number of tokens.\nconst PENALTY_NOT_COMPLETE = 0.99\n\nconst IS_GAP_REGEXP = /[\\\\/_+.#\"@[({&]/\nconst COUNT_GAPS_REGEXP = /[\\\\/_+.#\"@[({&]/g\nconst IS_SPACE_REGEXP = /[\\s-]/\nconst COUNT_SPACE_REGEXP = /[\\s-]/g\n\ntype MemoizedResults = Record<string, number>\n\nfunction commandScoreInner(\n string: string,\n abbreviation: string,\n lowerString: string,\n lowerAbbreviation: string,\n stringIndex: number,\n abbreviationIndex: number,\n memoizedResults: MemoizedResults,\n): number {\n if (abbreviationIndex === abbreviation.length) {\n if (stringIndex === string.length) {\n return SCORE_CONTINUE_MATCH\n }\n return PENALTY_NOT_COMPLETE\n }\n\n const memoizeKey = `${stringIndex},${abbreviationIndex}`\n if (memoizedResults[memoizeKey] !== undefined) {\n return memoizedResults[memoizeKey]\n }\n\n const abbreviationChar = lowerAbbreviation.charAt(abbreviationIndex)\n let index = lowerString.indexOf(abbreviationChar, stringIndex)\n let highScore = 0\n\n let score: number\n let transposedScore: number\n let wordBreaks: RegExpMatchArray | null\n let spaceBreaks: RegExpMatchArray | null\n\n while (index >= 0) {\n score = commandScoreInner(\n string,\n abbreviation,\n lowerString,\n lowerAbbreviation,\n index + 1,\n abbreviationIndex + 1,\n memoizedResults,\n )\n\n if (score > highScore) {\n if (index === stringIndex) {\n score *= SCORE_CONTINUE_MATCH\n } else if (IS_GAP_REGEXP.test(string.charAt(index - 1))) {\n score *= SCORE_NON_SPACE_WORD_JUMP\n wordBreaks = string\n .slice(stringIndex, index - 1)\n .match(COUNT_GAPS_REGEXP)\n if (wordBreaks && stringIndex > 0) {\n score *= PENALTY_SKIPPED ** wordBreaks.length\n }\n } else if (IS_SPACE_REGEXP.test(string.charAt(index - 1))) {\n score *= SCORE_SPACE_WORD_JUMP\n spaceBreaks = string\n .slice(stringIndex, index - 1)\n .match(COUNT_SPACE_REGEXP)\n if (spaceBreaks && stringIndex > 0) {\n score *= PENALTY_SKIPPED ** spaceBreaks.length\n }\n } else {\n score *= SCORE_CHARACTER_JUMP\n if (stringIndex > 0) {\n score *= PENALTY_SKIPPED ** (index - stringIndex)\n }\n }\n\n if (string.charAt(index) !== abbreviation.charAt(abbreviationIndex)) {\n score *= PENALTY_CASE_MISMATCH\n }\n }\n\n if (\n (score < SCORE_TRANSPOSITION &&\n lowerString.charAt(index - 1) ===\n lowerAbbreviation.charAt(abbreviationIndex + 1)) ||\n (lowerAbbreviation.charAt(abbreviationIndex + 1) ===\n lowerAbbreviation.charAt(abbreviationIndex) &&\n lowerString.charAt(index - 1) !==\n lowerAbbreviation.charAt(abbreviationIndex))\n ) {\n transposedScore = commandScoreInner(\n string,\n abbreviation,\n lowerString,\n lowerAbbreviation,\n index + 1,\n abbreviationIndex + 2,\n memoizedResults,\n )\n\n if (transposedScore * SCORE_TRANSPOSITION > score) {\n score = transposedScore * SCORE_TRANSPOSITION\n }\n }\n\n if (score > highScore) {\n highScore = score\n }\n\n index = lowerString.indexOf(abbreviationChar, index + 1)\n }\n\n memoizedResults[memoizeKey] = highScore\n return highScore\n}\n\nfunction formatInput(string: string): string {\n // Convert all valid space characters to space so they match each other\n return string.toLowerCase().replace(COUNT_SPACE_REGEXP, ' ')\n}\n\n/**\n * Calculates a fuzzy match score between a string and an abbreviation.\n *\n * @param string - The string to match against\n * @param abbreviation - The search query\n * @param keywords - Optional additional keywords to include in matching\n * @returns A score between 0 and 1, where 1 is a perfect match and 0 is no match\n */\nexport function commandScore(\n string: string,\n abbreviation: string,\n keywords?: string[],\n): number {\n if (!abbreviation) return 1\n if (!string) return 0\n\n // Combine string with keywords for matching\n const fullString =\n keywords && keywords.length > 0 ? `${string} ${keywords.join(' ')}` : string\n\n return commandScoreInner(\n fullString,\n abbreviation,\n formatInput(fullString),\n formatInput(abbreviation),\n 0,\n 0,\n {},\n )\n}\n\n/**\n * Default filter function for listbox items.\n * Returns a score > 0 for matches, 0 for non-matches.\n */\nexport const defaultFilter = commandScore\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","'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","'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 { 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 { useAimGuard } from '../../hooks/use-aim-guard.js'\nimport { PopupMenuPopupDataAttributes } from './popup.data-attrs.js'\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\nexport interface PopupMenuPopupProps\n extends Omit<PopoverPopupProps, 'className'> {\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// ============================================================================\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 { children, className: classNameProp, ...rest } = 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 // 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', surfaceId)\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 // 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 // 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 const extendedState: PopupMenuPopupState = { ...baseState, isSubmenu }\n return classNameProp(extendedState)\n }\n }\n return classNameProp\n }, [classNameProp, isSubmenu])\n\n // Get component name for slot attribute\n const componentName = useMaybeComponentName()\n const slotAttr = getSlotAttribute(componentName, 'popup')\n\n return (\n <PopupSurfaceIdContext.Provider value={surfaceId}>\n <Popover.Popup\n ref={combinedRef}\n initialFocus={initialFocus}\n finalFocus={finalFocus}\n className={className}\n data-input-embedded={isInputEmbedded ? '' : undefined}\n {...(slotAttr ? { [slotAttr]: '' } : {})}\n {...{\n [PopupMenuPopupDataAttributes.focused]: isFocused ? '' : undefined,\n [PopupMenuPopupDataAttributes.hasOpenSubmenu]: hasOpenSubmenu\n ? ''\n : undefined,\n [PopupMenuPopupDataAttributes.submenu]: isSubmenu ? '' : undefined,\n }}\n onPointerMove={(event) => {\n handlePointerMove()\n handleFocusTransferOnMove(event)\n rest.onPointerMove?.(event)\n }}\n {...rest}\n >\n {children}\n </Popover.Popup>\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 { 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","'use client'\n\nimport { Popover, type PopoverPositionerProps } from '@base-ui/react/popover'\nimport * as React from 'react'\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\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 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 we've measured (only measure once per open)\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 // 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 // Measurement function for list-start offset\n // Updates the ref and forces a synchronous re-render\n const measureListStartOffset = React.useCallback(() => {\n if (!useListStartAlign) return\n\n const contentEl = submenuContext?.contentRef.current\n if (!contentEl) return\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 listStartOffsetRef.current = 0\n return\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 offset = -(listRect.top + listPaddingTop - contentRect.top)\n listStartOffsetRef.current = offset\n }, [useListStartAlign, submenuContext])\n\n // Measure once when submenu opens\n // Using useLayoutEffect to measure synchronously 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 // Reset measurement flag when menu closes\n React.useEffect(() => {\n if (!isOpen) {\n hasMeasuredRef.current = false\n listStartOffsetRef.current = 0\n }\n }, [isOpen])\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 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 /** 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 /**\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 * - 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 depth,\n closeAll,\n registerSurface,\n virtualization,\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 depth,\n closeAll,\n registerSurface,\n virtualization,\n virtualAnchor,\n menuType,\n closeOnOutsidePress,\n getQualifiedRowId,\n }),\n [\n store,\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 return (\n <ComponentNameContext.Provider value={componentName}>\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 </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 { 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 type UsePopupMenuItemReturn = UseListboxItemReturn\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, ...rest } = params\n const { aimGuardActiveRef, guardedDepthRef } = useAimGuard()\n const { closeAll } = useListboxContext()\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 return useListboxItem({\n ...rest,\n aimGuard,\n closeOnClick,\n onAfterSelect: handleAfterSelect,\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 { 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 /** Whether keyboard handling is enabled */\n enabled: 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 enabled,\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 // 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,\n onKeyDown,\n onSelect: handleSelect,\n closeAll,\n focusOwner: focusOwnerStore,\n depth,\n submenuContext: submenuInterface,\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'\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 // Use dedicated selector for this check\n const shouldRender = store.useState('hasSearchWithNoResults')\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 { 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 { useMaybeSubmenuContext } from '../../contexts/submenu-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 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 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 enabled: true,\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 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 { useMaybeSubmenuContext } from '../../contexts/submenu-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 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\n\n // Use centralized keyboard navigation hook\n const { handleKeyDown } = usePopupMenuKeyboard({\n store,\n surfaceId,\n focusOwnerStore,\n depth,\n submenuContext,\n enabled: shouldHandleKeyboard,\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 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 SurfaceContext,\n useListboxContext,\n useSurfaceContext as useParentSurfaceContext,\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'\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 * 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 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 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 // 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.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 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 (depth === 0 && open) {\n focusOwnerStore.setOwnerId(surfaceId)\n }\n }, [depth, open, surfaceId, focusOwnerStore])\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 (!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 }, [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 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\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 = false,\n onSelect,\n forceMount = false,\n closeOnClick = false,\n shortcut,\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,\n forceMount,\n shortcut,\n closeOnClick,\n children,\n })\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","'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\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 = false,\n onSelect,\n forceMount = false,\n closeOnClick = true,\n shortcut,\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,\n forceMount,\n shortcut,\n onSelect,\n closeOnClick,\n children,\n })\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","'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 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 = false,\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 // 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","'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\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 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 disabled = 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,\n forceMount,\n shortcut,\n closeOnClick,\n children,\n })\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","'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('search')\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","'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'\n\nexport interface PopupMenuSubmenuRootProps\n extends Omit<PopoverRootProps, 'open' | 'onOpenChange' | 'defaultOpen'> {\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 * Only called when `virtualized={true}`.\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 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 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 // 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 store.setOpen(newOpen)\n },\n [store, 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 }\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 store.setOpen(false)\n }\n }, [parentOpen, store])\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) => store.setOpen(newOpen))\n }, [parentRegisterSurface, depth, store])\n\n // Submenu context value\n const submenuContextValue = React.useMemo(\n () => ({\n open,\n setOpen: (newOpen: boolean) => store.setOpen(newOpen),\n triggerRef,\n contentRef,\n parentSurfaceId,\n childSurfaceId,\n closeRootOnEsc,\n }),\n [open, store, parentSurfaceId, childSurfaceId, closeRootOnEsc],\n )\n\n // Fallback registerSurface for edge cases (submenu without parent root)\n const fallbackRegisterSurface = React.useCallback(() => () => {}, [])\n\n // Memoize virtualization config for this submenu\n const virtualization = React.useMemo(() => {\n if (!virtualized) return undefined\n return {\n virtualized: true as const,\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 depth,\n closeAll: parentCloseAll ?? (() => store.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 }),\n [\n store,\n depth,\n parentCloseAll,\n parentRegisterSurface,\n fallbackRegisterSurface,\n virtualization,\n parentPopupMenuContext?.virtualAnchor,\n parentPopupMenuContext?.menuType,\n parentPopupMenuContext?.closeOnOutsidePress,\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 >\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 = Popover.Root.Actions\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 { 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 getSmoothedHeading,\n resolveAnchorSide,\n willHitSubmenu,\n} from '../../utils/aim-guard.js'\nimport { useMouseTrail } from '../../utils/use-mouse-trail.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/**\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 = false,\n forceMount = false,\n openOnHighlight = true,\n delay: delayProp,\n closeDelay = 0,\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\n const clearOpenTimer = React.useCallback(() => {\n if (openTimerRef.current !== null) {\n clearTimeout(openTimerRef.current)\n openTimerRef.current = null\n }\n }, [])\n\n // Cleanup timer on unmount\n React.useEffect(() => clearOpenTimer, [clearOpenTimer])\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 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 // 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,\n forceMount,\n isSubmenuTrigger: true,\n closeOnClick: false, // Submenu triggers don't close the menu\n children,\n })\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 onPointerDown?.(event)\n },\n [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\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 return\n }\n\n // Highlight on hover (use storeId for store operations)\n parentStore.setHighlightedId(item.storeId)\n },\n [\n onPointerMove,\n disabled,\n aimGuardActiveRef,\n guardedDepthRef,\n parentDepth,\n guardedTriggerIdRef,\n item.id,\n item.storeId,\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\n // Check if aim guard is blocking this trigger\n if (\n aimGuardActiveRef.current &&\n guardedTriggerIdRef.current !== item.id\n ) {\n return\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 // Clear any existing aim guard and schedule open with delay\n clearAimGuard()\n clearOpenTimer()\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 guardedTriggerIdRef,\n item.id,\n item.storeId,\n parentStore,\n openOnHighlight,\n clearAimGuard,\n clearOpenTimer,\n delay.pointer,\n setOpen,\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\n // Cancel any pending open timer\n clearOpenTimer()\n\n // Check if aim guard is blocking this trigger\n if (aimGuardActiveRef.current && guardedTriggerIdRef.current !== item.id)\n return\n\n // Get the submenu content rect for safe polygon calculation\n const contentRect = contentRef.current?.getBoundingClientRect()\n if (!contentRect) {\n clearAimGuard()\n setOpen(false)\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 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 clearAimGuard()\n return\n }\n\n // Get trigger rect for aim guard calculation\n const tRect = triggerRef.current?.getBoundingClientRect() ?? null\n\n // Calculate safe polygon and check if user is aiming toward submenu\n const anchor = resolveAnchorSide(contentRect, tRect, clientX)\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 // DEBUG: Uncomment to debug aim guard issues\n // console.log('[AimGuard]', { clientX, clientY, contentRect, anchor, heading, hit, trail: [...mouseTrailRef.current] })\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 activateAimGuard(item.id, parentDepth, childSurfaceId, 600)\n parentStore.setHighlightedId(item.storeId)\n setOpen(true)\n } else {\n // User is not aiming at submenu - close it\n clearAimGuard()\n setOpen(false)\n }\n },\n [\n onPointerLeave,\n disabled,\n clearOpenTimer,\n aimGuardActiveRef,\n guardedTriggerIdRef,\n item.id,\n item.storeId,\n contentRef,\n clearAimGuard,\n setOpen,\n triggerRef,\n mouseTrailRef,\n activateAimGuard,\n parentDepth,\n childSurfaceId,\n parentStore,\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 // Don't render if not visible\n if (!item.isVisible) return null\n\n return <Popover.Trigger nativeButton={false} render={element} />\n})\n\nexport namespace PopupMenuSubmenuTrigger {\n export type State = PopupMenuSubmenuTriggerState\n export interface Props extends PopupMenuSubmenuTriggerProps {}\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","'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 loading */\n isAnyLoading: boolean\n /** Static loaders are loading */\n isStaticLoading: boolean\n /** Query loaders are loading */\n isQueryLoading: boolean\n /** All loaders have resolved (not loading, no pending) */\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 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 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 isAnyLoading = isStaticLoading || isQueryLoading\n\n const allResolved = React.useMemo(() => {\n for (const [, state] of loaders) {\n if (state.result.isLoading) {\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 isStaticLoading,\n isQueryLoading,\n skippedMenus,\n }\n }, [isAnyLoading, isStaticLoading, isQueryLoading, erroredLoaders])\n\n // Context value\n const contextValue: AsyncMenuCoordinatorValue = React.useMemo(\n () => ({\n registerLoader,\n unregisterLoader,\n updateLoaderResult,\n searchQuery,\n loaders,\n isAnyLoading,\n isStaticLoading,\n isQueryLoading,\n allResolved,\n getAsyncNodes,\n erroredLoaders,\n getAsyncState,\n }),\n [\n registerLoader,\n unregisterLoader,\n updateLoaderResult,\n searchQuery,\n loaders,\n isAnyLoading,\n isStaticLoading,\n isQueryLoading,\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 * as React from 'react'\nimport type {\n AsyncLoaderConfig,\n DeepSearchConfig,\n DisplayNode,\n GetQualifiedRowIdFn,\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 /** 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\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\n// ============================================================================\n// Render Node Function Type\n// ============================================================================\n\nexport type RenderNodeFn = (displayNode: DisplayNode) => React.ReactNode\n","'use client'\n\nimport * as React from 'react'\nimport { useSurfaceContext } from '../../listbox/index.js'\nimport { PopupMenuList } from '../components/list/list.js'\nimport {\n AsyncMenuCoordinatorProvider,\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 RadioGroupDef,\n RowRenderContext,\n SubmenuDef,\n} from './types.js'\nimport {\n isDisplayGroupNode,\n isDisplayRadioGroupNode,\n isDisplaySeparatorNode,\n} from './types.js'\nimport {\n type AsyncSubmenuInfo,\n collectAsyncSubmenus,\n filterNodes,\n mergeAsyncNodesIntoTree,\n shouldIncludeInDeepSearch,\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\n// ============================================================================\n// Async Loader Component\n// ============================================================================\n\ninterface AsyncLoaderRendererProps {\n info: AsyncSubmenuInfo\n query: string\n enabled: boolean\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, node } = info\n const Loader = config.Loader\n\n // For query-dependent loaders, determine effective query\n const effectiveQuery = React.useMemo(() => {\n if (config.type === 'query') {\n const minLength = config.minQueryLength ?? 1\n if (query.length < minLength) {\n return ''\n }\n }\n return query\n }, [config, query])\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}>\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 isLoading: boolean\n isError: 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.isLoading !== result.isLoading ||\n prev.isError !== result.isError ||\n prev.error !== result.error\n\n if (hasChanged) {\n prevResultRef.current = {\n data: result.data,\n isLoading: result.isLoading,\n isError: result.isError,\n error: result.error,\n }\n coord.updateLoaderResult(id, result)\n }\n }, [id, result.data, result.isLoading, result.isError, result.error]) // 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 // For query-dependent loaders, determine effective query\n const effectiveQuery = React.useMemo(() => {\n if (!asyncContent) return ''\n if (asyncContent.type === 'query') {\n const minLength = asyncContent.minQueryLength ?? 1\n if (query.length < minLength) {\n return ''\n }\n }\n return query\n }, [asyncContent, query])\n\n if (!asyncContent) {\n return null\n }\n\n const Loader = asyncContent.Loader\n\n return (\n <Loader query={effectiveQuery}>\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 const {\n children,\n label = 'Menu',\n className,\n style,\n render,\n measureRowWidth,\n maxRowWidth,\n } = props\n\n // Get data surface context for content and deep search config\n const dataSurfaceCtx = useDataSurfaceContext()\n const { content, asyncContent, deepSearchConfig, getQualifiedRowId } =\n dataSurfaceCtx\n\n // Get store from surface context for search state\n const { store } = useSurfaceContext()\n const search = store.useState('search')\n\n // Wrap with coordinator provider\n return (\n <AsyncMenuCoordinatorProvider searchQuery={search}>\n <DataListInner\n ref={forwardedRef}\n {...props}\n content={content}\n asyncContent={asyncContent}\n deepSearchConfig={deepSearchConfig}\n getQualifiedRowId={getQualifiedRowId}\n search={search}\n store={store}\n />\n </AsyncMenuCoordinatorProvider>\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 getQualifiedRowId: GetQualifiedRowIdFn\n search: 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 getQualifiedRowId,\n search,\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),\n [content],\n )\n\n // Determine if deep search is active\n const minLength = deepSearchConfig.minLength ?? 0\n const isDeepSearchActive =\n deepSearchConfig.enabled !== false && search.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 // Compute filtered display nodes and set composite IDs\n const { displayNodes, isDeepSearching } = React.useMemo(() => {\n const result = filterNodes({\n query: search,\n nodes: contentWithRootAsync,\n highlightedId: null, // Primitives handle highlighting via store\n deepSearch: deepSearchConfig.enabled,\n minLength: deepSearchConfig.minLength,\n groupSearchBehavior: deepSearchConfig.groupSearchBehavior,\n radioGroupSearchBehavior: deepSearchConfig.radioGroupSearchBehavior,\n sortGroups: deepSearchConfig.sortGroups,\n })\n // Set composite IDs directly on the freshly created display nodes\n computeItemIds(\n result.displayNodes,\n getQualifiedRowId,\n result.isDeepSearching,\n )\n return result\n }, [search, contentWithRootAsync, deepSearchConfig, getQualifiedRowId])\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\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 prevOrderedItemIdsRef.current = current\n return current\n }\n\n return prev\n }, [newOrderedItemIds])\n\n React.useEffect(() => {\n store.setOrderedItems(orderedItemIds)\n }, [store, orderedItemIds])\n\n // Helper to render a single row node (item, checkbox item, or submenu)\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 submenu children\n const compositeId = displayNode.compositeId ?? node.id ?? node.value\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 },\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 },\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 },\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\n // Get async state for this submenu if it has asyncNodes\n let submenuAsyncState:\n | {\n isLoading: boolean\n isError: boolean\n error: Error | null\n isBelowMinLength?: boolean\n }\n | undefined\n if (node.asyncNodes && coordinator) {\n const asyncResult = coordinator.loaders.get(compositeId)\n if (asyncResult) {\n const isBelowMinLength =\n node.asyncNodes.type === 'query' &&\n search.length < (node.asyncNodes.minQueryLength ?? 1)\n submenuAsyncState = {\n isLoading: asyncResult.result.isLoading,\n isError: asyncResult.result.isError,\n error: asyncResult.result.error,\n isBelowMinLength,\n }\n }\n }\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 =>\n (n.kind === 'item' ||\n n.kind === 'checkbox-item' ||\n n.kind === 'submenu') &&\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, and submenus\n if (\n childNode.kind !== 'item' &&\n childNode.kind !== 'checkbox-item' &&\n childNode.kind !== 'submenu'\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 },\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 return null\n },\n [coordinator, search],\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)\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 isStaticLoading: false,\n isQueryLoading: 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={search} />\n\n {/* Submenu async loaders */}\n {asyncSubmenus.map((info) => (\n <AsyncLoaderRenderer\n key={info.id}\n info={info}\n query={search}\n enabled={\n isDeepSearchActive && shouldIncludeInDeepSearch(info.config)\n }\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 {\n CheckedChangeEventDetails,\n RadioValueChangeEventDetails,\n} from '../events.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 interface AsyncLoaderResult<T> {\n /** The loaded data, undefined while loading or on error */\n data: T | undefined\n /** Error if the load failed, null otherwise */\n error: Error | null\n /** Whether the loader is currently loading */\n isLoading: boolean\n /** Whether the loader encountered an error */\n isError: boolean\n /** Optional function to refetch the data */\n refetch?: () => void\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 /** Render function receiving loader state */\n children: (state: AsyncLoaderResult<NodeDef[]>) => React.ReactNode\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 * Initial query to use when the loader becomes active.\n * Set to '' to fetch all items immediately when the submenu opens.\n * If undefined, waits for user to type before fetching.\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 * Union of all async loader configurations.\n */\nexport type AsyncLoaderConfig = StaticLoaderConfig | QueryDependentLoaderConfig\n\n/**\n * Base options for async nodes that apply to both loader types.\n */\ninterface AsyncNodesBaseOptions {\n /**\n * Include this menu's async content in parent's deep search.\n * - Static loaders: default true (data loaded, filter client-side)\n * - Query loaders: default true (pass query to server)\n */\n includeInDeepSearch?: boolean\n}\n\n/**\n * Static async nodes configuration for submenus.\n */\nexport type StaticAsyncNodesConfig = StaticLoaderConfig & AsyncNodesBaseOptions\n\n/**\n * Query-dependent async nodes configuration for submenus.\n */\nexport type QueryAsyncNodesConfig = QueryDependentLoaderConfig &\n AsyncNodesBaseOptions\n\n/**\n * Async nodes configuration for submenus.\n * Union of static and query-dependent loader configs with deep search options.\n */\nexport type AsyncNodesConfig = StaticAsyncNodesConfig | QueryAsyncNodesConfig\n\n/**\n * Async state exposed to submenu render functions.\n */\nexport interface AsyncRenderState {\n /** Whether the loader is currently loading */\n isLoading: 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 loading */\n isLoading: boolean\n /** Static loaders specifically are loading */\n isStaticLoading: boolean\n /** Query loaders specifically are loading */\n isQueryLoading: boolean\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 * Submenu node info passed in breadcrumbs context.\n * Contains the full submenu definition for maximum flexibility.\n */\nexport interface BreadcrumbNode {\n /** The submenu node definition */\n node: SubmenuDef\n /** The submenu's value */\n value: string\n /** The submenu'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\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 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 and submenu 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 (0-1, higher = better match) */\n score: number\n } | null\n\n /**\n * Full path of submenu nodes from root to this row's parent.\n * Contains the full submenu 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<PopupMenuItemProps, 'closeOnClick' | 'onSelect' | 'shortcut'>\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<PopupMenuRadioItemProps, 'closeOnClick' | 'onSelect' | 'shortcut'>\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\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// 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 (0-1) */\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'\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' | 'disabled' | 'onSelect' | 'closeOnClick' | 'shortcut'\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' | 'disabled' | 'onSelect' | 'closeOnClick' | 'shortcut'\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' | 'disabled' | 'checked' | 'onCheckedChange' | 'closeOnClick'\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<PopupMenuSubmenuTriggerProps, 'keywords' | 'disabled'> {\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 children in deep search.\n * @default true\n */\n deepSearch?: boolean\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 * 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 | 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\n /** Search match score (0-1) */\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\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 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), 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).\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 * 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\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 /** Filter function or false to disable filtering */\n filter?:\n | ((value: string, search: string, keywords?: string[]) => number)\n | false\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","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 ItemDef,\n NodeDef,\n RadioGroupBehavior,\n RadioGroupDef,\n RadioItemDef,\n RowRenderContext,\n ScoredNode,\n SeparatorDef,\n SubmenuDef,\n} from './types.js'\nimport {\n isDisplayGroupNode,\n isDisplayRadioGroupNode,\n isDisplaySeparatorNode,\n} from './types.js'\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// 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 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 submenus (deep search) */\n deep?: boolean\n /** Parent breadcrumb nodes (submenu 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\n /** Breadcrumb nodes (submenu 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 submenus 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 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 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 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') {\n // Always include the submenu trigger itself\n result.push({\n node,\n breadcrumbs,\n group,\n radioGroup,\n })\n\n // If deep search enabled and submenu allows it, include children\n if (deep && node.deepSearch !== false && node.nodes) {\n // Create breadcrumb node for this submenu\n const submenuBreadcrumb: BreadcrumbNode = {\n node,\n value: node.value,\n id: node.id,\n }\n const childBreadcrumbs: BreadcrumbNode[] = [\n ...breadcrumbs,\n submenuBreadcrumb,\n ]\n\n result.push(\n ...flattenNodes(node.nodes, {\n deep,\n breadcrumbs: childBreadcrumbs,\n // Reset group and radio group context when entering a submenu\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): ScoredNode[] {\n if (!query) {\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 score = commandScore(normalizedValue, query, normalizedKeywords)\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\n/**\n * Sorts scored nodes by score (descending).\n */\nexport function sortByScore(nodes: ScoredNode[]): ScoredNode[] {\n return [...nodes].sort((a, b) => b.score - a.score)\n}\n\n/**\n * Partitions nodes: items first, then submenu triggers.\n * This ensures items appear before submenu triggers in search results.\n */\nexport function partitionByKind(nodes: ScoredNode[]): ScoredNode[] {\n const items = nodes.filter(\n (n) =>\n n.node.kind === 'item' ||\n n.node.kind === 'radio-item' ||\n n.node.kind === 'checkbox-item',\n )\n const submenus = nodes.filter((n) => n.node.kind === 'submenu')\n return [...items, ...submenus]\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\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 /** 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 /** 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 nodes,\n highlightedId,\n deepSearch = 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, { deep: shouldDeepSearch })\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)\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 matchingIds = new Set(matchingItems.map((item) => item.node.id))\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: matching items first (by score), then non-matching\n itemsToDisplay.sort((a, b) => b.score - a.score)\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 score\n type SortableNode = { node: DisplayNode; score: number }\n\n const allNodes: SortableNode[] = [\n ...regularDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.context.search?.score ?? 0,\n })),\n ...radioGroupDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.bestScore,\n })),\n ]\n\n allNodes.sort((a, b) => b.score - a.score)\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 nodes,\n highlightedId,\n deepSearch = 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, { deep: shouldDeepSearch })\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)\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 score\n items.sort((a, b) => b.score - a.score)\n\n const bestScore = items[0]?.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: matching items first (by score), then non-matching\n itemsToDisplay.sort((a, b) => b.score - a.score)\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((a, b) => b.score - a.score)\n .map((item) => buildDisplayRowNode(item, query, highlightedId))\n\n // Merge groups, radio groups, and ungrouped items, sorted by best score\n type SortableNode = { node: DisplayNode; score: number }\n\n const allNodes: SortableNode[] = [\n ...groupDisplayNodes.map((g) => ({\n node: g as DisplayNode,\n score: g.bestScore,\n })),\n ...radioGroupDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.bestScore,\n })),\n ...ungroupedDisplayNodes.map((r) => ({\n node: r as DisplayNode,\n score: r.context.search?.score ?? 0,\n })),\n ]\n\n if (sortGroups) {\n allNodes.sort((a, b) => b.score - a.score)\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\n // Browse mode - no query\n // Always preserve groups in browse mode (groupSearchBehavior only affects search)\n if (!query) {\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(options)\n }\n\n return filterNodesFlatten(options)\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, or submenu)\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 submenu for registration with coordinator.\n */\nexport interface AsyncSubmenuInfo {\n /** Unique identifier (uses node value and breadcrumbs) */\n id: string\n /** Breadcrumbs path to this submenu */\n breadcrumbs: string[]\n /** The submenu node definition */\n node: SubmenuDef\n /** The async configuration */\n config: AsyncNodesConfig\n}\n\n/**\n * Collects all async submenus from a node tree.\n * Recursively traverses groups and submenus to find all async configurations.\n */\nexport function collectAsyncSubmenus(\n nodes: NodeDef[],\n breadcrumbs: string[] = [],\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(...collectAsyncSubmenus(node.nodes, breadcrumbs))\n continue\n }\n\n if (node.kind === 'radio-group') {\n if (node.hidden) continue\n // Recurse into radio groups\n result.push(...collectAsyncSubmenus(node.nodes, breadcrumbs))\n continue\n }\n\n if (node.kind === 'submenu') {\n if (node.hidden) continue\n\n // If this submenu has async nodes, add it to the result\n if (node.asyncNodes) {\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 submenu's static nodes\n if (node.nodes) {\n const childBreadcrumbs = [...breadcrumbs, normalizeValue(node.value)]\n result.push(...collectAsyncSubmenus(node.nodes, childBreadcrumbs))\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') {\n const submenuPath = [\n ...currentBreadcrumbs,\n normalizeValue(node.value),\n ].join('.')\n const asyncNodes = asyncMap.get(submenuPath)\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 deep search should include this async config.\n */\nexport function shouldIncludeInDeepSearch(config: AsyncNodesConfig): boolean {\n // Default behavior:\n // - Static loaders: include by default\n // - Query loaders: include by default\n if (config.includeInDeepSearch !== undefined) {\n return config.includeInDeepSearch\n }\n return 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 // Both static and query loaders use explicit loadStrategy\n return config.loadStrategy === 'eager'\n}\n","'use client'\n\nimport * as React from 'react'\nimport { PopupMenuSurface } from '../components/surface/surface.js'\nimport { usePopupMenuContext } from '../contexts/popup-menu-context.js'\nimport { DataSurfaceContext, type DataSurfaceContextValue } from './context.js'\nimport type { DataSurfaceProps, DeepSearchConfig } from './types.js'\nimport { defaultGetQualifiedRowId } from './utils.js'\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 filter,\n search: searchProp,\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 }\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 }\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 listId,\n getQualifiedRowId,\n }),\n [content, asyncContent, deepSearchConfig, listId, getQualifiedRowId],\n )\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 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 {children}\n </PopupMenuSurface>\n </DataSurfaceContext.Provider>\n )\n})\n\nexport namespace PopupMenuDataSurface {\n export interface Props extends PopupMenuDataSurfaceProps {}\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 { useComboboxContext } from '../contexts/combobox-context.js'\nimport { ComboboxClearDataAttributes } from './clear.data-attrs.js'\n\nexport { ComboboxClearDataAttributes }\n\nexport interface ComboboxClearState extends Record<string, unknown> {\n /**\n * Whether the combobox has a value (clear button is actionable).\n */\n hasValue: boolean\n /**\n * Whether the combobox is disabled.\n */\n disabled: boolean\n}\n\nexport interface ComboboxClearProps\n extends ComponentProps<'button', ComboboxClear.State> {\n /**\n * Whether to render the button even when there's no value to clear.\n * @default false\n */\n keepMounted?: boolean\n}\n\n/**\n * A button that clears the selected value(s) when clicked.\n * Renders a `<button>` element.\n */\nexport const ComboboxClear = React.forwardRef<\n HTMLButtonElement,\n ComboboxClear.Props\n>(function ComboboxClear(props, forwardedRef) {\n const {\n keepMounted = false,\n disabled: disabledProp,\n render,\n className,\n style,\n onClick,\n ...rest\n } = props\n\n const comboboxContext = useComboboxContext()\n\n const disabled = disabledProp ?? comboboxContext.disabled\n\n const hasValue = comboboxContext.multiple\n ? comboboxContext.values.length > 0\n : comboboxContext.value !== ''\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n\n if (comboboxContext.multiple) {\n comboboxContext.onValuesChange([])\n } else {\n comboboxContext.onValueChange('')\n }\n\n // Also clear the input value\n comboboxContext.onInputValueChange('')\n },\n [onClick, comboboxContext],\n )\n\n // Prevent pointer down from stealing focus from the input\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent<HTMLButtonElement>) => {\n event.preventDefault()\n },\n [],\n )\n\n const state: ComboboxClear.State = React.useMemo(\n () => ({\n hasValue,\n disabled,\n }),\n [hasValue, disabled],\n )\n\n const element = useRender({\n render,\n ref: forwardedRef,\n state,\n props: {\n ...rest,\n [ComboboxClearDataAttributes.slot]: '',\n type: 'button',\n tabIndex: -1, // Not tabbable - use keyboard shortcuts instead\n 'aria-label': 'Clear selection',\n disabled: disabled || !hasValue,\n className,\n style,\n onClick: handleClick,\n onPointerDown: handlePointerDown,\n },\n enabled: keepMounted || hasValue,\n defaultTagName: 'button',\n })\n\n // Don't render if no value and not keepMounted\n if (!keepMounted && !hasValue) {\n return null\n }\n\n return element\n})\n\nexport namespace ComboboxClear {\n export type State = ComboboxClearState\n export interface Props extends ComboboxClearProps {}\n}\n","/**\n * Data attributes for ComboboxClear component.\n */\nexport const ComboboxClearDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-clear'}\n */\n slot: 'bazzaui-combobox-clear',\n} as const\n","'use client'\n\nimport * as React from 'react'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n// Types matching Base UI's positioning types\nexport type Side = 'top' | 'bottom' | 'left' | 'right'\nexport type Align = 'start' | 'center' | 'end'\n\n/**\n * Layout mode for the combobox popup.\n * - `'floating'` - Standard dropdown positioning below/above the input\n * - `'input-embedded'` - Popup wraps around the input (macOS-style)\n */\nexport type ComboboxLayout = 'floating' | 'input-embedded'\n\n/**\n * Context value for Combobox Positioner.\n * Provides alignment state for coordinating positioning behavior.\n */\nexport interface ComboboxPositionerContextValue {\n /**\n * The layout mode being used.\n * - `'floating'` - Standard dropdown positioning\n * - `'input-embedded'` - Popup wraps around the input\n */\n layout: ComboboxLayout\n\n /**\n * The side of the popup relative to the input.\n */\n side: Side\n\n /**\n * The alignment of the popup.\n */\n align: Align\n\n /**\n * Height of the input element in pixels.\n * Use this to add appropriate padding to the popup.\n */\n inputHeight: number\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst ComboboxPositionerContext =\n React.createContext<ComboboxPositionerContextValue | null>(null)\n\n/**\n * Hook to access the Combobox Positioner context.\n * Returns null if used outside a ComboboxPositioner.\n */\nexport function useComboboxPositionerContext(): ComboboxPositionerContextValue | null {\n return React.useContext(ComboboxPositionerContext)\n}\n\nexport { ComboboxPositionerContext }\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { useFocusOwner } from '../../internal/popup-menu/contexts/focus-owner-context.js'\nimport { usePopupMenuContext } from '../../internal/popup-menu/contexts/popup-menu-context.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useComboboxContext } from '../contexts/combobox-context.js'\nimport { useIsInsideInputWrapper } from '../input-wrapper/input-wrapper-context.js'\nimport { ComboboxInputDataAttributes } from './input.data-attrs.js'\nimport { useComboboxDisplayValue } from './use-combobox-display-value.js'\nimport { useComboboxInputBehavior } from './use-combobox-input-behavior.js'\n\nexport { ComboboxInputDataAttributes }\n\nexport interface ComboboxInputState extends Record<string, unknown> {\n /**\n * Whether the combobox popup is open.\n */\n open: boolean\n /**\n * Whether the input is disabled.\n */\n disabled: boolean\n /**\n * Whether the input currently shows placeholder (no value selected).\n */\n placeholder: boolean\n}\n\n/**\n * Cursor behavior when the combobox popup opens.\n * - `'none'` - Don't move the cursor (cursor appears where clicked)\n * - `'end'` - Move cursor to the end of the input\n * - `'select-all'` - Move cursor to the end and select all text\n */\nexport type ComboboxInputCursorBehavior = 'none' | 'end' | 'select-all'\n\nexport interface ComboboxInputProps\n extends Omit<\n ComponentProps<'input', ComboboxInput.State>,\n 'value' | 'onChange' | 'type'\n > {\n /**\n * Placeholder text shown when no value is selected and input is empty.\n * Overrides the placeholder set on Combobox.Root.\n */\n placeholder?: string\n\n /**\n * Cursor behavior when the combobox popup opens.\n * - `'none'` - Don't move the cursor (cursor appears where clicked)\n * - `'end'` - Move cursor to the end of the input\n * - `'select-all'` - Move cursor to the end and select all text\n *\n * @default 'none'\n */\n cursorBehavior?: ComboboxInputCursorBehavior\n}\n\n/**\n * An input that acts as both the trigger and search field for the combobox.\n * Renders an `<input>` element with combobox ARIA semantics.\n */\nexport const ComboboxInput = React.forwardRef<\n HTMLInputElement,\n ComboboxInput.Props\n>(function ComboboxInput(props, forwardedRef) {\n const {\n placeholder: placeholderProp,\n disabled: disabledProp,\n cursorBehavior = 'none',\n render,\n className,\n style,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n ...rest\n } = props\n\n const comboboxContext = useComboboxContext()\n const popupMenuContext = usePopupMenuContext()\n const focusOwnerStore = useFocusOwner()\n const isInsideInputWrapper = useIsInsideInputWrapper()\n\n const disabled = disabledProp ?? comboboxContext.disabled\n const placeholder = placeholderProp ?? comboboxContext.placeholder\n\n // Get open state\n const open = popupMenuContext.store.useState('open')\n\n // Use display value hook\n const { hasValue, displayValue, getValueText } = useComboboxDisplayValue({\n comboboxContext,\n open,\n })\n\n // Use input behavior hook\n const { handleChange, handleFocus, handleBlur, handleClick, handleKeyDown } =\n useComboboxInputBehavior({\n comboboxContext,\n store: popupMenuContext.store,\n focusOwnerStore,\n open,\n disabled,\n cursorBehavior,\n hasValue,\n getValueText,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n })\n\n // Build data attributes\n const dataAttrs: Record<string, string> = {\n [ComboboxInputDataAttributes.slot]: '',\n }\n if (open) {\n dataAttrs[ComboboxInputDataAttributes.open] = ''\n } else {\n dataAttrs[ComboboxInputDataAttributes.closed] = ''\n }\n if (disabled) {\n dataAttrs[ComboboxInputDataAttributes.disabled] = ''\n }\n if (!hasValue) {\n dataAttrs[ComboboxInputDataAttributes.placeholder] = ''\n }\n // Add input-embedded data attribute when layout is input-embedded\n if (comboboxContext.layout === 'input-embedded') {\n dataAttrs['data-input-embedded'] = ''\n }\n\n // Register input element for positioning\n const mergedRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n comboboxContext.setInputElement(node)\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [forwardedRef, comboboxContext],\n )\n\n const state: ComboboxInput.State = React.useMemo(\n () => ({\n open,\n disabled,\n placeholder: !hasValue,\n }),\n [open, disabled, hasValue],\n )\n\n // When input-embedded layout, apply styles to position input above the popup\n // Skip z-index if inside an InputWrapper (the wrapper handles z-index)\n const inputEmbeddedStyles: React.CSSProperties | undefined =\n comboboxContext.layout === 'input-embedded' && !isInsideInputWrapper\n ? { position: 'relative', zIndex: 1 }\n : undefined\n\n const element = useRender({\n render,\n ref: mergedRef,\n state,\n props: {\n ...rest,\n ...dataAttrs,\n type: 'text',\n role: 'combobox',\n 'aria-autocomplete': 'list',\n 'aria-expanded': open,\n 'aria-controls': comboboxContext.listId,\n 'aria-haspopup': 'listbox',\n autoComplete: 'off',\n autoCorrect: 'off',\n spellCheck: false,\n disabled,\n placeholder: !hasValue ? placeholder : undefined,\n className,\n style: { ...inputEmbeddedStyles, ...style },\n value: displayValue,\n onChange: handleChange,\n onFocus: handleFocus,\n onBlur: handleBlur,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n },\n defaultTagName: 'input',\n })\n\n return element\n})\n\nexport namespace ComboboxInput {\n export interface Props extends ComboboxInputProps {}\n export type State = ComboboxInputState\n}\n","import * as React from 'react'\n\n/**\n * Context to indicate that children are inside an InputWrapper.\n * When true, Input should not apply its own z-index styles for input-embedded layout.\n */\nexport const ComboboxInputWrapperContext = React.createContext<boolean>(false)\n\n/**\n * Hook to check if component is inside a ComboboxInputWrapper.\n */\nexport function useIsInsideInputWrapper(): boolean {\n return React.useContext(ComboboxInputWrapperContext)\n}\n","/**\n * Data attributes for ComboboxInput component.\n */\nexport const ComboboxInputDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-input'}\n */\n slot: 'bazzaui-combobox-input',\n /** Present when the combobox popup is open. */\n open: 'data-open',\n /** Present when the combobox popup is closed. */\n closed: 'data-closed',\n /** Present when the input is disabled. */\n disabled: 'data-disabled',\n /** Present when no value is selected (showing placeholder). */\n placeholder: 'data-placeholder',\n} as const\n","'use client'\n\nimport * as React from 'react'\nimport {\n resolveLabel,\n stringifyAsValue,\n} from '../../utils/resolve-value-label.js'\nimport type { ComboboxContextValue } from '../contexts/combobox-context.js'\n\n/**\n * Helper to resolve label from items prop\n */\nfunction resolveLabelFromItems(\n items:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n | undefined,\n value: string,\n): string | undefined {\n if (!items) return undefined\n\n if (Array.isArray(items)) {\n const item = items.find((i) => i.value === value)\n const label = item?.label\n return typeof label === 'string' ? label : undefined\n }\n\n const label = items[value]\n return typeof label === 'string' ? label : undefined\n}\n\nexport interface UseComboboxDisplayValueParams<Value = unknown> {\n comboboxContext: ComboboxContextValue<Value>\n open: boolean\n}\n\nexport interface UseComboboxDisplayValueReturn<Value = unknown> {\n /** Whether a value is selected */\n hasValue: boolean\n /** The value to display in the input */\n displayValue: string\n /** The label of the selected value(s) */\n selectedLabel: string\n /** Get the display text for a value */\n getValueText: (value: Value) => string | undefined\n}\n\n/**\n * Hook to compute the display value for the combobox input.\n *\n * Handles:\n * - Determining if a value is selected (single or multi-select)\n * - Computing the display label for selected values\n * - Switching between selected label (closed) and input value (open)\n */\nexport function useComboboxDisplayValue<Value = unknown>(\n params: UseComboboxDisplayValueParams<Value>,\n): UseComboboxDisplayValueReturn<Value> {\n const { comboboxContext, open } = params\n\n // Determine if showing placeholder (no value selected)\n const hasValue = comboboxContext.multiple\n ? comboboxContext.values.length > 0\n : comboboxContext.value != null\n\n // Get the display text for selected value\n const getValueText = React.useCallback(\n (value: Value): string | undefined => {\n // Serialize for registry lookup\n const serializedValue = stringifyAsValue(\n value,\n comboboxContext.itemToStringValue,\n )\n\n // First try the registry (populated when items mount)\n const registryText = comboboxContext.itemTextRegistry.get(serializedValue)\n if (registryText !== undefined) {\n return registryText\n }\n\n // Fall back to the items prop (for initial render before popup opens)\n const itemsLabel = resolveLabelFromItems(\n comboboxContext.items,\n serializedValue,\n )\n if (itemsLabel !== undefined) {\n return itemsLabel\n }\n\n // Fall back to itemToStringLabel for object values\n const resolvedLabel = resolveLabel(\n value,\n comboboxContext.itemToStringLabel,\n )\n // Only return if it's different from the serialized value (meaning we got a real label)\n if (resolvedLabel && resolvedLabel !== serializedValue) {\n return resolvedLabel\n }\n\n return undefined\n },\n [\n comboboxContext.itemTextRegistry,\n comboboxContext.items,\n comboboxContext.itemToStringLabel,\n comboboxContext.itemToStringValue,\n ],\n )\n\n // Get the label for the selected value (used when closed or just opened)\n const selectedLabel = React.useMemo(() => {\n if (!hasValue) {\n return ''\n }\n if (comboboxContext.multiple) {\n // For multi-select, show comma-separated values or count\n const texts = comboboxContext.values\n .map((v) => {\n const text = getValueText(v)\n if (text !== undefined) return text\n // Fall back to resolved label or serialized value\n return (\n resolveLabel(v, comboboxContext.itemToStringLabel) ||\n stringifyAsValue(v, comboboxContext.itemToStringValue)\n )\n })\n .filter(Boolean)\n if (texts.length <= 2) {\n return texts.join(', ')\n }\n return `${texts.length} selected`\n }\n // Single-select: show the value's text\n const value = comboboxContext.value\n if (value == null) return ''\n\n const text = getValueText(value)\n if (text !== undefined) return text\n // Fall back to resolved label or serialized value\n return (\n resolveLabel(value, comboboxContext.itemToStringLabel) ||\n stringifyAsValue(value, comboboxContext.itemToStringValue)\n )\n }, [\n hasValue,\n comboboxContext.multiple,\n comboboxContext.value,\n comboboxContext.values,\n comboboxContext.itemToStringLabel,\n comboboxContext.itemToStringValue,\n getValueText,\n ])\n\n // Determine the display value for the input\n // When closed: show selected value's text\n // When open: show the search/filter text (inputValue)\n const displayValue = React.useMemo(() => {\n if (!open) {\n // When closed, show the selected value's label\n return selectedLabel\n }\n // When open, use the input value for filtering\n return comboboxContext.inputValue\n }, [open, selectedLabel, comboboxContext.inputValue])\n\n return {\n hasValue,\n displayValue,\n selectedLabel,\n getValueText,\n }\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ListboxStore } from '../../internal/listbox/index.js'\nimport { usePopupMenuKeyboard } from '../../internal/popup-menu/hooks/use-popup-menu-keyboard.js'\nimport type { FocusOwnerStore } from '../../internal/popup-menu/store/FocusOwnerStore.js'\nimport { REASONS } from '../../utils/events/index.js'\nimport { resolveLabel } from '../../utils/resolve-value-label.js'\nimport type { ComboboxContextValue } from '../contexts/combobox-context.js'\nimport type { ComboboxInputCursorBehavior } from './input.js'\n\nexport interface UseComboboxInputBehaviorParams {\n comboboxContext: ComboboxContextValue\n store: ListboxStore\n focusOwnerStore: FocusOwnerStore\n open: boolean\n disabled: boolean\n cursorBehavior: ComboboxInputCursorBehavior\n hasValue: boolean\n /** Get display text for a value - receives the raw value (possibly an object) */\n getValueText: (value: unknown) => string | undefined\n // User event handlers to chain\n onFocus?: React.FocusEventHandler<HTMLInputElement>\n onBlur?: React.FocusEventHandler<HTMLInputElement>\n onClick?: React.MouseEventHandler<HTMLInputElement>\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>\n}\n\nexport interface UseComboboxInputBehaviorReturn {\n handleChange: React.ChangeEventHandler<HTMLInputElement>\n handleFocus: React.FocusEventHandler<HTMLInputElement>\n handleBlur: React.FocusEventHandler<HTMLInputElement>\n handleClick: React.MouseEventHandler<HTMLInputElement>\n handleKeyDown: React.KeyboardEventHandler<HTMLInputElement>\n /** Ref to track selection for controlled input restoration */\n selectionRef: React.MutableRefObject<{ start: number; end: number } | null>\n}\n\n/**\n * Hook to manage combobox input behavior including:\n * - Cursor positioning on open (cursorBehavior prop)\n * - Selection preservation for controlled inputs\n * - Focus/blur handling with popup awareness\n * - Click handling to open popup\n * - Keyboard navigation integration\n */\nexport function useComboboxInputBehavior(\n params: UseComboboxInputBehaviorParams,\n): UseComboboxInputBehaviorReturn {\n const {\n comboboxContext,\n store,\n focusOwnerStore,\n open,\n disabled,\n cursorBehavior,\n hasValue,\n getValueText,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n } = params\n\n // Track if open was triggered by typing (to avoid overwriting typed character)\n const openedByTypingRef = React.useRef(false)\n\n // Track if open was triggered by click (to restore cursor position)\n const openedByClickRef = React.useRef(false)\n\n // Track if input was already focused when opening (skip cursor behavior if so)\n const wasAlreadyFocusedRef = React.useRef(false)\n\n // Track the click cursor position to restore after value changes\n const clickCursorPositionRef = React.useRef<number | null>(null)\n\n // Track the last selection to restore after controlled value updates\n const selectionRef = React.useRef<{ start: number; end: number } | null>(null)\n\n // Track if blur was caused by a pointer event (to distinguish outside-press from focus-out)\n // Also store the event itself so we can pass it to the close handler\n const outsidePointerEventRef = React.useRef<PointerEvent | null>(null)\n\n // Listen for pointerdown on document to detect outside clicks\n React.useEffect(() => {\n if (!open) return\n\n const handlePointerDown = (event: PointerEvent) => {\n const input = comboboxContext.inputRef.current\n const inputWrapper = comboboxContext.inputWrapperRef.current\n const listbox = document.getElementById(comboboxContext.listId)\n\n const target = event.target as Node\n\n // Check if click is inside the input, wrapper, or listbox\n const isInsideInput = input?.contains(target)\n const isInsideWrapper = inputWrapper?.contains(target)\n const isInsideListbox = listbox?.contains(target)\n\n if (!isInsideInput && !isInsideWrapper && !isInsideListbox) {\n // Pointer down outside - store the event for blur handler\n outsidePointerEventRef.current = event\n }\n }\n\n // Use capture phase so we see the event before stopPropagation can block it\n document.addEventListener('pointerdown', handlePointerDown, true)\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown, true)\n outsidePointerEventRef.current = null\n }\n }, [\n open,\n comboboxContext.inputRef,\n comboboxContext.inputWrapperRef,\n comboboxContext.listId,\n ])\n\n // Restore selection after React re-renders the controlled input\n React.useLayoutEffect(() => {\n const inputElement = comboboxContext.inputRef.current\n if (inputElement && open && selectionRef.current) {\n const { start, end } = selectionRef.current\n // Only restore if the current selection is at the end (React's default reset position)\n // This avoids interfering with intentional cursor movements\n const currentPos = inputElement.selectionStart\n const valueLen = inputElement.value.length\n if (currentPos === valueLen && start !== valueLen) {\n inputElement.setSelectionRange(start, end)\n }\n selectionRef.current = null\n }\n })\n\n // When opening, apply cursor behavior based on how the combobox was opened\n const prevOpenRef = React.useRef(open)\n React.useLayoutEffect(() => {\n if (open && !prevOpenRef.current) {\n // If opened by typing, don't overwrite the typed character\n if (openedByTypingRef.current) {\n openedByTypingRef.current = false\n prevOpenRef.current = open\n return\n }\n\n // If input was already focused, skip cursor behavior entirely\n // Let the browser handle cursor positioning naturally\n if (wasAlreadyFocusedRef.current) {\n wasAlreadyFocusedRef.current = false\n openedByClickRef.current = false\n clickCursorPositionRef.current = null\n prevOpenRef.current = open\n return\n }\n\n // If opened by click with cursorBehavior='none', restore cursor to click position\n if (openedByClickRef.current && cursorBehavior === 'none') {\n const inputElement = comboboxContext.inputRef.current\n const clickPos = clickCursorPositionRef.current\n\n if (inputElement && clickPos !== null) {\n // Use requestAnimationFrame to ensure DOM has updated\n requestAnimationFrame(() => {\n // Clamp position to the current value length (in case text changed)\n const maxPos = inputElement.value.length\n const safePos = Math.min(clickPos, maxPos)\n inputElement.setSelectionRange(safePos, safePos)\n })\n }\n\n openedByClickRef.current = false\n clickCursorPositionRef.current = null\n prevOpenRef.current = open\n return\n }\n\n // For multi-select, clear input for fresh search\n if (hasValue && comboboxContext.multiple) {\n comboboxContext.onInputValueChange('')\n }\n\n // Apply cursor behavior based on prop (only when initially opening from unfocused state)\n // Note: The input value is already set by the click/focus/keyboard handlers\n const inputElement = comboboxContext.inputRef.current\n if (inputElement) {\n const valueLength = inputElement.value.length\n\n if (cursorBehavior === 'select-all' && valueLength > 0) {\n // Use requestAnimationFrame to ensure the value has been applied\n requestAnimationFrame(() => {\n inputElement.setSelectionRange(0, inputElement.value.length)\n })\n } else if (cursorBehavior === 'end' && valueLength > 0) {\n requestAnimationFrame(() => {\n inputElement.setSelectionRange(\n inputElement.value.length,\n inputElement.value.length,\n )\n })\n }\n // For cursorBehavior='none' without click tracking (e.g., focus/keyboard open),\n // cursor naturally goes to end which is acceptable\n }\n }\n prevOpenRef.current = open\n }, [open, comboboxContext, hasValue, cursorBehavior])\n\n // Handle input change\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const inputElement = event.target\n const newValue = inputElement.value\n\n // Save selection position to restore after React re-render\n const start = inputElement.selectionStart\n const end = inputElement.selectionEnd\n if (start !== null && end !== null) {\n selectionRef.current = { start, end }\n }\n\n comboboxContext.onInputValueChange(newValue)\n\n // Set filter mode to active (normal filtering using inputValue)\n comboboxContext.setFilterActive()\n\n // Also update the store's search state for filtering\n store.setSearch(newValue)\n\n // Open the combobox if not already open\n if (!store.state.open) {\n // Mark that we're opening by typing so the effect doesn't overwrite the value\n openedByTypingRef.current = true\n comboboxContext.openCombobox()\n }\n },\n [comboboxContext, store],\n )\n\n // Handle focus\n const handleFocus = React.useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n onFocus?.(event)\n if (event.defaultPrevented) return\n\n const isOpen = store.state.open\n\n // If popup is already open, input is getting focus while open\n // Mark as already focused so click handler knows not to apply cursorBehavior\n if (isOpen) {\n wasAlreadyFocusedRef.current = true\n }\n\n if (comboboxContext.openOnFocus && !disabled && !isOpen) {\n // Pre-set the input value BEFORE opening to avoid the empty intermediate state\n if (hasValue && !comboboxContext.multiple) {\n const labelValue =\n getValueText(comboboxContext.value) ??\n resolveLabel(\n comboboxContext.value,\n comboboxContext.itemToStringLabel,\n )\n comboboxContext.onInputValueChange(labelValue)\n }\n comboboxContext.openCombobox()\n }\n },\n [onFocus, comboboxContext, disabled, store, hasValue, getValueText],\n )\n\n // Handle blur - close combobox when focus moves outside\n const handleBlur = React.useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n onBlur?.(event)\n if (event.defaultPrevented) return\n\n // Use requestAnimationFrame to check where focus moved to\n // This allows the click on an item to complete before we check\n requestAnimationFrame(() => {\n const activeElement = document.activeElement\n\n // Check if focus moved to something inside the popup\n // The popup is rendered in a portal, so we need to check if the active element\n // is inside any element with role=\"listbox\" that belongs to this combobox\n const listbox = document.getElementById(comboboxContext.listId)\n const isInsideListbox = listbox?.contains(activeElement)\n\n // Also check if focus is still on the input itself\n const isOnInput = activeElement === comboboxContext.inputRef.current\n\n if (!isInsideListbox && !isOnInput) {\n // Reset the \"already focused\" flag when closing\n wasAlreadyFocusedRef.current = false\n // Use outside-press if blur was caused by a pointer event, otherwise focus-out\n const pointerEvent = outsidePointerEventRef.current\n const reason = pointerEvent ? REASONS.outsidePress : REASONS.focusOut\n outsidePointerEventRef.current = null\n comboboxContext.closeCombobox(reason, pointerEvent ?? undefined)\n }\n })\n },\n [onBlur, comboboxContext],\n )\n\n // Handle click\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLInputElement>) => {\n onClick?.(event)\n if (event.defaultPrevented) return\n\n const isOpen = store.state.open\n\n if (!disabled && !isOpen) {\n const inputElement = event.target as HTMLInputElement\n\n // Capture cursor position before opening (for cursorBehavior='none')\n if (cursorBehavior === 'none') {\n // The browser has already calculated the click position based on current text\n const clickPosition = inputElement.selectionStart\n clickCursorPositionRef.current = clickPosition\n openedByClickRef.current = true\n }\n\n // Pre-set the input value BEFORE opening to avoid the empty intermediate state\n // This prevents the flash where displayValue goes from \"Banana\" -> \"\" -> \"Banana\"\n if (hasValue && !comboboxContext.multiple) {\n const labelValue =\n getValueText(comboboxContext.value) ??\n resolveLabel(\n comboboxContext.value,\n comboboxContext.itemToStringLabel,\n )\n comboboxContext.onInputValueChange(labelValue)\n }\n\n comboboxContext.openCombobox()\n } else if (isOpen) {\n // Clicking while already open - mark as already focused\n // This will prevent cursorBehavior from being applied if popup re-opens\n wasAlreadyFocusedRef.current = true\n }\n },\n [\n onClick,\n comboboxContext,\n disabled,\n store,\n cursorBehavior,\n hasValue,\n getValueText,\n ],\n )\n\n // Handle keyboard when popup is closed (opening it) or Escape to close\n const handleKeyDownWhenClosed = React.useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Let user handler run first\n onKeyDown?.(event)\n if (event.defaultPrevented) return\n\n // Handle Escape to close popup (input stays focused)\n if (open && event.key === 'Escape') {\n event.preventDefault()\n comboboxContext.closeCombobox(REASONS.escapeKey)\n return\n }\n\n // If popup is closed, open it on arrow keys or Enter\n if (!open) {\n if (\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp' ||\n event.key === 'Enter'\n ) {\n event.preventDefault()\n // Pre-set the input value BEFORE opening to avoid the empty intermediate state\n if (hasValue && !comboboxContext.multiple) {\n const labelValue =\n getValueText(comboboxContext.value) ??\n resolveLabel(\n comboboxContext.value,\n comboboxContext.itemToStringLabel,\n )\n comboboxContext.onInputValueChange(labelValue)\n }\n comboboxContext.openCombobox()\n return\n }\n }\n },\n [open, comboboxContext, onKeyDown, hasValue, getValueText],\n )\n\n // Use centralized keyboard navigation hook for when popup is open\n // This handles Enter to select, arrow keys for navigation, Escape to close, etc.\n const { handleKeyDown: handleKeyDownFromHook } = usePopupMenuKeyboard({\n store,\n surfaceId: 'combobox-input', // Input acts as a virtual surface for keyboard handling\n focusOwnerStore,\n depth: 0,\n submenuContext: null,\n enabled: open, // Only enabled when popup is open\n enableTypeToSearch: false,\n onKeyDown: handleKeyDownWhenClosed, // Chain with our closed-state handler\n closeAll: comboboxContext.closeCombobox,\n // Skip focus owner check because the input is outside the Surface\n // but should still handle keyboard navigation when the popup is open\n skipFocusOwnerCheck: true,\n })\n\n return {\n handleChange,\n handleFocus,\n handleBlur,\n handleClick,\n handleKeyDown: handleKeyDownFromHook,\n selectionRef,\n }\n}\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { usePopupMenuContext } from '../../internal/popup-menu/contexts/popup-menu-context.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useComboboxContext } from '../contexts/combobox-context.js'\nimport { ComboboxInputWrapperDataAttributes } from './input-wrapper.data-attrs.js'\nimport { ComboboxInputWrapperContext } from './input-wrapper-context.js'\n\nexport { ComboboxInputWrapperDataAttributes }\n\nexport interface ComboboxInputWrapperState extends Record<string, unknown> {\n /**\n * Whether the combobox popup is open.\n */\n open: boolean\n}\n\nexport interface ComboboxInputWrapperProps\n extends ComponentProps<'div', ComboboxInputWrapper.State> {}\n\nconst stateAttributesMapping = {\n open: (value: unknown): Record<string, string> | null =>\n value ? { [ComboboxInputWrapperDataAttributes.open]: '' } : null,\n}\n\n/**\n * A wrapper component for the Combobox.Input and Combobox.Icon.\n * Provides relative positioning context and manages z-index for input-embedded layouts.\n * Use this to position icons or other elements inside/over the input.\n *\n * Renders a `<div>` element with `position: relative`.\n */\nexport const ComboboxInputWrapper = React.forwardRef<\n HTMLDivElement,\n ComboboxInputWrapper.Props\n>(function ComboboxInputWrapper(props, forwardedRef) {\n const { render, className, style, children, ...rest } = props\n\n const { store } = usePopupMenuContext()\n const comboboxContext = useComboboxContext()\n const open = store.useState('open')\n\n const state: ComboboxInputWrapper.State = React.useMemo(\n () => ({ open }),\n [open],\n )\n\n // When input-embedded layout, apply higher z-index to ensure\n // the wrapper (and its children like Icon) appear above the popup\n const inputEmbeddedStyles: React.CSSProperties =\n comboboxContext.layout === 'input-embedded'\n ? { position: 'relative', zIndex: 1 }\n : { position: 'relative' }\n\n // Register wrapper element for positioning (used as anchor instead of input)\n const mergedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n comboboxContext.setInputWrapperElement(node)\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [forwardedRef, comboboxContext],\n )\n\n const element = useRender({\n render,\n ref: mergedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n [ComboboxInputWrapperDataAttributes.slot]: '',\n className,\n style: { ...inputEmbeddedStyles, ...style },\n children,\n },\n defaultTagName: 'div',\n })\n\n return (\n <ComboboxInputWrapperContext.Provider value={true}>\n {element}\n </ComboboxInputWrapperContext.Provider>\n )\n})\n\nexport namespace ComboboxInputWrapper {\n export type State = ComboboxInputWrapperState\n export interface Props extends ComboboxInputWrapperProps {}\n}\n","/**\n * Data attributes for ComboboxInputWrapper component.\n */\nexport const ComboboxInputWrapperDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-input-wrapper'}\n */\n slot: 'bazzaui-combobox-input-wrapper',\n /** Present when the combobox popup is open. */\n open: 'data-open',\n} as const\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { usePopupMenuItem } from '../../internal/popup-menu/index.js'\nimport {\n compareItemEquality,\n itemIncludes,\n removeItem,\n} from '../../utils/item-equality.js'\nimport {\n resolveLabel,\n stringifyAsValue,\n} from '../../utils/resolve-value-label.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useComboboxContext } from '../contexts/combobox-context.js'\nimport { ComboboxItemDataAttributes } from './item.data-attrs.js'\nimport {\n ComboboxItemContext,\n type ComboboxItemContextValue,\n} from './item-context.js'\n\nexport { ComboboxItemDataAttributes }\n\nexport interface ComboboxItemState 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.\n */\n selected: boolean\n}\n\nexport interface ComboboxItemProps<Value = unknown>\n extends ComponentProps<'div', ComboboxItem.State> {\n /**\n * The value of this item. Required and must be unique within the Combobox.\n * Can be a primitive or an object.\n */\n value: Value\n\n /**\n * Text value to use for display in the input when this item is selected.\n * If not provided, the text content of the item will be used.\n * For object values, this can be auto-detected from `{ label }` shape.\n */\n textValue?: 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.\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\nconst stateAttributesMapping = {\n highlighted: (value: unknown): Record<string, string> | null =>\n value ? { [ComboboxItemDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [ComboboxItemDataAttributes.disabled]: '' } : null,\n selected: (value: unknown): Record<string, string> | null =>\n value ? { [ComboboxItemDataAttributes.selected]: '' } : null,\n}\n\n/**\n * Helper to resolve label from items prop (for legacy string-keyed items)\n */\nfunction resolveLabelFromItems(\n items:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n | undefined,\n value: string,\n): React.ReactNode | undefined {\n if (!items) return undefined\n\n if (Array.isArray(items)) {\n const item = items.find((i) => i.value === value)\n return item?.label\n }\n\n return items[value]\n}\n\n/**\n * A selectable item in the combobox dropdown.\n * Renders a `<div>` element with role=\"option\".\n *\n * @template Value - The type of the item value (can be a primitive or object)\n */\nfunction ComboboxItemImpl<Value = unknown>(\n props: ComboboxItemProps<Value>,\n forwardedRef: React.ForwardedRef<HTMLDivElement>,\n) {\n const {\n value,\n textValue: textValueProp,\n keywords: keywordsProp,\n disabled = false,\n onSelect,\n forceMount = false,\n render,\n className,\n style,\n onClick,\n onPointerDown,\n onPointerMove,\n children,\n ...rest\n } = props\n\n const comboboxContext = useComboboxContext<Value>()\n\n // Serialize value for registry key and internal lookups\n const serializedValue = React.useMemo(\n () => stringifyAsValue(value, comboboxContext.itemToStringValue),\n [value, comboboxContext.itemToStringValue],\n )\n\n // Resolve label from items prop (for auto-populating textValue and keywords)\n // This works for legacy string-keyed items\n const labelFromItems = React.useMemo(\n () => resolveLabelFromItems(comboboxContext.items, serializedValue),\n [comboboxContext.items, serializedValue],\n )\n\n // Auto-resolve label from object value shape { label }\n const labelFromObjectValue = React.useMemo(\n () => resolveLabel(value, comboboxContext.itemToStringLabel),\n [value, comboboxContext.itemToStringLabel],\n )\n\n // Auto-populate textValue: explicit prop > label from items (if string) > label from object > undefined\n const textValue = React.useMemo(() => {\n if (textValueProp !== undefined) return textValueProp\n if (typeof labelFromItems === 'string') return labelFromItems\n // For object values, use the resolved label\n if (labelFromObjectValue && labelFromObjectValue !== serializedValue) {\n return labelFromObjectValue\n }\n return undefined\n }, [textValueProp, labelFromItems, labelFromObjectValue, serializedValue])\n\n // Auto-add label to keywords for search/filter\n const keywords = React.useMemo(() => {\n const labelStr =\n typeof labelFromItems === 'string'\n ? labelFromItems\n : labelFromObjectValue && labelFromObjectValue !== serializedValue\n ? labelFromObjectValue\n : undefined\n if (!labelStr) return keywordsProp\n if (!keywordsProp) return [labelStr]\n // Only add if not already included\n if (keywordsProp.includes(labelStr)) return keywordsProp\n return [...keywordsProp, labelStr]\n }, [keywordsProp, labelFromItems, labelFromObjectValue, serializedValue])\n\n const textRef = React.useRef<string | undefined>(textValue)\n\n // Track if this item is selected using custom equality\n const selected = comboboxContext.multiple\n ? itemIncludes(\n comboboxContext.values,\n value,\n comboboxContext.isItemEqualToValue,\n )\n : comboboxContext.value != null &&\n compareItemEquality(\n comboboxContext.value,\n value,\n comboboxContext.isItemEqualToValue,\n )\n\n // Determine close behavior based on context setting\n const closeOnClick = comboboxContext.closeOnSelect\n\n const item = usePopupMenuItem({\n value: serializedValue,\n keywords,\n disabled,\n forceMount,\n closeOnClick,\n children,\n })\n\n // Register the select handler that updates the value\n React.useEffect(() => {\n const handleSelect = () => {\n if (disabled) return\n\n if (comboboxContext.multiple) {\n // Toggle value in array using custom equality\n const newValues = selected\n ? removeItem(\n comboboxContext.values,\n value,\n comboboxContext.isItemEqualToValue,\n )\n : [...comboboxContext.values, value]\n comboboxContext.onValuesChange(newValues)\n } else {\n // Set single value\n comboboxContext.onValueChange(value)\n }\n\n onSelect?.()\n }\n return item.registerSelect(handleSelect)\n }, [disabled, comboboxContext, value, selected, onSelect, item])\n\n // Register item text for input display\n React.useEffect(() => {\n // Use textValue if provided, otherwise extract from children\n const text = textRef.current\n if (text) {\n return comboboxContext.registerItemText(serializedValue, text)\n }\n }, [serializedValue, comboboxContext])\n\n // Update text ref when children might have changed (for extraction)\n React.useEffect(() => {\n if (!textValue && typeof children === 'string') {\n textRef.current = children\n comboboxContext.registerItemText(serializedValue, children)\n }\n }, [children, textValue, serializedValue, comboboxContext])\n\n const state: ComboboxItem.State = React.useMemo(\n () => ({\n highlighted: item.isHighlighted,\n disabled,\n selected,\n }),\n [item.isHighlighted, disabled, selected],\n )\n\n const itemContextValue: ComboboxItemContextValue<Value> = React.useMemo(\n () => ({\n id: item.id,\n value,\n textValue,\n highlighted: item.isHighlighted,\n disabled,\n selected,\n }),\n [item.id, value, textValue, item.isHighlighted, disabled, selected],\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 const element = useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n [ComboboxItemDataAttributes.slot]: '',\n id: item.id,\n role: 'option',\n tabIndex: -1,\n 'aria-selected': selected,\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 <ComboboxItemContext.Provider\n value={itemContextValue as ComboboxItemContextValue}\n >\n {element}\n </ComboboxItemContext.Provider>\n )\n}\n\nexport const ComboboxItem = React.forwardRef(ComboboxItemImpl) as <\n Value = unknown,\n>(\n props: ComboboxItemProps<Value> & React.RefAttributes<HTMLDivElement>,\n) => React.ReactElement | null\n\nexport namespace ComboboxItem {\n export type State = ComboboxItemState\n export interface Props<Value = unknown> extends ComboboxItemProps<Value> {}\n}\n","/**\n * Type for custom item equality comparison functions.\n * Used to compare object values in Select and Combobox components.\n */\nexport type ItemEqualityComparer<Value = unknown> = (\n itemValue: Value,\n value: Value,\n) => boolean\n\n/**\n * Default equality comparer using Object.is.\n * Handles primitives and object reference equality.\n */\nexport const defaultItemEquality: ItemEqualityComparer = (item, value) =>\n Object.is(item, value)\n\n/**\n * Compare two items for equality using a custom comparer.\n * Handles null/undefined values separately using Object.is.\n */\nexport function compareItemEquality<Value>(\n item: Value,\n value: Value,\n comparer: ItemEqualityComparer<Value>,\n): boolean {\n // Handle null/undefined with Object.is for consistent behavior\n if (item == null || value == null) {\n return Object.is(item, value)\n }\n return comparer(item, value)\n}\n\n/**\n * Check if a collection includes a specific value using custom equality.\n */\nexport function itemIncludes<Value>(\n collection: readonly Value[] | undefined | null,\n value: Value,\n comparer: ItemEqualityComparer<Value>,\n): boolean {\n if (!collection || collection.length === 0) {\n return false\n }\n return collection.some((item) => {\n if (item === undefined) {\n return false\n }\n return compareItemEquality(item, value, comparer)\n })\n}\n\n/**\n * Find the index of a value in a collection using custom equality.\n * Returns -1 if not found.\n */\nexport function findItemIndex<Value>(\n collection: readonly Value[] | undefined | null,\n value: Value,\n comparer: ItemEqualityComparer<Value>,\n): number {\n if (!collection || collection.length === 0) {\n return -1\n }\n return collection.findIndex((item) => {\n if (item === undefined) {\n return false\n }\n return compareItemEquality(item, value, comparer)\n })\n}\n\n/**\n * Remove a value from a collection using custom equality.\n * Returns a new array without the matching item.\n */\nexport function removeItem<Value>(\n collection: readonly Value[],\n value: Value,\n comparer: ItemEqualityComparer<Value>,\n): Value[] {\n return collection.filter(\n (item) => !compareItemEquality(item, value, comparer),\n )\n}\n","/**\n * Data attributes applied to Combobox.Item for styling.\n *\n * @example\n * ```css\n * [data-bazzaui-combobox-item][data-highlighted] {\n * background: var(--highlight-bg);\n * }\n * [data-bazzaui-combobox-item][data-selected] {\n * font-weight: bold;\n * }\n * [data-bazzaui-combobox-item][data-disabled] {\n * opacity: 0.5;\n * pointer-events: none;\n * }\n * ```\n */\nexport const ComboboxItemDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-item'}\n */\n slot: 'bazzaui-combobox-item',\n /** Present when the item is highlighted (via keyboard or pointer). */\n highlighted: 'data-highlighted',\n /** Present when the item is disabled. */\n disabled: 'data-disabled',\n /** Present when the item is currently selected. */\n selected: 'data-selected',\n} as const\n","'use client'\n\nimport * as React from 'react'\n\n/**\n * Context value for ComboboxItem.\n * Provides item state to child components like ItemIndicator.\n *\n * @template Value - The type of the item value (can be a primitive or object)\n */\nexport interface ComboboxItemContextValue<Value = unknown> {\n /** Unique ID for the item element */\n id: string\n /** The item's value */\n value: Value\n /** The text value/label for this item */\n textValue: string | undefined\n /** Whether the item is highlighted (via keyboard or pointer) */\n highlighted: boolean\n /** Whether the item is disabled */\n disabled: boolean\n /** Whether the item is selected */\n selected: boolean\n}\n\nconst ComboboxItemContext =\n React.createContext<ComboboxItemContextValue | null>(null)\n\n/**\n * Hook to access the ComboboxItem context.\n * Throws if used outside a ComboboxItem.\n */\nexport function useComboboxItemContext<\n Value = unknown,\n>(): ComboboxItemContextValue<Value> {\n const context = React.useContext(ComboboxItemContext)\n if (!context) {\n throw new Error(\n 'ComboboxItem child components must be used within a Combobox.Item',\n )\n }\n return context as ComboboxItemContextValue<Value>\n}\n\n/**\n * Hook to optionally access the ComboboxItem context.\n * Returns null if used outside a ComboboxItem.\n */\nexport function useMaybeComboboxItemContext<\n Value = unknown,\n>(): ComboboxItemContextValue<Value> | null {\n return React.useContext(\n ComboboxItemContext,\n ) as ComboboxItemContextValue<Value> | null\n}\n\nexport { ComboboxItemContext }\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 { useComboboxItemContext } from '../item/item-context.js'\nimport { ComboboxItemIndicatorDataAttributes } from './item-indicator.data-attrs.js'\n\nexport { ComboboxItemIndicatorDataAttributes }\n\nexport interface ComboboxItemIndicatorState extends Record<string, unknown> {\n /**\n * Whether the parent item is selected.\n */\n selected: boolean\n}\n\nexport interface ComboboxItemIndicatorProps\n extends ComponentProps<'span', ComboboxItemIndicator.State> {\n /**\n * Whether to always render the indicator regardless of selection state.\n * When false (default), only renders when the item is selected.\n * @default false\n */\n keepMounted?: boolean\n}\n\nconst stateAttributesMapping = {\n selected: (value: unknown): Record<string, string> | null =>\n value ? { [ComboboxItemIndicatorDataAttributes.selected]: '' } : null,\n}\n\n/**\n * Visual indicator for the selected state of a combobox item.\n * Only renders when the parent item is selected (unless keepMounted is true).\n * Renders a `<span>` element.\n */\nexport const ComboboxItemIndicator = React.forwardRef<\n HTMLSpanElement,\n ComboboxItemIndicator.Props\n>(function ComboboxItemIndicator(props, forwardedRef) {\n const { keepMounted = false, render, className, style, ...rest } = props\n\n const itemContext = useComboboxItemContext()\n\n const state: ComboboxItemIndicator.State = React.useMemo(\n () => ({\n selected: itemContext.selected,\n }),\n [itemContext.selected],\n )\n\n const element = useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n [ComboboxItemIndicatorDataAttributes.slot]: '',\n 'aria-hidden': true,\n className,\n style,\n },\n enabled: keepMounted || itemContext.selected,\n defaultTagName: 'span',\n })\n\n // Don't render if not selected and not keepMounted\n if (!keepMounted && !itemContext.selected) {\n return null\n }\n\n return element\n})\n\nexport namespace ComboboxItemIndicator {\n export type State = ComboboxItemIndicatorState\n export interface Props extends ComboboxItemIndicatorProps {}\n}\n","/**\n * Data attributes for ComboboxItemIndicator component.\n */\nexport const ComboboxItemIndicatorDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-item-indicator'}\n */\n slot: 'bazzaui-combobox-item-indicator',\n /** Present when the item is selected. */\n selected: 'data-selected',\n} as const\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { stringifyAsValue } from '../../utils/resolve-value-label.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useComboboxContext } from '../contexts/combobox-context.js'\nimport { useComboboxItemContext } from '../item/item-context.js'\nimport { ComboboxItemLabelDataAttributes } from './item-label.data-attrs.js'\n\nexport { ComboboxItemLabelDataAttributes }\n\nexport interface ComboboxItemLabelState extends Record<string, unknown> {\n /**\n * The serialized string key for the parent item's value.\n * For object values, this is the result of `itemToStringValue` or the auto-detected `.value` property.\n */\n value: string\n /**\n * Whether the parent item is selected.\n */\n selected: boolean\n /**\n * Whether the parent item is highlighted.\n */\n highlighted: boolean\n /**\n * Whether the parent item is disabled.\n */\n disabled: boolean\n}\n\nexport interface ComboboxItemLabelProps\n extends ComponentProps<'span', ComboboxItemLabel.State> {}\n\n/**\n * Helper to resolve label from items prop\n */\nfunction resolveLabelFromItems(\n items:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n | undefined,\n valueKey: string,\n): React.ReactNode | undefined {\n if (!items) return undefined\n\n if (Array.isArray(items)) {\n const item = items.find((i) => i.value === valueKey)\n return item?.label\n }\n\n return items[valueKey]\n}\n\n/**\n * Renders the text label for a combobox item.\n *\n * When no children are provided, automatically renders the label from:\n * 1. The `items` prop passed to `Combobox.Root`\n * 2. The `textValue` prop on `Combobox.Item`\n * 3. Falls back to the item's value\n *\n * Also registers the text content for use in the input display.\n * Renders a `<span>` element.\n */\nexport const ComboboxItemLabel = React.forwardRef<\n HTMLSpanElement,\n ComboboxItemLabel.Props\n>(function ComboboxItemLabel(props, forwardedRef) {\n const { render, className, style, children, ...rest } = props\n\n const comboboxContext = useComboboxContext()\n const itemContext = useComboboxItemContext()\n\n // Serialize the item value to a string key for registry lookups\n const valueKey = stringifyAsValue(\n itemContext.value,\n comboboxContext.itemToStringValue,\n )\n\n // Resolve label content:\n // 1. Explicit children (override)\n // 2. Label from items prop lookup\n // 3. textValue from item context\n // 4. Fall back to the serialized value key\n const resolvedLabel = React.useMemo(() => {\n if (children !== undefined) {\n return children\n }\n\n const labelFromItems = resolveLabelFromItems(\n comboboxContext.items,\n valueKey,\n )\n if (labelFromItems !== undefined) {\n return labelFromItems\n }\n\n if (itemContext.textValue !== undefined) {\n return itemContext.textValue\n }\n\n return valueKey\n }, [children, comboboxContext.items, valueKey, itemContext.textValue])\n\n // Build state for render prop and className/style functions\n const state: ComboboxItemLabel.State = React.useMemo(\n () => ({\n value: valueKey,\n selected: itemContext.selected,\n highlighted: itemContext.highlighted,\n disabled: itemContext.disabled,\n }),\n [\n valueKey,\n itemContext.selected,\n itemContext.highlighted,\n itemContext.disabled,\n ],\n )\n\n // Register text content when mounted or resolved label changes\n React.useEffect(() => {\n if (typeof resolvedLabel === 'string') {\n return comboboxContext.registerItemText(valueKey, resolvedLabel)\n }\n }, [resolvedLabel, comboboxContext, valueKey])\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n props: {\n ...rest,\n [ComboboxItemLabelDataAttributes.slot]: '',\n className,\n style,\n children: resolvedLabel,\n },\n defaultTagName: 'span',\n })\n})\n\nexport namespace ComboboxItemLabel {\n export interface Props extends ComboboxItemLabelProps {}\n export type State = ComboboxItemLabelState\n}\n","/**\n * Data attributes for ComboboxItemLabel component.\n */\nexport const ComboboxItemLabelDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-item-label'}\n */\n slot: 'bazzaui-combobox-item-label',\n} as const\n","'use client'\n\nimport { Popover, type PopoverPositionerProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport { useComboboxContext } from '../contexts/combobox-context.js'\nimport {\n type Align,\n type ComboboxLayout,\n ComboboxPositionerContext,\n type ComboboxPositionerContextValue,\n type Side,\n} from '../contexts/combobox-positioner-context.js'\nimport { ComboboxPositionerDataAttributes } from './positioner.data-attrs.js'\n\nexport { ComboboxPositionerDataAttributes }\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ComboboxPositionerProps extends PopoverPositionerProps {\n /**\n * Override the layout mode for the popup.\n * If not provided, uses the `layout` from `Combobox.Root`.\n *\n * - `'floating'` - Standard dropdown positioning below/above the input\n * - `'input-embedded'` - Popup wraps around the input (macOS Spotlight-style).\n * The input appears to be inside the popup at the top.\n *\n * When `'input-embedded'`:\n * - Popup is positioned flush with the input (sideOffset=0)\n * - Alignment is centered on the input\n * - Positioning styles are automatically applied to the Popup child\n * - Use `popupPadding` to control the padding around the input\n * - `data-input-embedded` attribute is added to Input, Positioner, Popup, and List\n */\n layout?: ComboboxLayout\n\n /**\n * Padding around the popup content when `layout=\"input-embedded\"`.\n * Creates the \"encapsulated\" look where the input appears inside the popup\n * with padding on all sides.\n *\n * Only applies when `layout=\"input-embedded\"`.\n *\n * @default 8\n */\n popupPadding?: number\n}\n\n// ============================================================================\n// Helper: Get positioning styles based on actual side\n// ============================================================================\n\nfunction getInputEmbeddedStyles(\n actualSide: Side,\n inputHeight: number,\n inputWidth: number,\n popupPadding: number,\n): React.CSSProperties {\n const popupWidth = inputWidth + popupPadding * 2\n\n if (actualSide === 'top') {\n // Popup is above the input, so extend downward to wrap the input\n // Input will appear at the BOTTOM of the popup\n const popupMarginBottom = -(inputHeight + popupPadding)\n const popupPaddingBottom = inputHeight + popupPadding\n\n return {\n width: popupWidth,\n marginBottom: popupMarginBottom,\n paddingTop: popupPadding,\n paddingLeft: popupPadding,\n paddingRight: popupPadding,\n paddingBottom: popupPaddingBottom,\n }\n }\n\n // Default: side === 'bottom'\n // Popup is below the input, so extend upward to wrap the input\n // Input will appear at the TOP of the popup\n const popupMarginTop = -(inputHeight + popupPadding)\n const popupPaddingTop = inputHeight + popupPadding\n\n return {\n width: popupWidth,\n marginTop: popupMarginTop,\n paddingTop: popupPaddingTop,\n paddingLeft: popupPadding,\n paddingRight: popupPadding,\n paddingBottom: popupPadding,\n }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Positions the combobox popup against the input.\n * Uses the input element as the anchor for positioning.\n *\n * Supports `alignInputWithPopup` mode where the popup visually wraps around\n * the input, making the input appear to be inside the popup (macOS-style).\n *\n * Renders a `<div>` element.\n */\nexport const ComboboxPositioner = React.forwardRef<\n HTMLDivElement,\n ComboboxPositioner.Props\n>(function ComboboxPositioner(props, forwardedRef) {\n const {\n layout: layoutProp,\n popupPadding = 8,\n side = 'bottom',\n align: alignProp,\n sideOffset = 4,\n anchor: anchorProp,\n className,\n style,\n children,\n ...rest\n } = props\n\n const comboboxContext = useComboboxContext()\n\n // Use prop if provided, otherwise fall back to Root's layout\n const layout = layoutProp ?? comboboxContext.layout\n const isInputEmbedded = layout === 'input-embedded'\n\n // Use the wrapper element as anchor if present, otherwise fall back to input\n // This ensures the popup aligns with the visual container (InputWrapper) when used\n const anchor =\n (anchorProp ?? comboboxContext.inputWrapperRef.current)\n ? comboboxContext.inputWrapperRef\n : comboboxContext.inputRef\n\n // When input-embedded layout is enabled:\n // - Use zero sideOffset (popup flush with input)\n // - Center align (popup centered on input)\n const effectiveSideOffset = isInputEmbedded ? 0 : sideOffset\n const effectiveAlign = isInputEmbedded ? 'center' : (alignProp ?? 'start')\n\n const { inputHeight, inputWidth } = comboboxContext\n const popupWidth = inputWidth + popupPadding * 2\n\n // When input-embedded, set z-index: 0 so the input (with z-index: 1) appears above\n const basePositionerStyles: React.CSSProperties = {\n ...style,\n ...(isInputEmbedded ? { zIndex: 0 } : {}),\n }\n\n // For input-embedded layout, we need to use a render function to access\n // the actual side after collision detection\n if (isInputEmbedded) {\n return (\n <Popover.Positioner\n ref={forwardedRef}\n side={side}\n align={effectiveAlign}\n sideOffset={effectiveSideOffset}\n anchor={anchor}\n className={className}\n style={basePositionerStyles}\n data-input-embedded=\"\"\n {...{ [ComboboxPositionerDataAttributes.slot]: '' }}\n {...rest}\n render={(renderProps, state) => {\n const actualSide = state.side as Side\n\n // Context value with actual side\n const contextValue: ComboboxPositionerContextValue = {\n layout,\n side: actualSide,\n align: state.align as Align,\n inputHeight: comboboxContext.inputHeight,\n }\n\n // CSS variables for input dimensions\n const cssVariables: React.CSSProperties = {\n '--combobox-input-height': `${inputHeight}px`,\n '--combobox-input-width': `${inputWidth}px`,\n '--combobox-popup-padding': `${popupPadding}px`,\n '--combobox-popup-width': `${popupWidth}px`,\n } as React.CSSProperties\n\n // Get positioning styles based on actual side\n const positioningStyles = getInputEmbeddedStyles(\n actualSide,\n inputHeight,\n inputWidth,\n popupPadding,\n )\n\n // Enhance children with positioning styles\n const enhancedChildren = React.Children.map(children, (child) => {\n if (!React.isValidElement(child)) {\n return child\n }\n\n return React.cloneElement(child as React.ReactElement<any>, {\n style: {\n ...positioningStyles,\n ...(child.props as any).style,\n },\n 'data-side': actualSide,\n })\n })\n\n return (\n <ComboboxPositionerContext.Provider value={contextValue}>\n <div\n {...renderProps}\n style={{ ...renderProps.style, ...cssVariables }}\n data-side={actualSide}\n >\n {enhancedChildren}\n </div>\n </ComboboxPositionerContext.Provider>\n )\n }}\n />\n )\n }\n\n // Non-input-embedded: simple rendering\n const contextValue: ComboboxPositionerContextValue = {\n layout,\n side: side as Side,\n align: effectiveAlign as Align,\n inputHeight: comboboxContext.inputHeight,\n }\n\n // CSS variables for input dimensions\n const cssVariables: React.CSSProperties = {\n '--combobox-input-height': `${inputHeight}px`,\n '--combobox-input-width': `${inputWidth}px`,\n } as React.CSSProperties\n\n const positionerStyles: React.CSSProperties = {\n ...basePositionerStyles,\n ...cssVariables,\n }\n\n return (\n <ComboboxPositionerContext.Provider value={contextValue}>\n <Popover.Positioner\n ref={forwardedRef}\n side={side}\n align={effectiveAlign}\n sideOffset={effectiveSideOffset}\n anchor={anchor}\n className={className}\n style={positionerStyles}\n {...{ [ComboboxPositionerDataAttributes.slot]: '' }}\n {...rest}\n >\n {children}\n </Popover.Positioner>\n </ComboboxPositionerContext.Provider>\n )\n})\n\nexport namespace ComboboxPositioner {\n export type Props = ComboboxPositionerProps\n export type State = Popover.Positioner.State\n}\n","/**\n * Data attributes for ComboboxPositioner component.\n */\nexport const ComboboxPositionerDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-positioner'}\n */\n slot: 'bazzaui-combobox-positioner',\n} as const\n","'use client'\n\nimport { Popover, type PopoverRootProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport type { VirtualItem } from '../../internal/listbox/index.js'\nimport type { PopupMenuOpenChangeReason } from '../../internal/popup-menu/events.js'\nimport {\n PopupMenuProviders,\n type UsePopupMenuRootParams,\n usePopupMenuRoot,\n} from '../../internal/popup-menu/index.js'\nimport {\n defaultItemEquality,\n type ItemEqualityComparer,\n} from '../../utils/item-equality.js'\nimport { stringifyAsValue } from '../../utils/resolve-value-label.js'\nimport {\n ComboboxContext,\n type ComboboxContextValue,\n type ComboboxFilterMode,\n type ItemTextRegistry,\n} from '../contexts/combobox-context.js'\nimport type { ComboboxLayout } from '../contexts/combobox-positioner-context.js'\nimport type {\n ComboboxHighlightChangeEventDetails,\n ComboboxOpenChangeEventDetails,\n} from '../events.js'\n\n/**\n * Helper type to determine the value type based on the multiple flag.\n */\ntype ComboboxValueType<\n Value,\n Multiple extends boolean | undefined,\n> = Multiple extends true ? Value[] : Value | null\n\nexport interface ComboboxRootProps<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n> extends Omit<PopoverRootProps, 'open' | 'onOpenChange' | 'defaultOpen'> {\n // ===== Open State =====\n /**\n * Whether the combobox 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: ComboboxOpenChangeEventDetails,\n ) => void\n\n /**\n * Whether the combobox is initially open.\n * Use for uncontrolled mode.\n * @default false\n */\n defaultOpen?: boolean\n\n // ===== Single Selection =====\n /**\n * Current selected value (single-select mode).\n * Use for controlled mode.\n * Can be a primitive or an object.\n */\n value?: ComboboxValueType<Value, Multiple>\n\n /**\n * Default selected value (single-select mode).\n * Use for uncontrolled mode.\n */\n defaultValue?: ComboboxValueType<Value, Multiple>\n\n /**\n * Callback when the selected value changes (single-select mode).\n */\n onValueChange?: (value: Value) => void\n\n // ===== Multi Selection =====\n /**\n * Whether multi-select mode is enabled.\n * @default false\n */\n multiple?: Multiple\n\n /**\n * Current selected values (multi-select mode).\n * Use for controlled mode.\n */\n values?: Value[]\n\n /**\n * Default selected values (multi-select mode).\n * Use for uncontrolled mode.\n */\n defaultValues?: Value[]\n\n /**\n * Callback when the selected values change (multi-select mode).\n */\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 /**\n * When the item values are objects (`<Combobox.Item value={object}>`),\n * this function converts the object value to a string representation\n * 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 /**\n * When the item values are objects (`<Combobox.Item value={object}>`),\n * this function converts the object value to a string representation\n * 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 /**\n * Current input value.\n * Use for controlled mode.\n */\n inputValue?: string\n\n /**\n * Default input value.\n * Use for uncontrolled mode.\n */\n defaultInputValue?: string\n\n /**\n * Callback when the input value changes.\n */\n onInputValueChange?: (value: string) => void\n\n // ===== Form Integration =====\n /**\n * Form field name for submission.\n * When set, hidden input(s) will be rendered for form submission.\n */\n name?: string\n\n /**\n * Associate with a form by ID.\n */\n form?: string\n\n /**\n * Whether this field is required.\n */\n required?: boolean\n\n /**\n * Whether the combobox is disabled.\n * @default false\n */\n disabled?: boolean\n\n /**\n * Placeholder text for the input.\n * @default \"Search...\"\n */\n placeholder?: string\n\n /**\n * Data structure of the items rendered in the combobox popup.\n * When specified, the input shows the label of the selected item\n * instead of the raw value.\n *\n * Can be a record mapping values to labels, or an array of { value, label } objects.\n * @example\n * ```tsx\n * // Record format\n * <Combobox.Root items={{ us: 'United States', uk: 'United Kingdom' }}>\n *\n * // Array format\n * <Combobox.Root items={[\n * { value: 'us', label: 'United States' },\n * { value: 'uk', label: 'United Kingdom' },\n * ]}>\n * ```\n */\n items?:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n\n // ===== Behavior =====\n /**\n * Determines if the combobox enters a modal state when open.\n *\n * - `true`: user interaction is limited to the combobox: document page scroll\n * is locked, and pointer interactions on outside elements are disabled.\n * - `false`: user interaction with the rest of the document is allowed.\n * - `'trap-focus'`: focus is trapped inside the combobox, but document page\n * scroll is not locked and pointer interactions outside of it remain enabled.\n *\n * @default false\n */\n modal?: boolean | 'trap-focus'\n\n /**\n * Whether to close the popup after selecting an item.\n * @default true for single-select, false for multi-select\n */\n closeOnSelect?: boolean\n\n /**\n * Whether to open the popup when the input is focused.\n * @default true\n */\n openOnFocus?: boolean\n\n // ===== Virtualization =====\n /**\n * Whether virtualization mode is enabled.\n * When true, items should provide an explicit `index` prop and\n * the `virtualItems` 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 virtualItems?: VirtualItem[]\n\n /**\n * Callback when the highlighted item changes.\n * Useful for synchronizing with a virtualizer (e.g., scrollToIndex).\n * Only called when `virtualized={true}`.\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: ComboboxHighlightChangeEventDetails,\n ) => void\n\n // ===== Layout =====\n /**\n * The layout mode for the combobox popup.\n *\n * - `'floating'` (default) - Standard dropdown positioning below/above the input\n * - `'input-embedded'` - Popup wraps around the input (macOS Spotlight-style).\n * The input appears to be inside the popup at the top.\n *\n * When `'input-embedded'`:\n * - `data-input-embedded` attribute is added to Input, Positioner, Popup, and List\n * - Use CSS selectors like `[data-input-embedded]` to style components\n *\n * @default 'floating'\n */\n layout?: ComboboxLayout\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 children: React.ReactNode\n}\n\n/**\n * Groups all parts of the combobox.\n * Manages open state, selection state, input state, and provides context to children.\n * Doesn't render its own HTML element.\n *\n * @template Value - The type of the combobox value (can be a primitive or object)\n * @template Multiple - Whether multiple selection is enabled\n */\nexport function ComboboxRoot<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n>(props: ComboboxRootProps<Value, Multiple>): React.JSX.Element {\n const {\n // Open state\n open: openProp,\n onOpenChange,\n defaultOpen = false,\n // Single selection\n value: valueProp,\n defaultValue,\n onValueChange,\n // Multi selection\n multiple = false as Multiple,\n values: valuesProp,\n defaultValues,\n onValuesChange,\n // Object value support\n isItemEqualToValue = defaultItemEquality as ItemEqualityComparer<Value>,\n itemToStringLabel,\n itemToStringValue,\n // Input state\n inputValue: inputValueProp,\n defaultInputValue = '',\n onInputValueChange,\n // Form integration\n name,\n form,\n required,\n disabled = false,\n placeholder = 'Search...',\n items,\n // Behavior\n modal = false,\n closeOnSelect: closeOnSelectProp,\n openOnFocus = true,\n // Virtualization\n virtualized = false,\n virtualItems,\n onHighlightChange,\n // Layout\n layout = 'floating',\n // Animation callback\n onOpenChangeComplete: onOpenChangeCompleteProp,\n children,\n ...rest\n } = props\n\n // Generate a unique ID for the listbox\n const listId = React.useId()\n\n // ===== Element Refs for Positioning =====\n const inputRef = React.useRef<HTMLInputElement | null>(null)\n const inputWrapperRef = React.useRef<HTMLElement | null>(null)\n const [inputHeight, setInputHeight] = React.useState(0)\n const [inputWidth, setInputWidth] = React.useState(0)\n\n const setInputElement = React.useCallback(\n (element: HTMLInputElement | null) => {\n inputRef.current = element\n // Only use input dimensions if there's no wrapper\n if (element && !inputWrapperRef.current) {\n const rect = element.getBoundingClientRect()\n setInputHeight(rect.height)\n setInputWidth(rect.width)\n }\n },\n [],\n )\n\n const setInputWrapperElement = React.useCallback(\n (element: HTMLElement | null) => {\n inputWrapperRef.current = element\n // When wrapper is present, use its dimensions instead of input\n if (element) {\n const rect = element.getBoundingClientRect()\n setInputHeight(rect.height)\n setInputWidth(rect.width)\n }\n },\n [],\n )\n\n // ===== Open State =====\n // Use shared hook to create stores and utilities\n const {\n store,\n focusOwnerStore,\n openChainStore,\n registerSurface,\n closeAll,\n virtualization,\n handleOpenChange: baseHandleOpenChange,\n } = usePopupMenuRoot({\n // Cast to generic type - component handles type safety via narrowed types\n onOpenChange:\n onOpenChange as unknown as UsePopupMenuRootParams['onOpenChange'],\n defaultOpen,\n virtualized,\n items: virtualItems,\n onHighlightChange:\n onHighlightChange as unknown as UsePopupMenuRootParams['onHighlightChange'],\n })\n\n // Sync controlled open prop to store\n store.useControlledProp('open', openProp, defaultOpen)\n\n // Get open state from store for Popover\n const open = store.useState('open')\n\n // Custom handleOpenChange that ignores close events when input has focus\n // This prevents base-ui's Popover from closing when clicking on the input\n const handleOpenChange = React.useCallback(\n (\n newOpen: boolean,\n reason?: ComboboxOpenChangeEventDetails['reason'],\n event?: Event,\n ) => {\n // When trying to close, check if input has focus\n if (!newOpen && inputRef.current) {\n const activeElement = document.activeElement\n // If the input has focus or will have focus, don't close\n if (activeElement === inputRef.current) {\n return\n }\n }\n // Cast reason - combobox has additional reasons beyond PopupMenu's reasons\n baseHandleOpenChange(\n newOpen,\n reason as Parameters<typeof baseHandleOpenChange>[1],\n event,\n )\n },\n [baseHandleOpenChange],\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 // Call user's callback\n onOpenChangeCompleteProp?.(nextOpen)\n },\n [store, onOpenChangeCompleteProp],\n )\n\n // Wrapper to adapt Popover's event details to our handleOpenChange\n const handlePopoverOpenChange = React.useCallback(\n (nextOpen: boolean, popoverDetails: Popover.Root.ChangeEventDetails) => {\n // Forward to our internal handler with the reason and event\n handleOpenChange(\n nextOpen,\n popoverDetails.reason as ComboboxOpenChangeEventDetails['reason'],\n popoverDetails.event,\n )\n },\n [handleOpenChange],\n )\n\n // ===== Single Selection State =====\n const [internalValue, setInternalValue] = React.useState<Value | null>(\n defaultValue !== undefined ? (defaultValue as Value | null) : null,\n )\n const value: Value | null =\n valueProp !== undefined ? (valueProp as Value | null) : internalValue\n\n const handleValueChange = React.useCallback(\n (newValue: Value) => {\n if (valueProp === undefined) {\n setInternalValue(newValue)\n }\n onValueChange?.(newValue)\n },\n [valueProp, onValueChange],\n )\n\n // ===== Multi Selection State =====\n const [internalValues, setInternalValues] = React.useState<Value[]>(\n defaultValues ?? [],\n )\n const values: Value[] = valuesProp !== undefined ? valuesProp : internalValues\n\n const handleValuesChange = React.useCallback(\n (newValues: Value[]) => {\n if (valuesProp === undefined) {\n setInternalValues(newValues)\n }\n onValuesChange?.(newValues)\n },\n [valuesProp, onValuesChange],\n )\n\n // ===== Input Value State =====\n const [internalInputValue, setInternalInputValue] =\n React.useState(defaultInputValue)\n const inputValue =\n inputValueProp !== undefined ? inputValueProp : internalInputValue\n\n const handleInputValueChange = React.useCallback(\n (newValue: string) => {\n if (inputValueProp === undefined) {\n setInternalInputValue(newValue)\n }\n onInputValueChange?.(newValue)\n },\n [inputValueProp, onInputValueChange],\n )\n\n // ===== Item Text Registry =====\n // The registry persists item text even after items unmount (popup closes).\n // This ensures the input can display the correct label for selected values.\n // Text is only overwritten when items re-mount with new text, never deleted.\n const itemTextRegistryRef = React.useRef<ItemTextRegistry>(new Map())\n\n const registerItemText = React.useCallback(\n (itemValue: string, text: string) => {\n itemTextRegistryRef.current.set(itemValue, text)\n // No cleanup - text should persist even when items unmount\n return () => {}\n },\n [],\n )\n\n // ===== Close on Select =====\n const closeOnSelect = closeOnSelectProp ?? !multiple\n\n // ===== Filter Mode State Machine =====\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 //\n // We use a ref for synchronous access during close (to prevent flash of items).\n const filterModeRef = React.useRef<ComboboxFilterMode>({ type: 'active' })\n const [, setFilterModeState] = React.useState<ComboboxFilterMode>({\n type: 'active',\n })\n\n const setFilterMode = React.useCallback((mode: ComboboxFilterMode) => {\n filterModeRef.current = mode\n setFilterModeState(mode)\n }, [])\n\n // Read from ref for synchronous access\n const filterMode = filterModeRef.current\n\n const setFilterActive = React.useCallback(() => {\n // User is typing, switch to active filtering\n setFilterMode({ type: 'active' })\n }, [setFilterMode])\n\n // ===== Open/Close Helpers =====\n const openCombobox = React.useCallback(() => {\n if (!disabled) {\n // If opening with a selected value (single-select), show all items initially.\n // Otherwise, use active filtering.\n if (!multiple && value != null) {\n setFilterMode({ type: 'showAll' })\n } else {\n setFilterMode({ type: 'active' })\n }\n store.setOpen(true)\n }\n }, [disabled, store, multiple, value, setFilterMode])\n\n const closeCombobox = React.useCallback(\n (reason?: ComboboxOpenChangeEventDetails['reason'], event?: Event) => {\n // Freeze the current search state BEFORE closing to prevent filter changes\n // during exit animations.\n //\n // Get the effective search value based on current filter mode:\n // - 'active': freeze to current inputValue\n // - 'showAll': freeze to '' (keep showing all items)\n // - 'frozen': keep the existing frozen value (shouldn't happen, but handle it)\n const currentMode = filterModeRef.current\n const searchToFreeze =\n currentMode.type === 'active'\n ? internalInputValue\n : currentMode.type === 'showAll'\n ? ''\n : currentMode.search\n\n setFilterMode({ type: 'frozen', search: searchToFreeze })\n // Cast is safe: closeCombobox only receives close-related reasons\n // which are a subset of PopupMenuOpenChangeReason\n store.setOpen(\n false,\n reason as PopupMenuOpenChangeReason | undefined,\n event,\n )\n },\n [store, setFilterMode, internalInputValue],\n )\n\n // ===== Combobox Context =====\n const comboboxContextValue: ComboboxContextValue<Value> = React.useMemo(\n () => ({\n multiple: multiple as boolean,\n value,\n values,\n onValueChange: handleValueChange,\n onValuesChange: handleValuesChange,\n isItemEqualToValue,\n itemToStringLabel,\n itemToStringValue,\n inputValue,\n onInputValueChange: handleInputValueChange,\n name,\n form,\n required,\n disabled,\n placeholder,\n items,\n itemTextRegistry: itemTextRegistryRef.current,\n registerItemText,\n listId,\n inputRef,\n setInputElement,\n inputWrapperRef,\n setInputWrapperElement,\n closeOnSelect,\n openOnFocus,\n openCombobox,\n closeCombobox,\n filterMode,\n setFilterActive,\n inputHeight,\n inputWidth,\n layout,\n }),\n [\n multiple,\n value,\n values,\n handleValueChange,\n handleValuesChange,\n isItemEqualToValue,\n itemToStringLabel,\n itemToStringValue,\n inputValue,\n handleInputValueChange,\n name,\n form,\n required,\n disabled,\n placeholder,\n items,\n registerItemText,\n listId,\n setInputElement,\n setInputWrapperElement,\n closeOnSelect,\n openOnFocus,\n openCombobox,\n closeCombobox,\n filterMode,\n setFilterActive,\n inputHeight,\n inputWidth,\n layout,\n ],\n )\n\n // ===== Hidden Inputs for Form Submission =====\n const hiddenInputs = React.useMemo(() => {\n if (!name) return null\n\n if (multiple) {\n // Multiple hidden inputs for array submission\n if (values.length > 0) {\n return values.map((v, index) => {\n const serializedValue = stringifyAsValue(v, itemToStringValue)\n return (\n <input\n key={serializedValue}\n type=\"hidden\"\n name={name}\n value={serializedValue}\n form={form}\n required={required && index === 0}\n />\n )\n })\n }\n // Empty hidden input to ensure field is submitted even when empty\n return (\n <input\n type=\"hidden\"\n name={name}\n value=\"\"\n form={form}\n required={required}\n />\n )\n }\n\n // Single hidden input\n return (\n <input\n type=\"hidden\"\n name={name}\n value={value != null ? stringifyAsValue(value, itemToStringValue) : ''}\n form={form}\n required={required}\n />\n )\n }, [name, form, required, multiple, value, values, itemToStringValue])\n\n return (\n <ComboboxContext.Provider\n value={comboboxContextValue as ComboboxContextValue<unknown>}\n >\n <PopupMenuProviders\n store={store}\n focusOwnerStore={focusOwnerStore}\n openChainStore={openChainStore}\n depth={0}\n closeAll={closeAll}\n registerSurface={registerSurface}\n virtualization={virtualization}\n menuType=\"dropdown\"\n componentName=\"combobox\"\n >\n {hiddenInputs}\n <Popover.Root\n {...rest}\n open={open}\n onOpenChange={handlePopoverOpenChange}\n onOpenChangeComplete={handleOpenChangeComplete}\n modal={modal}\n >\n {children}\n </Popover.Root>\n </PopupMenuProviders>\n </ComboboxContext.Provider>\n )\n}\n\nexport namespace ComboboxRoot {\n export interface Props<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n > extends ComboboxRootProps<Value, Multiple> {}\n export type OpenChangeEventDetails = ComboboxOpenChangeEventDetails\n export type HighlightChangeEventDetails = ComboboxHighlightChangeEventDetails\n export type Actions = Popover.Root.Actions\n}\n","'use client'\n\nimport * as React from 'react'\nimport {\n PopupMenuSurface,\n type PopupMenuSurfaceProps,\n} from '../../internal/popup-menu/index.js'\nimport { stringifyAsValue } from '../../utils/resolve-value-label.js'\nimport { useComboboxContext } from '../contexts/combobox-context.js'\nimport { ComboboxSurfaceDataAttributes } from './surface.data-attrs.js'\n\nexport { ComboboxSurfaceDataAttributes }\n\nexport interface ComboboxSurfaceProps\n extends Omit<PopupMenuSurfaceProps, 'autoHighlightFirst'> {\n /**\n * Controls auto-highlighting behavior when the combobox opens.\n * - `true`: highlight the first item (default)\n * - `false`: don't auto-highlight any item\n * - `'selected'`: highlight the currently selected item, or first item if none selected\n * - `string`: highlight the item with this specific value\n * @default true\n */\n autoHighlightFirst?: boolean | 'selected' | string\n}\n\n/**\n * Provides search context and manages item registration for Combobox.\n * Automatically syncs the search state with the combobox's input value.\n *\n * Place inside Combobox.Popup to enable search functionality.\n * Renders a `<div>` element.\n */\nexport const ComboboxSurface = React.forwardRef<\n HTMLDivElement,\n ComboboxSurface.Props\n>(function ComboboxSurface(props, forwardedRef) {\n const {\n autoHighlightFirst: autoHighlightFirstProp,\n search: searchProp,\n onSearchChange: onSearchChangeProp,\n onPointerMove: onPointerMoveProp,\n ...rest\n } = props\n\n const comboboxContext = useComboboxContext()\n\n // Focus the input when cursor moves inside the popup\n // This allows users to immediately type to filter after hovering\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMoveProp?.(event)\n\n // Focus the input if it's not already focused\n const input = comboboxContext.inputRef.current\n if (input && document.activeElement !== input) {\n input.focus()\n }\n },\n [onPointerMoveProp, comboboxContext.inputRef],\n )\n\n // Resolve autoHighlightFirst:\n // - 'selected': use the current selected value (falls back to true if no selection)\n // - true/false/string: pass through as-is\n // Default to true (highlight first item)\n const autoHighlightFirst = React.useMemo(() => {\n const prop = autoHighlightFirstProp ?? true\n\n if (prop === 'selected') {\n // For single-select, use the selected value\n // For multi-select, use the first selected value\n const selectedValue = comboboxContext.multiple\n ? comboboxContext.values[0]\n : comboboxContext.value\n\n // If there's a selected value, serialize it to a string and use for highlighting\n if (selectedValue != null) {\n return stringifyAsValue(\n selectedValue,\n comboboxContext.itemToStringValue,\n )\n }\n // Otherwise highlight first\n return true\n }\n\n return prop\n }, [\n autoHighlightFirstProp,\n comboboxContext.multiple,\n comboboxContext.value,\n comboboxContext.values,\n comboboxContext.itemToStringValue,\n ])\n\n // Sync search with combobox's input value based on filter mode:\n // - 'active': use inputValue (normal filtering)\n // - 'showAll': use '' (show all items when opened with selected value)\n // - 'frozen': use frozen search value (during close animation)\n const { filterMode } = comboboxContext\n const search =\n searchProp ??\n (filterMode.type === 'active'\n ? comboboxContext.inputValue\n : filterMode.type === 'showAll'\n ? ''\n : filterMode.search)\n\n // Sync search changes back to combobox\n const handleSearchChange = React.useCallback(\n (value: string) => {\n comboboxContext.onInputValueChange(value)\n onSearchChangeProp?.(value)\n },\n [comboboxContext, onSearchChangeProp],\n )\n\n return (\n <PopupMenuSurface\n ref={forwardedRef}\n autoHighlightFirst={autoHighlightFirst}\n search={search}\n onSearchChange={handleSearchChange}\n onPointerMove={handlePointerMove}\n // Skip auto-focus because the Combobox.Input is outside the popup\n // and should retain focus while the dropdown is open\n skipAutoFocus\n {...{ [ComboboxSurfaceDataAttributes.slot]: '' }}\n {...rest}\n />\n )\n})\n\nexport namespace ComboboxSurface {\n export type State = PopupMenuSurface.State\n export interface Props extends ComboboxSurfaceProps {}\n}\n","/**\n * Data attributes for ComboboxSurface component.\n */\nexport const ComboboxSurfaceDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-surface'}\n */\n slot: 'bazzaui-combobox-surface',\n} as const\n","export enum ComboboxArrowDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-arrow'}\n */\n slot = 'bazzaui-combobox-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","export enum ComboboxBackdropDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-backdrop'}\n */\n slot = 'bazzaui-combobox-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","export enum ComboboxEmptyDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-empty'}\n */\n slot = 'bazzaui-combobox-empty',\n}\n","export enum ComboboxGroupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-group'}\n */\n slot = 'bazzaui-combobox-group',\n}\n","export enum ComboboxGroupLabelDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-group-label'}\n */\n slot = 'bazzaui-combobox-group-label',\n}\n","export const ComboboxIconDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-icon'}\n */\n slot: 'bazzaui-combobox-icon',\n /** Present when the popup is open. */\n open: 'data-popup-open',\n} as const\n","export enum ComboboxListDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-list'}\n */\n slot = 'bazzaui-combobox-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","export enum ComboboxPopupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-popup'}\n */\n slot = 'bazzaui-combobox-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","export const ComboboxScrollArrowDataAttributes = {\n /**\n * Identifies the component part for scroll up arrow.\n * @type {'bazzaui-combobox-scroll-up-arrow'}\n */\n slotUp: 'bazzaui-combobox-scroll-up-arrow',\n /**\n * Identifies the component part for scroll down arrow.\n * @type {'bazzaui-combobox-scroll-down-arrow'}\n */\n slotDown: 'bazzaui-combobox-scroll-down-arrow',\n /**\n * Direction of the scroll arrow.\n * @type {'up' | 'down'}\n */\n direction: 'data-direction',\n /**\n * Side of the popup.\n * @type {'top' | 'bottom' | 'left' | 'right'}\n */\n side: 'data-side',\n} as const\n","export enum ComboboxSeparatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-combobox-separator'}\n */\n slot = 'bazzaui-combobox-separator',\n}\n","// ============================================================================\n// Context Menu Parts\n// ============================================================================\n// Re-exports shared components from internal/popup-menu with context-menu specific\n// Root and Trigger components.\n\n// Re-export VirtualItem type from internal/listbox\nexport type { VirtualItem } from '../internal/listbox/index.js'\n// Re-export shared components from internal/popup-menu\nexport {\n PopupMenuArrow as Arrow,\n PopupMenuBackdrop as Backdrop,\n PopupMenuCheckboxItem as CheckboxItem,\n PopupMenuCheckboxItemIndicator as CheckboxItemIndicator,\n PopupMenuDataInput as DataInput,\n PopupMenuDataList as DataList,\n // Deep Search (Data-First API)\n PopupMenuDataSurface as DataSurface,\n PopupMenuEmpty as Empty,\n // Structure\n PopupMenuGroup as Group,\n PopupMenuGroupLabel as GroupLabel,\n // Trigger components\n PopupMenuIcon as Icon,\n PopupMenuInput as Input,\n // Items\n PopupMenuItem as Item,\n PopupMenuList as List,\n PopupMenuPopup as Popup,\n // Positioning & Container\n PopupMenuPortal as Portal,\n PopupMenuPositioner as Positioner,\n PopupMenuRadioGroup as RadioGroup,\n PopupMenuRadioGroupValue as RadioGroupValue,\n PopupMenuRadioItem as RadioItem,\n PopupMenuRadioItemIndicator as RadioItemIndicator,\n // Scroll indicators\n PopupMenuScrollDownArrow as ScrollDownArrow,\n PopupMenuScrollUpArrow as ScrollUpArrow,\n PopupMenuSeparator as Separator,\n // Utility\n PopupMenuShortcut as Shortcut,\n // Submenus\n PopupMenuSubmenuRoot as Submenu,\n PopupMenuSubmenuTrigger as SubmenuTrigger,\n PopupMenuSubmenuTriggerIndicator as SubmenuTriggerIndicator,\n // Content\n PopupMenuSurface as Surface,\n} from '../internal/popup-menu/index.js'\n// Context-menu specific components\nexport { ContextMenuRoot as Root } from './root/root.js'\nexport { ContextMenuTrigger as Trigger } from './trigger/trigger.js'\n","'use client'\n\nimport { Popover } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport type { VirtualItem } from '../../internal/listbox/index.js'\nimport type { GetQualifiedRowIdFn } from '../../internal/popup-menu/deep-search/types.js'\nimport {\n PopupMenuProviders,\n type UsePopupMenuRootParams,\n usePopupMenuRoot,\n type VirtualAnchor,\n} from '../../internal/popup-menu/index.js'\nimport type {\n ContextMenuHighlightChangeEventDetails,\n ContextMenuOpenChangeEventDetails,\n} from '../events.js'\n\nexport interface ContextMenuRootProps {\n /**\n * Whether the context menu 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: ContextMenuOpenChangeEventDetails,\n ) => void\n\n /**\n * Whether the context menu is initially open.\n * Use for uncontrolled mode.\n * @default false\n */\n defaultOpen?: boolean\n\n /**\n * Whether virtualization mode is enabled.\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 * Only called when `virtualized={true}`.\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: ContextMenuHighlightChangeEventDetails,\n ) => void\n\n /**\n * Whether the component should ignore user interaction.\n * @default false\n */\n disabled?: boolean\n\n /**\n * Determines if the context menu enters a modal state when open.\n *\n * - `true`: user interaction is limited to the menu: document page scroll\n * is locked, and pointer interactions on outside elements are disabled.\n * - `false`: user interaction with the rest of the document is allowed.\n *\n * @default true\n */\n modal?: boolean\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 * 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 * 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 * Default behavior:\n * - If node.id is provided, use it as-is (treat as globally unique)\n * - Otherwise, qualify with breadcrumbs + slugified value when deep searching\n */\n getQualifiedRowId?: GetQualifiedRowIdFn\n\n children: React.ReactNode\n}\n\n/**\n * Internal context for ContextMenu-specific state.\n * Used by Trigger to set the virtual anchor position.\n */\ninterface ContextMenuInternalContextValue {\n /** Set the virtual anchor position (called by Trigger on right-click) */\n setAnchorPosition: (x: number, y: number, isTouchEvent?: boolean) => void\n /** Open the menu */\n openMenu: () => void\n /** Close the menu */\n closeMenu: () => void\n /** Whether the menu is disabled */\n disabled: boolean\n /** Whether the menu is open */\n open: boolean\n}\n\nconst ContextMenuInternalContext =\n React.createContext<ContextMenuInternalContextValue | null>(null)\n\nexport function useContextMenuInternal(): ContextMenuInternalContextValue {\n const context = React.useContext(ContextMenuInternalContext)\n if (!context) {\n throw new Error(\n 'ContextMenu components must be used within a ContextMenu.Root',\n )\n }\n return context\n}\n\n/**\n * Creates a virtual anchor at a specific point for positioning.\n */\nfunction createVirtualAnchor(\n x: number,\n y: number,\n isTouchEvent = false,\n): VirtualAnchor {\n // Touch events use a larger anchor for better UX\n const size = isTouchEvent ? 10 : 0\n return {\n getBoundingClientRect() {\n return DOMRect.fromRect({\n width: size,\n height: size,\n x,\n y,\n })\n },\n }\n}\n\n/**\n * Groups all parts of the context menu.\n * Manages open state and provides context to children.\n * Doesn't render its own HTML element.\n */\nexport function ContextMenuRoot(props: ContextMenuRoot.Props) {\n const {\n open: openProp,\n onOpenChange,\n defaultOpen = false,\n virtualized = false,\n items: itemsProp,\n onHighlightChange,\n disabled = false,\n modal = true,\n closeOnOutsidePress = 'pointerdown',\n onOpenChangeComplete: onOpenChangeCompleteProp,\n getQualifiedRowId,\n children,\n } = props\n\n // Use shared hook to create stores and utilities\n const {\n store,\n focusOwnerStore,\n openChainStore,\n registerSurface,\n closeAll,\n virtualization,\n handleOpenChange,\n } = usePopupMenuRoot({\n // Cast to generic type - component handles type safety via narrowed types\n onOpenChange:\n onOpenChange as unknown as UsePopupMenuRootParams['onOpenChange'],\n defaultOpen,\n virtualized,\n items: itemsProp,\n onHighlightChange:\n onHighlightChange as unknown as UsePopupMenuRootParams['onHighlightChange'],\n closeOnOutsidePress,\n })\n\n // Sync controlled open prop to store\n store.useControlledProp('open', openProp, defaultOpen)\n\n // Get open state from store\n const open = store.useState('open')\n\n // Virtual anchor state (position where menu appears)\n const [virtualAnchor, setVirtualAnchor] = React.useState<VirtualAnchor>(() =>\n createVirtualAnchor(0, 0),\n )\n\n // Set anchor position (called by Trigger on right-click/long-press)\n const setAnchorPosition = React.useCallback(\n (x: number, y: number, isTouchEvent = false) => {\n setVirtualAnchor(createVirtualAnchor(x, y, isTouchEvent))\n },\n [],\n )\n\n // Open the menu\n const openMenu = React.useCallback(() => {\n if (disabled) return\n store.setOpen(true)\n }, [store, disabled])\n\n // Close the menu\n const closeMenu = React.useCallback(() => {\n handleOpenChange(false)\n }, [handleOpenChange])\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 }\n // Call user's callback\n onOpenChangeCompleteProp?.(nextOpen)\n },\n [store, onOpenChangeCompleteProp],\n )\n\n // Wrapper to adapt Popover's event details to our handleOpenChange\n const handlePopoverOpenChange = React.useCallback(\n (nextOpen: boolean, popoverDetails: Popover.Root.ChangeEventDetails) => {\n // Forward to our internal handler with the reason and event\n handleOpenChange(\n nextOpen,\n popoverDetails.reason as ContextMenuOpenChangeEventDetails['reason'],\n popoverDetails.event,\n )\n },\n [handleOpenChange],\n )\n\n // Internal context for Trigger\n const internalContextValue: ContextMenuInternalContextValue = React.useMemo(\n () => ({\n setAnchorPosition,\n openMenu,\n closeMenu,\n disabled,\n open,\n }),\n [setAnchorPosition, openMenu, closeMenu, disabled, open],\n )\n\n return (\n <ContextMenuInternalContext.Provider value={internalContextValue}>\n <PopupMenuProviders\n store={store}\n focusOwnerStore={focusOwnerStore}\n openChainStore={openChainStore}\n depth={0}\n closeAll={closeAll}\n registerSurface={registerSurface}\n virtualization={virtualization}\n virtualAnchor={virtualAnchor}\n menuType=\"context\"\n closeOnOutsidePress={closeOnOutsidePress}\n componentName=\"context-menu\"\n getQualifiedRowId={getQualifiedRowId}\n >\n <Popover.Root\n open={open}\n onOpenChange={handlePopoverOpenChange}\n onOpenChangeComplete={handleOpenChangeComplete}\n modal={modal}\n >\n {children}\n </Popover.Root>\n </PopupMenuProviders>\n </ContextMenuInternalContext.Provider>\n )\n}\n\nexport namespace ContextMenuRoot {\n export interface Props extends ContextMenuRootProps {}\n export type OpenChangeEventDetails = ContextMenuOpenChangeEventDetails\n export type HighlightChangeEventDetails =\n ContextMenuHighlightChangeEventDetails\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 { useContextMenuInternal } from '../root/root.js'\nimport { ContextMenuTriggerDataAttributes } from './trigger.data-attrs.js'\n\n// Long-press delay in milliseconds\nconst LONG_PRESS_DELAY = 500\n// Movement threshold to cancel long-press (in pixels)\nconst MOVE_THRESHOLD = 10\n\nexport interface ContextMenuTriggerState extends Record<string, unknown> {\n /**\n * Whether the context menu is currently open.\n */\n open: boolean\n /**\n * Whether the trigger is currently being pressed (long-press in progress).\n */\n pressed: boolean\n /**\n * Whether the trigger is disabled.\n */\n disabled: boolean\n}\n\nexport interface ContextMenuTriggerProps\n extends ComponentProps<'div', ContextMenuTrigger.State> {\n /**\n * Whether the trigger is disabled.\n * When disabled, right-click and long-press will not open the menu.\n * @default false\n */\n disabled?: boolean\n}\n\nconst stateAttributesMapping = {\n open: (value: unknown): Record<string, string> | null =>\n value ? { [ContextMenuTriggerDataAttributes.popupOpen]: '' } : null,\n pressed: (value: unknown): Record<string, string> | null =>\n value ? { [ContextMenuTriggerDataAttributes.pressed]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [ContextMenuTriggerDataAttributes.disabled]: '' } : null,\n}\n\n/**\n * An area that opens the context menu on right-click or long-press.\n * Renders a `<div>` element.\n */\nexport const ContextMenuTrigger = React.forwardRef<\n HTMLDivElement,\n ContextMenuTrigger.Props\n>(function ContextMenuTrigger(props, forwardedRef) {\n const {\n disabled: disabledProp = false,\n render,\n className,\n style,\n onContextMenu,\n onTouchStart,\n onTouchMove,\n onTouchEnd,\n onTouchCancel,\n children,\n ...rest\n } = props\n\n const {\n setAnchorPosition,\n openMenu,\n disabled: rootDisabled,\n open,\n } = useContextMenuInternal()\n\n const disabled = disabledProp || rootDisabled\n\n // Long-press state\n const [pressed, setPressed] = React.useState(false)\n const longPressTimeoutRef = React.useRef<ReturnType<\n typeof setTimeout\n > | null>(null)\n const touchStartPosRef = React.useRef<{ x: number; y: number } | null>(null)\n\n // Cleanup long-press timeout\n const clearLongPressTimeout = React.useCallback(() => {\n if (longPressTimeoutRef.current) {\n clearTimeout(longPressTimeoutRef.current)\n longPressTimeoutRef.current = null\n }\n setPressed(false)\n }, [])\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n clearLongPressTimeout()\n }\n }, [clearLongPressTimeout])\n\n // Handle right-click (contextmenu event)\n const handleContextMenu = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n onContextMenu?.(event)\n\n if (event.defaultPrevented) return\n if (disabled) return\n\n // Prevent default browser context menu\n event.preventDefault()\n\n // Set anchor at cursor position\n setAnchorPosition(event.clientX, event.clientY, false)\n\n // Open the menu\n openMenu()\n },\n [onContextMenu, disabled, setAnchorPosition, openMenu],\n )\n\n // Handle touch start (begin long-press detection)\n const handleTouchStart = React.useCallback(\n (event: React.TouchEvent<HTMLDivElement>) => {\n onTouchStart?.(event)\n\n if (event.defaultPrevented) return\n if (disabled) return\n\n const touch = event.touches[0]\n if (!touch) return\n\n // Store initial touch position\n touchStartPosRef.current = { x: touch.clientX, y: touch.clientY }\n setPressed(true)\n\n // Start long-press timer\n longPressTimeoutRef.current = setTimeout(() => {\n if (!touchStartPosRef.current) return\n\n // Set anchor at touch position\n setAnchorPosition(\n touchStartPosRef.current.x,\n touchStartPosRef.current.y,\n true,\n )\n\n // Open the menu\n openMenu()\n\n // Reset state\n setPressed(false)\n touchStartPosRef.current = null\n }, LONG_PRESS_DELAY)\n },\n [onTouchStart, disabled, setAnchorPosition, openMenu],\n )\n\n // Handle touch move (cancel if moved too far)\n const handleTouchMove = React.useCallback(\n (event: React.TouchEvent<HTMLDivElement>) => {\n onTouchMove?.(event)\n\n if (!touchStartPosRef.current) return\n\n const touch = event.touches[0]\n if (!touch) return\n\n // Calculate distance moved\n const dx = touch.clientX - touchStartPosRef.current.x\n const dy = touch.clientY - touchStartPosRef.current.y\n const distance = Math.sqrt(dx * dx + dy * dy)\n\n // Cancel if moved beyond threshold\n if (distance > MOVE_THRESHOLD) {\n clearLongPressTimeout()\n touchStartPosRef.current = null\n }\n },\n [onTouchMove, clearLongPressTimeout],\n )\n\n // Handle touch end (cleanup)\n const handleTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLDivElement>) => {\n onTouchEnd?.(event)\n clearLongPressTimeout()\n touchStartPosRef.current = null\n },\n [onTouchEnd, clearLongPressTimeout],\n )\n\n // Handle touch cancel (cleanup)\n const handleTouchCancel = React.useCallback(\n (event: React.TouchEvent<HTMLDivElement>) => {\n onTouchCancel?.(event)\n clearLongPressTimeout()\n touchStartPosRef.current = null\n },\n [onTouchCancel, clearLongPressTimeout],\n )\n\n const state: ContextMenuTrigger.State = React.useMemo(\n () => ({\n open,\n pressed,\n disabled,\n }),\n [open, pressed, disabled],\n )\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n [ContextMenuTriggerDataAttributes.slot]: '',\n onContextMenu: handleContextMenu,\n onTouchStart: handleTouchStart,\n onTouchMove: handleTouchMove,\n onTouchEnd: handleTouchEnd,\n onTouchCancel: handleTouchCancel,\n className,\n style: {\n // Prevent native iOS callout on long-press\n WebkitTouchCallout: 'none',\n // Prevent text selection on long-press\n WebkitUserSelect: 'none',\n userSelect: 'none',\n ...style,\n },\n children,\n },\n defaultTagName: 'div',\n })\n})\n\nexport namespace ContextMenuTrigger {\n export type State = ContextMenuTriggerState\n export interface Props extends ContextMenuTriggerProps {}\n}\n","export enum ContextMenuTriggerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-trigger'}\n */\n slot = 'bazzaui-context-menu-trigger',\n /** Present when the corresponding context menu is open. */\n popupOpen = 'data-popup-open',\n /** Present when the trigger is being pressed (long-press). */\n pressed = 'data-pressed',\n /** Present when the trigger is disabled. */\n disabled = 'data-disabled',\n}\n","export enum ContextMenuArrowDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-arrow'}\n */\n slot = 'bazzaui-context-menu-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","export enum ContextMenuBackdropDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-backdrop'}\n */\n slot = 'bazzaui-context-menu-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","export enum ContextMenuCheckboxItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-checkbox-item'}\n */\n slot = 'bazzaui-context-menu-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\nexport enum ContextMenuCheckboxItemIndicatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-checkbox-item-indicator'}\n */\n slot = 'bazzaui-context-menu-checkbox-item-indicator',\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","export enum ContextMenuEmptyDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-empty'}\n */\n slot = 'bazzaui-context-menu-empty',\n}\n","export enum ContextMenuGroupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-group'}\n */\n slot = 'bazzaui-context-menu-group',\n}\n","export enum ContextMenuGroupLabelDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-group-label'}\n */\n slot = 'bazzaui-context-menu-group-label',\n}\n","export const ContextMenuIconDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-icon'}\n */\n slot: 'bazzaui-context-menu-icon',\n /** Present when the popup is open. */\n open: 'data-popup-open',\n} as const\n","export enum ContextMenuInputDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-input'}\n */\n slot = 'bazzaui-context-menu-input',\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","export enum ContextMenuItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-item'}\n */\n slot = 'bazzaui-context-menu-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","export enum ContextMenuListDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-list'}\n */\n slot = 'bazzaui-context-menu-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","export enum ContextMenuPopupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-popup'}\n */\n slot = 'bazzaui-context-menu-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","export enum ContextMenuPositionerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-positioner'}\n */\n slot = 'bazzaui-context-menu-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","export enum ContextMenuRadioGroupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-radio-group'}\n */\n slot = 'bazzaui-context-menu-radio-group',\n /**\n * Present when the radio group is disabled.\n */\n disabled = 'data-disabled',\n}\n","export enum ContextMenuRadioItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-radio-item'}\n */\n slot = 'bazzaui-context-menu-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\nexport enum ContextMenuRadioItemIndicatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-radio-item-indicator'}\n */\n slot = 'bazzaui-context-menu-radio-item-indicator',\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","export const ContextMenuScrollArrowDataAttributes = {\n /**\n * Identifies the component part for scroll up arrow.\n * @type {'bazzaui-context-menu-scroll-up-arrow'}\n */\n slotUp: 'bazzaui-context-menu-scroll-up-arrow',\n /**\n * Identifies the component part for scroll down arrow.\n * @type {'bazzaui-context-menu-scroll-down-arrow'}\n */\n slotDown: 'bazzaui-context-menu-scroll-down-arrow',\n /**\n * Direction of the scroll arrow.\n * @type {'up' | 'down'}\n */\n direction: 'data-direction',\n /**\n * Side of the popup.\n * @type {'top' | 'bottom' | 'left' | 'right'}\n */\n side: 'data-side',\n} as const\n","export enum ContextMenuSeparatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-separator'}\n */\n slot = 'bazzaui-context-menu-separator',\n}\n","export enum ContextMenuShortcutDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-shortcut'}\n */\n slot = 'bazzaui-context-menu-shortcut',\n /**\n * Present when the parent item is highlighted.\n */\n highlighted = 'data-highlighted',\n}\n","export enum ContextMenuSubmenuTriggerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-submenu-trigger'}\n */\n slot = 'bazzaui-context-menu-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\nexport enum ContextMenuSubmenuTriggerIndicatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-submenu-trigger-indicator'}\n */\n slot = 'bazzaui-context-menu-submenu-trigger-indicator',\n /**\n * Present when the submenu popup is open.\n */\n popupOpen = 'data-popup-open',\n}\n","export enum ContextMenuSurfaceDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-context-menu-surface'}\n */\n slot = 'bazzaui-context-menu-surface',\n}\n","// ============================================================================\n// Dropdown Menu Parts\n// ============================================================================\n// Re-exports shared components from internal/popup-menu with dropdown-menu specific\n// Root and Trigger components.\n\n// Re-export VirtualItem type from internal/listbox\nexport type { VirtualItem } from '../internal/listbox/index.js'\n// Re-export shared components from internal/popup-menu\nexport {\n PopupMenuArrow as Arrow,\n PopupMenuBackdrop as Backdrop,\n PopupMenuCheckboxItem as CheckboxItem,\n PopupMenuCheckboxItemIndicator as CheckboxItemIndicator,\n PopupMenuDataInput as DataInput,\n PopupMenuDataList as DataList,\n // Deep Search (Data-First API)\n PopupMenuDataSurface as DataSurface,\n PopupMenuEmpty as Empty,\n // Structure\n PopupMenuGroup as Group,\n PopupMenuGroupLabel as GroupLabel,\n // Trigger components\n PopupMenuIcon as Icon,\n PopupMenuInput as Input,\n // Items\n PopupMenuItem as Item,\n PopupMenuList as List,\n PopupMenuPopup as Popup,\n // Positioning & Container\n PopupMenuPortal as Portal,\n PopupMenuPositioner as Positioner,\n PopupMenuRadioGroup as RadioGroup,\n PopupMenuRadioGroupValue as RadioGroupValue,\n PopupMenuRadioItem as RadioItem,\n PopupMenuRadioItemIndicator as RadioItemIndicator,\n // Scroll indicators\n PopupMenuScrollDownArrow as ScrollDownArrow,\n PopupMenuScrollUpArrow as ScrollUpArrow,\n PopupMenuSeparator as Separator,\n // Utility\n PopupMenuShortcut as Shortcut,\n // Submenus\n PopupMenuSubmenuRoot as Submenu,\n PopupMenuSubmenuTrigger as SubmenuTrigger,\n PopupMenuSubmenuTriggerIndicator as SubmenuTriggerIndicator,\n // Content\n PopupMenuSurface as Surface,\n} from '../internal/popup-menu/index.js'\n// Dropdown-menu specific components\nexport { DropdownMenuRoot as Root } from './root/root.js'\nexport { DropdownMenuTrigger as Trigger } from './trigger/trigger.js'\n","'use client'\n\nimport { Popover, type PopoverRootProps } from '@base-ui/react/popover'\nimport { useCallback, useRef } from 'react'\nimport type { VirtualItem } from '../../internal/listbox/index.js'\nimport type { GetQualifiedRowIdFn } from '../../internal/popup-menu/deep-search/types.js'\nimport {\n PopupMenuProviders,\n type UsePopupMenuRootParams,\n usePopupMenuRoot,\n} from '../../internal/popup-menu/index.js'\nimport type {\n DropdownMenuHighlightChangeEventDetails,\n DropdownMenuOpenChangeEventDetails,\n} from '../events.js'\n\nexport interface DropdownMenuRootProps\n extends Omit<PopoverRootProps, 'open' | 'onOpenChange' | 'defaultOpen'> {\n /**\n * Whether the dropdown menu 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: DropdownMenuOpenChangeEventDetails,\n ) => void\n\n /**\n * Whether the dropdown menu is initially open.\n * Use for uncontrolled mode.\n * @default false\n */\n defaultOpen?: boolean\n\n /**\n * Determines if the dropdown menu enters a modal state when open.\n *\n * - `true`: user interaction is limited to the dropdown menu: document page scroll\n * is locked, and pointer interactions on outside elements are disabled.\n * - `false`: user interaction with the rest of the document is allowed.\n * - `'trap-focus'`: focus is trapped inside the dropdown menu, but document page\n * scroll is not locked and pointer interactions outside of it remain enabled.\n *\n * @default true\n */\n modal?: boolean | 'trap-focus'\n\n /**\n * Whether virtualization mode is enabled.\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 * Only called when `virtualized={true}`.\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: DropdownMenuHighlightChangeEventDetails,\n ) => void\n\n /**\n * When to close the menu on outside interactions (clicking outside or clicking the trigger when open).\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 * 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 * 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 * 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 * ```tsx\n * <DropdownMenu.Root\n * getQualifiedRowId={(ctx) => {\n * if (ctx.id) return ctx.id\n * const path = ctx.breadcrumbs.map(b => b.id ?? slugify(b.value))\n * return [...path, slugify(ctx.value)].join('.')\n * }}\n * >\n * ```\n */\n getQualifiedRowId?: GetQualifiedRowIdFn\n\n children: React.ReactNode\n}\n\n/**\n * Groups all parts of the dropdown menu.\n * Manages open state and provides context to children.\n * Doesn't render its own HTML element.\n */\nexport function DropdownMenuRoot(props: DropdownMenuRoot.Props) {\n const {\n open: openProp,\n onOpenChange,\n defaultOpen = false,\n modal = true,\n virtualized = false,\n items: itemsProp,\n onHighlightChange,\n closeOnOutsidePress = 'pointerdown',\n onOpenChangeComplete: onOpenChangeCompleteProp,\n getQualifiedRowId,\n children,\n ...rest\n } = props\n\n // Use shared hook to create stores and utilities\n const {\n store,\n focusOwnerStore,\n openChainStore,\n registerSurface,\n closeAll,\n virtualization,\n handleOpenChange,\n } = usePopupMenuRoot({\n // Cast to generic type - component handles type safety via narrowed types\n onOpenChange:\n onOpenChange as unknown as UsePopupMenuRootParams['onOpenChange'],\n defaultOpen,\n virtualized,\n items: itemsProp,\n onHighlightChange:\n onHighlightChange as unknown as UsePopupMenuRootParams['onHighlightChange'],\n closeOnOutsidePress,\n })\n\n // Sync controlled open prop to store\n store.useControlledProp('open', openProp, defaultOpen)\n\n // Get open state from store for Popover\n const open = store.useState('open')\n\n // Handle animation complete - clear search and hide input if clearSearchOnClose is 'after-exit'\n const handleOpenChangeComplete = 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 }\n // Call user's callback\n onOpenChangeCompleteProp?.(nextOpen)\n },\n [store, onOpenChangeCompleteProp],\n )\n\n // Wrapper to adapt Popover's event details to our handleOpenChange\n const handlePopoverOpenChange = useCallback(\n (nextOpen: boolean, popoverDetails: Popover.Root.ChangeEventDetails) => {\n // Forward to our internal handler with the reason and event\n handleOpenChange(\n nextOpen,\n popoverDetails.reason as DropdownMenuOpenChangeEventDetails['reason'],\n popoverDetails.event,\n )\n },\n [handleOpenChange],\n )\n\n return (\n <PopupMenuProviders\n store={store}\n focusOwnerStore={focusOwnerStore}\n openChainStore={openChainStore}\n depth={0}\n closeAll={closeAll}\n registerSurface={registerSurface}\n virtualization={virtualization}\n menuType=\"dropdown\"\n closeOnOutsidePress={closeOnOutsidePress}\n getQualifiedRowId={getQualifiedRowId}\n componentName=\"dropdown-menu\"\n >\n <Popover.Root\n {...rest}\n open={open}\n onOpenChange={handlePopoverOpenChange}\n onOpenChangeComplete={handleOpenChangeComplete}\n modal={modal}\n >\n {children}\n </Popover.Root>\n </PopupMenuProviders>\n )\n}\n\nexport namespace DropdownMenuRoot {\n export interface Props extends DropdownMenuRootProps {}\n export type OpenChangeEventDetails = DropdownMenuOpenChangeEventDetails\n export type HighlightChangeEventDetails =\n DropdownMenuHighlightChangeEventDetails\n export type Actions = Popover.Root.Actions\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 { usePopupMenuContext } from '../../internal/popup-menu/contexts/popup-menu-context.js'\nimport { REASONS } from '../../utils/events/index.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { DropdownMenuTriggerDataAttributes } from './trigger.data-attrs.js'\n\nexport { DropdownMenuTriggerDataAttributes }\n\nexport interface DropdownMenuTriggerState extends Record<string, unknown> {\n /**\n * Whether the dropdown menu is open.\n */\n open: boolean\n /**\n * Whether the trigger is disabled.\n */\n disabled: boolean\n}\n\nexport interface DropdownMenuTriggerProps\n extends ComponentProps<'button', DropdownMenuTrigger.State> {\n /**\n * Whether the trigger is disabled.\n */\n disabled?: boolean\n /**\n * Whether the menu opens when hovering the trigger.\n * @default false\n */\n openOnHover?: boolean\n /**\n * Delay before opening on hover (in milliseconds).\n * Only applies when `openOnHover` is true.\n * @default 100\n */\n delay?: number\n /**\n * Delay before closing when pointer leaves (in milliseconds).\n * Only applies when `openOnHover` is true.\n * @default 0\n */\n closeDelay?: number\n}\n\nconst stateAttributesMapping = {\n open: (value: unknown): Record<string, string> | null =>\n value ? { [DropdownMenuTriggerDataAttributes.popupOpen]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { 'data-disabled': '' } : null,\n}\n\n/**\n * Inner component that renders using useRender.\n */\nconst DropdownMenuTriggerInner = React.forwardRef<\n HTMLButtonElement,\n DropdownMenuTriggerProps & {\n triggerProps: React.ComponentPropsWithRef<'button'>\n triggerState: { open: boolean; disabled: boolean }\n }\n>(function DropdownMenuTriggerInner(props, forwardedRef) {\n const {\n render,\n children,\n disabled,\n className,\n style,\n triggerProps,\n triggerState,\n openOnHover,\n delay,\n closeDelay,\n ...rest\n } = props\n\n const state: DropdownMenuTrigger.State = React.useMemo(\n () => ({\n open: triggerState.open,\n disabled: triggerState.disabled,\n }),\n [triggerState.open, triggerState.disabled],\n )\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...triggerProps,\n ...rest,\n [DropdownMenuTriggerDataAttributes.slot]: '',\n className,\n style,\n children,\n },\n defaultTagName: 'button',\n })\n})\n\n/**\n * A button that opens the dropdown menu.\n * Renders a `<button>` element.\n *\n * Supports `openOnHover` to open the menu when hovering the trigger,\n * with configurable `delay` and `closeDelay`.\n *\n * When `closeOnOutsidePress` is set to `'pointerdown'` on the Root,\n * the trigger will close the menu immediately on pointerdown when open.\n */\nexport const DropdownMenuTrigger = React.forwardRef<\n HTMLButtonElement,\n DropdownMenuTrigger.Props\n>(function DropdownMenuTrigger(props, forwardedRef) {\n const { disabled, openOnHover, delay, closeDelay, ...rest } = props\n\n const { store, closeAll, closeOnOutsidePress } = usePopupMenuContext()\n const isOpen = store.useState('open')\n\n // We need to intercept pointerdown before it reaches Popover.Trigger\n // This ref tracks the element so we can add a one-time click blocker\n const triggerRef = React.useRef<HTMLButtonElement | null>(null)\n\n // Combine refs\n const setRef = React.useCallback(\n (element: HTMLButtonElement | null) => {\n triggerRef.current = element\n if (typeof forwardedRef === 'function') {\n forwardedRef(element)\n } else if (forwardedRef) {\n forwardedRef.current = element\n }\n },\n [forwardedRef],\n )\n\n // Handle pointerdown to close on press when open\n React.useEffect(() => {\n const trigger = triggerRef.current\n if (!trigger || closeOnOutsidePress !== 'pointerdown') return\n\n const handlePointerDown = (event: PointerEvent) => {\n // If menu is open, close it immediately and block the click\n if (isOpen) {\n closeAll(REASONS.triggerPress, event)\n\n // Block the upcoming click from reaching Popover.Trigger\n // This prevents the toggle behavior from reopening the menu\n trigger.addEventListener(\n 'click',\n (clickEvent) => {\n clickEvent.stopPropagation()\n clickEvent.preventDefault()\n },\n { once: true, capture: true },\n )\n }\n }\n\n // Use capture phase to see the event before Popover.Trigger\n trigger.addEventListener('pointerdown', handlePointerDown, true)\n return () => {\n trigger.removeEventListener('pointerdown', handlePointerDown, true)\n }\n }, [isOpen, closeAll, closeOnOutsidePress])\n\n return (\n <Popover.Trigger\n ref={setRef}\n disabled={disabled}\n openOnHover={openOnHover}\n delay={delay}\n closeDelay={closeDelay}\n render={(triggerProps, triggerState) => (\n <DropdownMenuTriggerInner\n {...rest}\n disabled={disabled}\n triggerProps={triggerProps}\n triggerState={triggerState}\n ref={triggerProps.ref as React.Ref<HTMLButtonElement>}\n />\n )}\n />\n )\n})\n\nexport namespace DropdownMenuTrigger {\n export interface Props extends DropdownMenuTriggerProps {}\n export type State = DropdownMenuTriggerState\n}\n","export enum DropdownMenuTriggerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-trigger'}\n */\n slot = 'bazzaui-dropdown-menu-trigger',\n /**\n * Present when the corresponding dropdown menu is open.\n */\n popupOpen = 'data-popup-open',\n /**\n * Present when the trigger is pressed.\n */\n pressed = 'data-pressed',\n}\n","export enum DropdownMenuArrowDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-arrow'}\n */\n slot = 'bazzaui-dropdown-menu-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","export enum DropdownMenuBackdropDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-backdrop'}\n */\n slot = 'bazzaui-dropdown-menu-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","export enum DropdownMenuCheckboxItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-checkbox-item'}\n */\n slot = 'bazzaui-dropdown-menu-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\nexport enum DropdownMenuCheckboxItemIndicatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-checkbox-item-indicator'}\n */\n slot = 'bazzaui-dropdown-menu-checkbox-item-indicator',\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","export enum DropdownMenuEmptyDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-empty'}\n */\n slot = 'bazzaui-dropdown-menu-empty',\n}\n","export enum DropdownMenuGroupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-group'}\n */\n slot = 'bazzaui-dropdown-menu-group',\n}\n","export enum DropdownMenuGroupLabelDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-group-label'}\n */\n slot = 'bazzaui-dropdown-menu-group-label',\n}\n","export const DropdownMenuIconDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-icon'}\n */\n slot: 'bazzaui-dropdown-menu-icon',\n /** Present when the popup is open. */\n open: 'data-popup-open',\n} as const\n","export enum DropdownMenuInputDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-input'}\n */\n slot = 'bazzaui-dropdown-menu-input',\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","export enum DropdownMenuItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-item'}\n */\n slot = 'bazzaui-dropdown-menu-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","export enum DropdownMenuListDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-list'}\n */\n slot = 'bazzaui-dropdown-menu-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","export enum DropdownMenuPopupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-popup'}\n */\n slot = 'bazzaui-dropdown-menu-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","export enum DropdownMenuPositionerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-positioner'}\n */\n slot = 'bazzaui-dropdown-menu-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","export enum DropdownMenuRadioGroupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-radio-group'}\n */\n slot = 'bazzaui-dropdown-menu-radio-group',\n /**\n * Present when the radio group is disabled.\n */\n disabled = 'data-disabled',\n}\n","export enum DropdownMenuRadioItemDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-radio-item'}\n */\n slot = 'bazzaui-dropdown-menu-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\nexport enum DropdownMenuRadioItemIndicatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-radio-item-indicator'}\n */\n slot = 'bazzaui-dropdown-menu-radio-item-indicator',\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","export const DropdownMenuScrollArrowDataAttributes = {\n /**\n * Identifies the component part for scroll up arrow.\n * @type {'bazzaui-dropdown-menu-scroll-up-arrow'}\n */\n slotUp: 'bazzaui-dropdown-menu-scroll-up-arrow',\n /**\n * Identifies the component part for scroll down arrow.\n * @type {'bazzaui-dropdown-menu-scroll-down-arrow'}\n */\n slotDown: 'bazzaui-dropdown-menu-scroll-down-arrow',\n /**\n * Direction of the scroll arrow.\n * @type {'up' | 'down'}\n */\n direction: 'data-direction',\n /**\n * Side of the popup.\n * @type {'top' | 'bottom' | 'left' | 'right'}\n */\n side: 'data-side',\n} as const\n","export enum DropdownMenuSeparatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-separator'}\n */\n slot = 'bazzaui-dropdown-menu-separator',\n}\n","export enum DropdownMenuShortcutDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-shortcut'}\n */\n slot = 'bazzaui-dropdown-menu-shortcut',\n /**\n * Present when the parent item is highlighted.\n */\n highlighted = 'data-highlighted',\n}\n","export enum DropdownMenuSubmenuTriggerDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-submenu-trigger'}\n */\n slot = 'bazzaui-dropdown-menu-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\nexport enum DropdownMenuSubmenuTriggerIndicatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-submenu-trigger-indicator'}\n */\n slot = 'bazzaui-dropdown-menu-submenu-trigger-indicator',\n /**\n * Present when the submenu popup is open.\n */\n popupOpen = 'data-popup-open',\n}\n","export enum DropdownMenuSurfaceDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-dropdown-menu-surface'}\n */\n slot = 'bazzaui-dropdown-menu-surface',\n}\n","// ============================================================================\n// Select Parts\n// ============================================================================\n// Re-exports shared components from internal/popup-menu with Select-specific\n// Root, Trigger, Value, Item, ItemLabel, and ItemIndicator components.\n\n// Re-export VirtualItem type from internal/listbox\nexport type { VirtualItem } from '../internal/listbox/index.js'\n\n// Re-export shared components from internal/popup-menu\nexport {\n PopupMenuArrow as Arrow,\n PopupMenuBackdrop as Backdrop,\n PopupMenuEmpty as Empty,\n // Structure\n PopupMenuGroup as Group,\n PopupMenuGroupLabel as GroupLabel,\n // Trigger components\n PopupMenuIcon as Icon,\n PopupMenuInput as Input,\n PopupMenuList as List,\n // Positioning & Container\n PopupMenuPortal as Portal,\n // Scroll indicators\n PopupMenuScrollDownArrow as ScrollDownArrow,\n PopupMenuScrollUpArrow as ScrollUpArrow,\n PopupMenuSeparator as Separator,\n} from '../internal/popup-menu/index.js'\nexport { SelectItem as Item } from './item/item.js'\nexport { SelectItemIndicator as ItemIndicator } from './item-indicator/item-indicator.js'\nexport { SelectItemLabel as ItemLabel } from './item-label/item-label.js'\n// Select-specific Popup with alignItemWithTriggerActive state\nexport type { SelectPopupProps, SelectPopupState } from './popup/popup.js'\nexport { SelectPopup as Popup } from './popup/popup.js'\n// Custom Select Positioner with alignItemWithTrigger support\nexport { SelectPositioner as Positioner } from './positioner/positioner.js'\n// Select-specific components\nexport { SelectRoot as Root } from './root/root.js'\n// Select-specific Surface with alignItemWithTrigger auto-highlight support\nexport { SelectSurface as Surface } from './surface/surface.js'\nexport { SelectTrigger as Trigger } from './trigger/trigger.js'\nexport { SelectValue as Value } from './value/value.js'\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { usePopupMenuItem } from '../../internal/popup-menu/index.js'\nimport {\n compareItemEquality,\n itemIncludes,\n removeItem,\n} from '../../utils/item-equality.js'\nimport {\n resolveLabel,\n stringifyAsValue,\n} from '../../utils/resolve-value-label.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useSelectContext } from '../contexts/select-context.js'\nimport { SelectItemDataAttributes } from './item.data-attrs.js'\nimport {\n SelectItemContext,\n type SelectItemContextValue,\n} from './item-context.js'\n\nexport { SelectItemDataAttributes }\n\nexport interface SelectItemState 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.\n */\n selected: boolean\n}\n\nexport interface SelectItemProps<Value = unknown>\n extends ComponentProps<'div', SelectItem.State> {\n /**\n * The value of this item. Required and must be unique within the Select.\n * Can be a primitive or an object.\n */\n value: Value\n\n /**\n * Text value to use for display in Select.Value when this item is selected.\n * If not provided, the text content of the item will be used.\n * For object values, this can be auto-detected from `{ label }` shape.\n */\n textValue?: 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.\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\nconst stateAttributesMapping = {\n highlighted: (value: unknown): Record<string, string> | null =>\n value ? { [SelectItemDataAttributes.highlighted]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [SelectItemDataAttributes.disabled]: '' } : null,\n selected: (value: unknown): Record<string, string> | null =>\n value ? { [SelectItemDataAttributes.selected]: '' } : null,\n}\n\n/**\n * Helper to resolve label from items prop (for legacy string-keyed items)\n */\nfunction resolveLabelFromItems(\n items:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n | undefined,\n value: string,\n): React.ReactNode | undefined {\n if (!items) return undefined\n\n if (Array.isArray(items)) {\n const item = items.find((i) => i.value === value)\n return item?.label\n }\n\n return items[value]\n}\n\n/**\n * A selectable item in the select dropdown.\n * Renders a `<div>` element with role=\"option\".\n *\n * @template Value - The type of the item value (can be a primitive or object)\n */\nfunction SelectItemImpl<Value = unknown>(\n props: SelectItemProps<Value>,\n forwardedRef: React.ForwardedRef<HTMLDivElement>,\n) {\n const {\n value,\n textValue: textValueProp,\n keywords: keywordsProp,\n disabled = false,\n onSelect,\n forceMount = false,\n render,\n className,\n style,\n onClick,\n onPointerDown,\n onPointerMove,\n children,\n ...rest\n } = props\n\n const selectContext = useSelectContext<Value>()\n\n // Serialize value for registry key and internal lookups\n const serializedValue = React.useMemo(\n () => stringifyAsValue(value, selectContext.itemToStringValue),\n [value, selectContext.itemToStringValue],\n )\n\n // Resolve label from items prop (for auto-populating textValue and keywords)\n // This works for legacy string-keyed items\n const labelFromItems = React.useMemo(\n () => resolveLabelFromItems(selectContext.items, serializedValue),\n [selectContext.items, serializedValue],\n )\n\n // Auto-resolve label from object value shape { label }\n const labelFromObjectValue = React.useMemo(\n () => resolveLabel(value, selectContext.itemToStringLabel),\n [value, selectContext.itemToStringLabel],\n )\n\n // Auto-populate textValue: explicit prop > label from items (if string) > label from object > undefined\n const textValue = React.useMemo(() => {\n if (textValueProp !== undefined) return textValueProp\n if (typeof labelFromItems === 'string') return labelFromItems\n // For object values, use the resolved label\n if (labelFromObjectValue && labelFromObjectValue !== serializedValue) {\n return labelFromObjectValue\n }\n return undefined\n }, [textValueProp, labelFromItems, labelFromObjectValue, serializedValue])\n\n // Auto-add label to keywords for search/filter\n const keywords = React.useMemo(() => {\n const labelStr =\n typeof labelFromItems === 'string'\n ? labelFromItems\n : labelFromObjectValue && labelFromObjectValue !== serializedValue\n ? labelFromObjectValue\n : undefined\n if (!labelStr) return keywordsProp\n if (!keywordsProp) return [labelStr]\n // Only add if not already included\n if (keywordsProp.includes(labelStr)) return keywordsProp\n return [...keywordsProp, labelStr]\n }, [keywordsProp, labelFromItems, labelFromObjectValue, serializedValue])\n\n const textRef = React.useRef<string | undefined>(textValue)\n\n // Track if this item is selected using custom equality\n const selected = selectContext.multiple\n ? itemIncludes(\n selectContext.values,\n value,\n selectContext.isItemEqualToValue,\n )\n : selectContext.value != null &&\n selectContext.value !== '' &&\n compareItemEquality(\n selectContext.value,\n value,\n selectContext.isItemEqualToValue,\n )\n\n // Determine close behavior: single-select closes, multi-select stays open\n const closeOnClick = !selectContext.multiple\n\n const item = usePopupMenuItem({\n value: serializedValue,\n keywords,\n disabled,\n forceMount,\n closeOnClick,\n children,\n })\n\n // Register the select handler that updates the value\n React.useEffect(() => {\n const handleSelect = () => {\n if (disabled) return\n\n if (selectContext.multiple) {\n // Toggle value in array using custom equality\n const newValues = selected\n ? removeItem(\n selectContext.values,\n value,\n selectContext.isItemEqualToValue,\n )\n : [...selectContext.values, value]\n selectContext.onValuesChange(newValues)\n } else {\n // Set single value\n selectContext.onValueChange(value)\n }\n\n onSelect?.()\n }\n return item.registerSelect(handleSelect)\n }, [disabled, selectContext, value, selected, onSelect, item])\n\n // Register item text for Select.Value display\n React.useEffect(() => {\n // Use textValue if provided, otherwise extract from children\n const text = textRef.current\n if (text) {\n return selectContext.registerItemText(serializedValue, text)\n }\n }, [serializedValue, selectContext])\n\n // Update text ref when children might have changed (for extraction)\n React.useEffect(() => {\n if (!textValue && typeof children === 'string') {\n textRef.current = children\n selectContext.registerItemText(serializedValue, children)\n }\n }, [children, textValue, serializedValue, selectContext])\n\n const state: SelectItem.State = React.useMemo(\n () => ({\n highlighted: item.isHighlighted,\n disabled,\n selected,\n }),\n [item.isHighlighted, disabled, selected],\n )\n\n const itemContextValue: SelectItemContextValue<Value> = React.useMemo(\n () => ({\n id: item.id,\n value,\n textValue,\n highlighted: item.isHighlighted,\n disabled,\n selected,\n }),\n [item.id, value, textValue, item.isHighlighted, disabled, selected],\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 const element = useRender({\n render,\n ref: [item.ref, forwardedRef],\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n [SelectItemDataAttributes.slot]: '',\n id: item.id,\n role: 'option',\n tabIndex: -1,\n 'aria-selected': selected,\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 <SelectItemContext.Provider\n value={itemContextValue as SelectItemContextValue}\n >\n {element}\n </SelectItemContext.Provider>\n )\n}\n\nexport const SelectItem = React.forwardRef(SelectItemImpl) as <Value = unknown>(\n props: SelectItemProps<Value> & React.RefAttributes<HTMLDivElement>,\n) => React.ReactElement | null\n\nexport namespace SelectItem {\n export type State = SelectItemState\n export interface Props<Value = unknown> extends SelectItemProps<Value> {}\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { ItemEqualityComparer } from '../../utils/item-equality.js'\n\n// ============================================================================\n// Select Context\n// ============================================================================\n// Provides value management and form integration for Select components.\n// Separate from PopupMenuContext to handle Select-specific concerns.\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 Select components.\n * Provides value state, callbacks, and form integration.\n *\n * @template Value - The type of the select value (can be a primitive or object)\n */\nexport interface SelectContextValue<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 select 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 trigger.\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 // ===== 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 select is disabled */\n disabled: boolean\n /** Placeholder text when no value selected */\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 trigger element */\n triggerRef: React.RefObject<HTMLElement | null>\n /** Ref to the value display element (text in trigger) */\n valueRef: React.RefObject<HTMLElement | null>\n /** Ref to the selected item's text element */\n selectedItemTextRef: React.MutableRefObject<HTMLElement | null>\n /** Ref to the first item's text element (used when no selection for alignItemWithTrigger) */\n firstItemTextRef: React.MutableRefObject<HTMLElement | null>\n /** Callback to set the trigger element */\n setTriggerElement: (element: HTMLElement | null) => void\n /** Callback to set the value element */\n setValueElement: (element: HTMLElement | null) => void\n\n // ===== Positioner Callback Registration =====\n /** Register a callback to reset positioning state after close animation */\n registerResetPositioningCallback: (\n callback: (() => void) | null,\n ) => () => void\n}\n\nconst SelectContext = React.createContext<SelectContextValue<unknown> | null>(\n null,\n)\n\n/**\n * Hook to access the Select context.\n * Throws if used outside a Select.Root.\n */\nexport function useSelectContext<Value = unknown>(): SelectContextValue<Value> {\n const context = React.useContext(SelectContext)\n if (!context) {\n throw new Error('Select components must be used within a Select.Root')\n }\n return context as SelectContextValue<Value>\n}\n\n/**\n * Hook to optionally access the Select context.\n * Returns null if used outside a Select.Root.\n */\nexport function useMaybeSelectContext<\n Value = unknown,\n>(): SelectContextValue<Value> | null {\n return React.useContext(SelectContext) as SelectContextValue<Value> | null\n}\n\nexport { SelectContext }\n","export const SelectItemDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-item'}\n */\n slot: 'bazzaui-select-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 * Present when the item is currently selected.\n */\n selected: 'data-selected',\n} as const\n","'use client'\n\nimport * as React from 'react'\n\n// ============================================================================\n// Select Item Context\n// ============================================================================\n// Provides select-specific item state to child components.\n\nexport interface SelectItemContextValue<Value = unknown> {\n /** Unique ID for this item (for DOM id attribute) */\n id: string\n /** The value of this item */\n value: Value\n /** The text value/label for this item */\n textValue: string | undefined\n /** Whether the item is highlighted */\n highlighted: boolean\n /** Whether the item is disabled */\n disabled: boolean\n /** Whether the item is selected */\n selected: boolean\n}\n\nconst SelectItemContext = React.createContext<SelectItemContextValue | null>(\n null,\n)\n\nexport function useSelectItemContext<\n Value = unknown,\n>(): SelectItemContextValue<Value> {\n const context = React.useContext(SelectItemContext)\n if (!context) {\n throw new Error(\n 'Select.Item child components must be used within a Select.Item',\n )\n }\n return context as SelectItemContextValue<Value>\n}\n\nexport function useMaybeSelectItemContext<\n Value = unknown,\n>(): SelectItemContextValue<Value> | null {\n return React.useContext(\n SelectItemContext,\n ) as SelectItemContextValue<Value> | null\n}\n\nexport { SelectItemContext }\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 { useSelectItemContext } from '../item/item-context.js'\nimport { SelectItemIndicatorDataAttributes } from './item-indicator.data-attrs.js'\n\nexport { SelectItemIndicatorDataAttributes }\n\nexport interface SelectItemIndicatorState extends Record<string, unknown> {\n /**\n * Whether the item is selected.\n */\n selected: boolean\n}\n\nexport interface SelectItemIndicatorProps\n extends Omit<ComponentProps<'span', SelectItemIndicator.State>, 'children'> {\n /**\n * Whether to force render even when the item is not selected.\n * @default false\n */\n forceMount?: boolean\n\n /**\n * Whether to keep the element mounted even when not selected.\n * Unlike forceMount, this still conditionally renders children.\n * Useful for checkbox-style indicators where the container is always visible.\n * @default false\n */\n keepMounted?: boolean\n\n /**\n * Content to render. Can be a ReactNode or a function that receives state.\n */\n children?:\n | React.ReactNode\n | ((state: SelectItemIndicator.State) => React.ReactNode)\n}\n\nconst stateAttributesMapping = {\n selected: (value: unknown): Record<string, string> | null =>\n value ? { [SelectItemIndicatorDataAttributes.selected]: '' } : null,\n}\n\n/**\n * Indicator that shows when the item is selected.\n * Typically renders a checkmark icon.\n * Only renders when the item is selected (unless forceMount or keepMounted is true).\n * Renders a `<span>` element.\n */\nexport const SelectItemIndicator = React.forwardRef<\n HTMLSpanElement,\n SelectItemIndicator.Props\n>(function SelectItemIndicator(props, forwardedRef) {\n const {\n render,\n className,\n style,\n forceMount = false,\n keepMounted = false,\n children,\n ...rest\n } = props\n\n const itemContext = useSelectItemContext()\n const selected = itemContext.selected\n\n const state: SelectItemIndicator.State = React.useMemo(\n () => ({ selected }),\n [selected],\n )\n\n // Determine if we should render\n const shouldRender = forceMount || keepMounted || selected\n\n // For keepMounted, only render children when selected\n const content =\n typeof children === 'function'\n ? children(state)\n : keepMounted && !selected\n ? null\n : children\n\n const element = useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n [SelectItemIndicatorDataAttributes.slot]: '',\n 'aria-hidden': true,\n className,\n style,\n children: content,\n },\n defaultTagName: 'span',\n })\n\n if (!shouldRender) {\n return null\n }\n\n return element\n})\n\nexport namespace SelectItemIndicator {\n export interface Props extends SelectItemIndicatorProps {}\n export type State = SelectItemIndicatorState\n}\n","export const SelectItemIndicatorDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-item-indicator'}\n */\n slot: 'bazzaui-select-item-indicator',\n /**\n * Present when the parent item is selected.\n */\n selected: 'data-selected',\n} as const\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { stringifyAsValue } from '../../utils/resolve-value-label.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useSelectContext } from '../contexts/select-context.js'\nimport { useSelectItemContext } from '../item/item-context.js'\nimport { SelectItemLabelDataAttributes } from './item-label.data-attrs.js'\n\nexport { SelectItemLabelDataAttributes }\n\nexport interface SelectItemLabelState extends Record<string, unknown> {\n /**\n * The serialized string key for the parent item's value.\n * For object values, this is the result of `itemToStringValue` or the auto-detected `.value` property.\n */\n value: string\n /**\n * Whether the parent item is selected.\n */\n selected: boolean\n /**\n * Whether the parent item is highlighted.\n */\n highlighted: boolean\n /**\n * Whether the parent item is disabled.\n */\n disabled: boolean\n}\n\nexport interface SelectItemLabelProps\n extends ComponentProps<'span', SelectItemLabel.State> {}\n\n/**\n * Helper to resolve label from items prop\n */\nfunction resolveLabelFromItems(\n items:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n | undefined,\n valueKey: string,\n): React.ReactNode | undefined {\n if (!items) return undefined\n\n if (Array.isArray(items)) {\n const item = items.find((i) => i.value === valueKey)\n return item?.label\n }\n\n return items[valueKey]\n}\n\n/**\n * The label/text content of a Select.Item.\n *\n * When no children are provided, automatically renders the label from the\n * `items` prop passed to `Select.Root`. If children are provided, they\n * override the automatic label.\n *\n * Also captures the text for display in `Select.Value` when the item is selected,\n * and provides the text element reference for `alignItemWithTrigger` positioning.\n *\n * Renders a `<span>` element.\n */\nexport const SelectItemLabel = React.forwardRef<\n HTMLSpanElement,\n SelectItemLabel.Props\n>(function SelectItemLabel(props, forwardedRef) {\n const { render, className, style, children, ...rest } = props\n\n const selectContext = useSelectContext()\n const itemContext = useSelectItemContext()\n const textRef = React.useRef<HTMLSpanElement | null>(null)\n\n // Serialize the item value to a string key for registry lookups\n const valueKey = stringifyAsValue(\n itemContext.value,\n selectContext.itemToStringValue,\n )\n\n // Resolve label content:\n // 1. Explicit children (override)\n // 2. Label from items prop lookup\n // 3. textValue from item context\n // 4. Fall back to the serialized value key\n const resolvedLabel = React.useMemo(() => {\n if (children !== undefined) {\n return children\n }\n\n const labelFromItems = resolveLabelFromItems(selectContext.items, valueKey)\n if (labelFromItems !== undefined) {\n return labelFromItems\n }\n\n if (itemContext.textValue !== undefined) {\n return itemContext.textValue\n }\n\n return valueKey\n }, [children, selectContext.items, valueKey, itemContext.textValue])\n\n // Build state for render prop and className/style functions\n const state: SelectItemLabel.State = React.useMemo(\n () => ({\n value: valueKey,\n selected: itemContext.selected,\n highlighted: itemContext.highlighted,\n disabled: itemContext.disabled,\n }),\n [\n valueKey,\n itemContext.selected,\n itemContext.highlighted,\n itemContext.disabled,\n ],\n )\n\n // Register the text content when mounted (for Select.Value display)\n React.useEffect(() => {\n if (typeof resolvedLabel === 'string') {\n return selectContext.registerItemText(valueKey, resolvedLabel)\n }\n }, [resolvedLabel, selectContext, valueKey])\n\n // Merge refs - need to track for positioning AND pass to useRender\n const mergedRef = React.useCallback(\n (node: HTMLSpanElement | null) => {\n textRef.current = node\n\n // Register this element as the selected item text for alignItemWithTrigger positioning\n if (itemContext.selected && node) {\n selectContext.selectedItemTextRef.current = node\n }\n\n // Register as the first item text for alignment fallback\n // Only set if not already set - first non-disabled item to render wins\n // The positioner will prefer selectedItemTextRef over firstItemTextRef\n if (node && !itemContext.disabled) {\n if (!selectContext.firstItemTextRef.current) {\n selectContext.firstItemTextRef.current = node\n }\n }\n },\n [itemContext.selected, itemContext.disabled, selectContext],\n )\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n props: {\n ...rest,\n [SelectItemLabelDataAttributes.slot]: '',\n ref: mergedRef,\n className,\n style,\n children: resolvedLabel,\n },\n defaultTagName: 'span',\n })\n})\n\nexport namespace SelectItemLabel {\n export interface Props extends SelectItemLabelProps {}\n export type State = SelectItemLabelState\n}\n","export const SelectItemLabelDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-item-label'}\n */\n slot: 'bazzaui-select-item-label',\n} as const\n","'use client'\n\nimport { Popover } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport {\n PopupMenuPopup,\n type PopupMenuPopupState,\n} from '../../internal/popup-menu/components/popup/popup.js'\nimport { useSelectPositionerContext } from '../contexts/select-positioner-context.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SelectPopupState extends PopupMenuPopupState {\n /**\n * Whether the popup is currently using align-item-with-trigger positioning.\n * This reflects the actual state, not just the prop value - it will be false\n * if alignment couldn't be applied (e.g., not enough space, no selected item).\n */\n alignItemWithTriggerActive: boolean\n}\n\nexport interface SelectPopupProps\n extends Omit<PopupMenuPopup.Props, 'className'> {\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: SelectPopupState) => string)\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * A container for the select popup contents.\n * Extends PopupMenuPopup with Select-specific state including alignItemWithTriggerActive.\n *\n * Renders a `<div>` element.\n */\nexport const SelectPopup = React.forwardRef<HTMLDivElement, SelectPopup.Props>(\n function SelectPopup(props, forwardedRef) {\n const { className: classNameProp, ...rest } = props\n\n // Get positioner context for alignItemWithTriggerActive\n const positionerContext = useSelectPositionerContext()\n const alignItemWithTriggerActive =\n positionerContext?.alignItemWithTriggerActive ?? false\n\n // Wrap className to include alignItemWithTriggerActive in the state\n const className = React.useMemo(() => {\n if (typeof classNameProp === 'function') {\n return (baseState: PopupMenuPopupState) => {\n const extendedState: SelectPopupState = {\n ...baseState,\n alignItemWithTriggerActive,\n }\n return classNameProp(extendedState)\n }\n }\n return classNameProp\n }, [classNameProp, alignItemWithTriggerActive])\n\n return (\n <PopupMenuPopup\n ref={forwardedRef}\n className={className}\n data-align-item-with-trigger={\n alignItemWithTriggerActive ? '' : undefined\n }\n {...rest}\n />\n )\n },\n)\n\nexport namespace SelectPopup {\n export type Props = SelectPopupProps\n export type State = SelectPopupState\n}\n","'use client'\n\nimport * as React from 'react'\n\n// Types matching Base UI's positioning types\nexport type Side = 'top' | 'bottom' | 'left' | 'right'\nexport type Align = 'start' | 'center' | 'end'\n\n/**\n * Context value for Select Positioner.\n * Provides alignment state for coordinating positioning behavior.\n */\nexport interface SelectPositionerContextValue {\n /**\n * Whether alignItemWithTrigger is actively being used.\n * This may be false even if the prop is true (e.g., fallback scenarios).\n */\n alignItemWithTriggerActive: boolean\n\n /**\n * The rendered side of the popup (or 'none' when using align-item-with-trigger).\n */\n side: Side | 'none'\n\n /**\n * The rendered alignment of the popup.\n */\n align: Align\n\n /**\n * Ref for the scroll up arrow element.\n */\n scrollUpArrowRef: React.RefObject<HTMLDivElement | null>\n\n /**\n * Ref for the scroll down arrow element.\n */\n scrollDownArrowRef: React.RefObject<HTMLDivElement | null>\n\n /**\n * Callback to disable alignItemWithTrigger (fallback to normal positioning).\n */\n setAlignItemWithTriggerActive: (active: boolean) => void\n\n /**\n * Callback to reset positioning state after close animation completes.\n * This preserves positioning during exit animations.\n */\n resetPositioningState: () => void\n}\n\nconst SelectPositionerContext =\n React.createContext<SelectPositionerContextValue | null>(null)\n\n/**\n * Hook to access the Select Positioner context.\n * Returns null if used outside a SelectPositioner.\n */\nexport function useSelectPositionerContext(): SelectPositionerContextValue | null {\n return React.useContext(SelectPositionerContext)\n}\n\nexport { SelectPositionerContext }\n","'use client'\n\nimport { Popover, type PopoverPositionerProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport { usePopupMenuContext } from '../../internal/popup-menu/contexts/popup-menu-context.js'\nimport { useSelectContext } from '../contexts/select-context.js'\nimport {\n type Align,\n SelectPositionerContext,\n type SelectPositionerContextValue,\n type Side,\n} from '../contexts/select-positioner-context.js'\nimport { SelectPositionerDataAttributes } from './positioner.data-attrs.js'\n\nexport { SelectPositionerDataAttributes }\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SelectPositionerProps extends PopoverPositionerProps {\n /**\n * Whether the positioner overlaps the trigger so the selected item's text\n * is aligned with the trigger's value text.\n *\n * This is automatically disabled if:\n * - There is not enough space in the viewport\n * - The trigger is too close to the viewport edges\n * - Touch input is detected (better UX to show full list)\n *\n * @default true\n */\n alignItemWithTrigger?: boolean\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst MARGIN = 10 // Viewport margin\nconst MIN_HEIGHT = 100 // Minimum popup height before fallback\nconst TRIGGER_COLLISION_THRESHOLD = 20 // Distance from viewport edge\n\n// ============================================================================\n// Helper: Calculate alignment position\n// ============================================================================\n\ninterface CalculatePositionParams {\n triggerElement: HTMLElement\n positioner: HTMLDivElement\n valueElement: HTMLElement | null\n /** The text element to align with (selected item or first item) */\n itemText: HTMLElement | null\n}\n\ninterface CalculatePositionResult {\n shouldFallback: boolean\n left: number\n top: number\n maxHeight?: number\n}\n\nfunction calculateAlignmentPosition(\n params: CalculatePositionParams,\n): CalculatePositionResult {\n const { triggerElement, positioner, valueElement, itemText } = params\n\n const triggerRect = triggerElement.getBoundingClientRect()\n const positionerRect = positioner.getBoundingClientRect()\n const viewportHeight = document.documentElement.clientHeight\n const viewportWidth = document.documentElement.clientWidth\n\n // Check if trigger is too close to viewport edges\n const triggerTooCloseToTop = triggerRect.top < TRIGGER_COLLISION_THRESHOLD\n const triggerTooCloseToBottom =\n triggerRect.bottom > viewportHeight - TRIGGER_COLLISION_THRESHOLD\n\n // Check if popup is too small\n const popupTooSmall = positionerRect.height < MIN_HEIGHT\n\n if (triggerTooCloseToTop || triggerTooCloseToBottom || popupTooSmall) {\n return { shouldFallback: true, left: 0, top: 0 }\n }\n\n // Fallback if no item text element to align with\n if (!itemText) {\n return { shouldFallback: true, left: 0, top: 0 }\n }\n\n let offsetX = 0\n let offsetY = 0\n\n // Calculate offsets based on text elements if available\n if (itemText && valueElement) {\n const valueRect = valueElement.getBoundingClientRect()\n const textRect = itemText.getBoundingClientRect()\n\n // Align text baselines (horizontal)\n const valueLeftFromTrigger = valueRect.left - triggerRect.left\n const textLeftFromPositioner = textRect.left - positionerRect.left\n offsetX = valueLeftFromTrigger - textLeftFromPositioner\n\n // Align text centers (vertical)\n const valueCenterY = valueRect.top + valueRect.height / 2\n const textCenterFromPositioner =\n textRect.top - positionerRect.top + textRect.height / 2\n offsetY = valueCenterY - positionerRect.top - textCenterFromPositioner\n }\n\n // Calculate final position\n let left = triggerRect.left + offsetX\n let top = positionerRect.top + offsetY\n\n // Clamp to viewport with margins\n const maxLeft = viewportWidth - positionerRect.width - MARGIN\n const maxTop = viewportHeight - positionerRect.height - MARGIN\n\n left = Math.max(MARGIN, Math.min(left, maxLeft))\n top = Math.max(MARGIN, Math.min(top, maxTop))\n\n // Check if we have enough height\n const availableHeight = viewportHeight - 2 * MARGIN\n if (positionerRect.height > availableHeight) {\n return {\n shouldFallback: false,\n left,\n top: MARGIN,\n maxHeight: availableHeight,\n }\n }\n\n return { shouldFallback: false, left, top }\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Positions the select popup against its trigger.\n * Supports aligning the selected item with the trigger for a native select feel.\n *\n * Renders a `<div>` element.\n */\nexport const SelectPositioner = React.forwardRef<\n HTMLDivElement,\n SelectPositioner.Props\n>(function SelectPositioner(props, forwardedRef) {\n const {\n alignItemWithTrigger = true,\n side: sideProp = 'bottom',\n align: alignProp = 'start',\n sideOffset = 0,\n className,\n style,\n children,\n ...rest\n } = props\n\n const popupMenuContext = usePopupMenuContext()\n const selectContext = useSelectContext()\n\n // Get open state from the store\n const open = popupMenuContext.store.useState('open')\n\n // Local state - track if alignment is active and if initial positioning is done\n const [alignItemWithTriggerActive, setAlignItemWithTriggerActive] =\n React.useState(alignItemWithTrigger)\n const [positionState, setPositionState] = React.useState<{\n positioned: boolean\n left?: number\n top?: number\n maxHeight?: number\n }>({ positioned: false })\n\n const positionerRef = React.useRef<HTMLDivElement | null>(null)\n const scrollUpArrowRef = React.useRef<HTMLDivElement | null>(null)\n const scrollDownArrowRef = React.useRef<HTMLDivElement | null>(null)\n\n // Reset positioning state after close animation completes\n // This preserves positioning during exit animations via onOpenChangeComplete\n const resetPositioningState = React.useCallback(() => {\n setAlignItemWithTriggerActive(alignItemWithTrigger)\n setPositionState({ positioned: false })\n }, [alignItemWithTrigger])\n\n // Register reset callback with SelectContext so Root can call it after animation\n React.useEffect(() => {\n const cleanup = selectContext.registerResetPositioningCallback(\n resetPositioningState,\n )\n return cleanup\n }, [selectContext, resetPositioningState])\n\n // Calculate position when alignItemWithTrigger is active\n // We use useLayoutEffect to calculate before paint, preventing flash\n // The calculation is done synchronously to ensure it completes before browser paint\n React.useLayoutEffect(() => {\n if (!open || !alignItemWithTriggerActive || positionState.positioned) {\n return\n }\n\n const positioner = positionerRef.current\n const triggerElement = selectContext.triggerRef.current\n const valueElement = selectContext.valueRef.current\n const selectedItemText = selectContext.selectedItemTextRef.current\n const firstItemText = selectContext.firstItemTextRef.current\n\n if (!positioner || !triggerElement) {\n return\n }\n\n // Use selected item text if available, otherwise fall back to first item text\n // This enables alignment even when no item is selected (aligns to first item)\n const itemText = selectedItemText ?? firstItemText\n\n // Calculate position synchronously - useLayoutEffect runs after DOM mutations\n // but before paint, so getBoundingClientRect will return correct values\n const result = calculateAlignmentPosition({\n triggerElement,\n positioner,\n valueElement,\n itemText,\n })\n\n if (result.shouldFallback) {\n setAlignItemWithTriggerActive(false)\n setPositionState({ positioned: true })\n return\n }\n\n setPositionState({\n positioned: true,\n left: result.left,\n top: result.top,\n maxHeight: result.maxHeight,\n })\n }, [\n open,\n alignItemWithTriggerActive,\n positionState.positioned,\n selectContext,\n ])\n\n // Determine rendered side - 'none' when align-item-with-trigger is active\n const renderedSide = alignItemWithTriggerActive ? 'none' : sideProp\n\n // Context value\n const contextValue: SelectPositionerContextValue = React.useMemo(\n () => ({\n alignItemWithTriggerActive,\n side: renderedSide as Side | 'none',\n align: alignProp as Align,\n scrollUpArrowRef,\n scrollDownArrowRef,\n setAlignItemWithTriggerActive,\n resetPositioningState,\n }),\n [\n alignItemWithTriggerActive,\n renderedSide,\n alignProp,\n resetPositioningState,\n ],\n )\n\n // Merge refs\n const mergedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n positionerRef.current = node\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [forwardedRef],\n )\n\n // When alignItemWithTrigger is active:\n // - Use visibility:hidden (NOT hidden attribute) to hide while measuring\n // The hidden attribute prevents the element from having dimensions!\n // - Apply fixed positioning with calculated coordinates after measurement\n // - Show element after positioning is done\n\n const shouldHide =\n open && alignItemWithTriggerActive && !positionState.positioned\n\n // Build position styles for alignment mode\n const alignmentStyles: React.CSSProperties =\n alignItemWithTriggerActive && positionState.positioned\n ? {\n position: 'fixed',\n left: positionState.left,\n top: positionState.top,\n ...(positionState.maxHeight\n ? { maxHeight: positionState.maxHeight }\n : {}),\n }\n : {}\n\n return (\n <SelectPositionerContext.Provider value={contextValue}>\n <Popover.Positioner\n ref={mergedRef}\n side={alignItemWithTriggerActive ? undefined : sideProp}\n align={alignItemWithTriggerActive ? undefined : alignProp}\n sideOffset={alignItemWithTriggerActive ? 0 : sideOffset}\n className={className}\n style={{\n ...style,\n ...alignmentStyles,\n // Use visibility:hidden instead of hidden attribute so element can be measured\n ...(shouldHide ? { visibility: 'hidden' } : {}),\n }}\n {...{ [SelectPositionerDataAttributes.slot]: '' }}\n {...rest}\n >\n {children}\n </Popover.Positioner>\n </SelectPositionerContext.Provider>\n )\n})\n\nexport namespace SelectPositioner {\n export type Props = SelectPositionerProps\n export type State = Popover.Positioner.State\n}\n","export const SelectPositionerDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-positioner'}\n */\n slot: 'bazzaui-select-positioner',\n} as const\n","'use client'\n\nimport { Popover, type PopoverRootProps } from '@base-ui/react/popover'\nimport * as React from 'react'\nimport type { VirtualItem } from '../../internal/listbox/index.js'\nimport {\n PopupMenuProviders,\n type UsePopupMenuRootParams,\n usePopupMenuRoot,\n} from '../../internal/popup-menu/index.js'\nimport {\n defaultItemEquality,\n type ItemEqualityComparer,\n} from '../../utils/item-equality.js'\nimport { stringifyAsValue } from '../../utils/resolve-value-label.js'\nimport {\n type ItemTextRegistry,\n SelectContext,\n type SelectContextValue,\n} from '../contexts/select-context.js'\nimport type {\n SelectHighlightChangeEventDetails,\n SelectOpenChangeEventDetails,\n} from '../events.js'\n\n/**\n * Helper type to determine the value type based on the multiple flag.\n */\ntype SelectValue<\n Value,\n Multiple extends boolean | undefined,\n> = Multiple extends true ? Value[] : Value | null\n\nexport interface SelectRootProps<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n> extends Omit<PopoverRootProps, 'open' | 'onOpenChange' | 'defaultOpen'> {\n // ===== Open State =====\n /**\n * Whether the select 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: SelectOpenChangeEventDetails,\n ) => void\n\n /**\n * Callback called after any animations complete when the select opens or closes.\n * Useful for resetting state after exit animations finish.\n */\n onOpenChangeComplete?: (open: boolean) => void\n\n /**\n * Whether the select is initially open.\n * Use for uncontrolled mode.\n * @default false\n */\n defaultOpen?: boolean\n\n // ===== Single Selection =====\n /**\n * Current selected value (single-select mode).\n * Use for controlled mode.\n * Can be a primitive or an object.\n */\n value?: SelectValue<Value, Multiple>\n\n /**\n * Default selected value (single-select mode).\n * Use for uncontrolled mode.\n */\n defaultValue?: SelectValue<Value, Multiple>\n\n /**\n * Callback when the selected value changes (single-select mode).\n */\n onValueChange?: (value: Value) => void\n\n // ===== Multi Selection =====\n /**\n * Whether multi-select mode is enabled.\n * @default false\n */\n multiple?: Multiple\n\n /**\n * Current selected values (multi-select mode).\n * Use for controlled mode.\n */\n values?: Value[]\n\n /**\n * Default selected values (multi-select mode).\n * Use for uncontrolled mode.\n */\n defaultValues?: Value[]\n\n /**\n * Callback when the selected values change (multi-select mode).\n */\n onValuesChange?: (values: Value[]) => void\n\n // ===== Object Value Support =====\n /**\n * Custom comparison logic used to determine if a select 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 /**\n * When the item values are objects (`<Select.Item value={object}>`),\n * this function converts the object value to a string representation\n * for display in the trigger.\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 /**\n * When the item values are objects (`<Select.Item value={object}>`),\n * this function converts the object value to a string representation\n * 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 // ===== Form Integration =====\n /**\n * Form field name for submission.\n * When set, hidden input(s) will be rendered for form submission.\n */\n name?: string\n\n /**\n * Associate with a form by ID.\n */\n form?: string\n\n /**\n * Whether this field is required.\n */\n required?: boolean\n\n /**\n * Whether the select is disabled.\n * @default false\n */\n disabled?: boolean\n\n /**\n * Placeholder text when no value is selected.\n * @default \"Select...\"\n */\n placeholder?: string\n\n /**\n * Data structure of the items rendered in the select popup.\n * When specified, `<Select.Value>` renders the label of the selected item\n * instead of the raw value.\n *\n * Can be a record mapping values to labels, or an array of { value, label } objects.\n * @example\n * ```tsx\n * // Record format\n * <Select.Root items={{ us: 'United States', uk: 'United Kingdom' }}>\n *\n * // Array format\n * <Select.Root items={[\n * { value: 'us', label: 'United States' },\n * { value: 'uk', label: 'United Kingdom' },\n * ]}>\n * ```\n */\n items?:\n | Record<string, React.ReactNode>\n | Array<{ value: string; label: React.ReactNode }>\n\n // ===== Behavior =====\n /**\n * Determines if the select enters a modal state when open.\n *\n * - `true`: user interaction is limited to the select: document page scroll\n * is locked, and pointer interactions on outside elements are disabled.\n * - `false`: user interaction with the rest of the document is allowed.\n * - `'trap-focus'`: focus is trapped inside the select, but document page\n * scroll is not locked and pointer interactions outside of it remain enabled.\n *\n * @default true\n */\n modal?: boolean | 'trap-focus'\n\n // ===== Virtualization =====\n /**\n * Whether virtualization mode is enabled.\n * When true, items should provide an explicit `index` prop and\n * the `virtualItems` 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 virtualItems?: VirtualItem[]\n\n /**\n * Callback when the highlighted item changes.\n * Useful for synchronizing with a virtualizer (e.g., scrollToIndex).\n * Only called when `virtualized={true}`.\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: SelectHighlightChangeEventDetails,\n ) => void\n\n children: React.ReactNode\n}\n\n/**\n * Groups all parts of the select.\n * Manages open state, selection state, and provides context to children.\n * Doesn't render its own HTML element.\n *\n * @template Value - The type of the select value (can be a primitive or object)\n * @template Multiple - Whether multiple selection is enabled\n */\nexport function SelectRoot<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n>(props: SelectRootProps<Value, Multiple>): React.JSX.Element {\n const {\n // Open state\n open: openProp,\n onOpenChange,\n onOpenChangeComplete,\n defaultOpen = false,\n // Single selection\n value: valueProp,\n defaultValue,\n onValueChange,\n // Multi selection\n multiple = false as Multiple,\n values: valuesProp,\n defaultValues,\n onValuesChange,\n // Object value support\n isItemEqualToValue = defaultItemEquality as ItemEqualityComparer<Value>,\n itemToStringLabel,\n itemToStringValue,\n // Form integration\n name,\n form,\n required,\n disabled = false,\n placeholder = 'Select...',\n items,\n // Behavior\n modal = true,\n // Virtualization\n virtualized = false,\n virtualItems,\n onHighlightChange,\n children,\n ...rest\n } = props\n\n // Generate a unique ID for the listbox\n const listId = React.useId()\n\n // ===== Element Refs for Positioning =====\n const triggerRef = React.useRef<HTMLElement | null>(null)\n const valueRef = React.useRef<HTMLElement | null>(null)\n const selectedItemTextRef = React.useRef<HTMLElement | null>(null)\n const firstItemTextRef = React.useRef<HTMLElement | null>(null)\n\n const setTriggerElement = React.useCallback((element: HTMLElement | null) => {\n triggerRef.current = element\n }, [])\n\n const setValueElement = React.useCallback((element: HTMLElement | null) => {\n valueRef.current = element\n }, [])\n\n // ===== Positioner Reset Callback =====\n // Store callback to reset positioning state after close animation\n const resetPositioningCallbackRef = React.useRef<(() => void) | null>(null)\n\n const registerResetPositioningCallback = React.useCallback(\n (callback: (() => void) | null) => {\n resetPositioningCallbackRef.current = callback\n // Return cleanup function\n return () => {\n resetPositioningCallbackRef.current = null\n }\n },\n [],\n )\n\n // ===== Open State =====\n // Use shared hook to create stores and utilities\n const {\n store,\n focusOwnerStore,\n openChainStore,\n registerSurface,\n closeAll,\n virtualization,\n handleOpenChange,\n } = usePopupMenuRoot({\n // Cast to generic type - component handles type safety via narrowed types\n onOpenChange:\n onOpenChange as unknown as UsePopupMenuRootParams['onOpenChange'],\n defaultOpen,\n virtualized,\n items: virtualItems,\n onHighlightChange:\n onHighlightChange as unknown as UsePopupMenuRootParams['onHighlightChange'],\n })\n\n // Sync controlled open prop to store\n store.useControlledProp('open', openProp, defaultOpen)\n\n // Get open state from store for Popover\n const open = store.useState('open')\n\n // ===== Single Selection State =====\n const [internalValue, setInternalValue] = React.useState<Value | null>(\n defaultValue !== undefined ? (defaultValue as Value | null) : null,\n )\n const value: Value | null =\n valueProp !== undefined ? (valueProp as Value | null) : internalValue\n\n const handleValueChange = React.useCallback(\n (newValue: Value) => {\n if (valueProp === undefined) {\n setInternalValue(newValue)\n }\n onValueChange?.(newValue)\n },\n [valueProp, onValueChange],\n )\n\n // ===== Multi Selection State =====\n const [internalValues, setInternalValues] = React.useState<Value[]>(\n defaultValues ?? [],\n )\n const values: Value[] = valuesProp !== undefined ? valuesProp : internalValues\n\n const handleValuesChange = React.useCallback(\n (newValues: Value[]) => {\n if (valuesProp === undefined) {\n setInternalValues(newValues)\n }\n onValuesChange?.(newValues)\n },\n [valuesProp, onValuesChange],\n )\n\n // ===== Item Text Registry =====\n // The registry persists item text even after items unmount (popup closes).\n // This ensures SelectValue can display the correct label for selected values.\n // Text is only overwritten when items re-mount with new text, never deleted.\n const itemTextRegistryRef = React.useRef<ItemTextRegistry>(new Map())\n\n const registerItemText = React.useCallback(\n (itemValue: string, text: string) => {\n itemTextRegistryRef.current.set(itemValue, text)\n // No cleanup - text should persist even when items unmount\n return () => {}\n },\n [],\n )\n\n // ===== Select Context =====\n const selectContextValue: SelectContextValue<Value> = React.useMemo(\n () => ({\n multiple: multiple as boolean,\n value,\n values,\n onValueChange: handleValueChange,\n onValuesChange: handleValuesChange,\n isItemEqualToValue,\n itemToStringLabel,\n itemToStringValue,\n name,\n form,\n required,\n disabled,\n placeholder,\n items,\n itemTextRegistry: itemTextRegistryRef.current,\n registerItemText,\n listId,\n triggerRef,\n valueRef,\n selectedItemTextRef,\n firstItemTextRef,\n setTriggerElement,\n setValueElement,\n registerResetPositioningCallback,\n }),\n [\n multiple,\n value,\n values,\n handleValueChange,\n handleValuesChange,\n isItemEqualToValue,\n itemToStringLabel,\n itemToStringValue,\n name,\n form,\n required,\n disabled,\n placeholder,\n items,\n registerItemText,\n listId,\n setTriggerElement,\n setValueElement,\n registerResetPositioningCallback,\n ],\n )\n\n // ===== Hidden Inputs for Form Submission =====\n const hiddenInputs = React.useMemo(() => {\n if (!name) return null\n\n if (multiple) {\n // Multiple hidden inputs for array submission\n if (values.length > 0) {\n return values.map((v, index) => {\n const serializedValue = stringifyAsValue(v, itemToStringValue)\n return (\n <input\n key={serializedValue}\n type=\"hidden\"\n name={name}\n value={serializedValue}\n form={form}\n required={required && index === 0}\n />\n )\n })\n }\n // Empty hidden input to ensure field is submitted even when empty\n return (\n <input\n type=\"hidden\"\n name={name}\n value=\"\"\n form={form}\n required={required}\n />\n )\n }\n\n // Single hidden input\n return (\n <input\n type=\"hidden\"\n name={name}\n value={value != null ? stringifyAsValue(value, itemToStringValue) : ''}\n form={form}\n required={required}\n />\n )\n }, [name, form, required, multiple, value, values, itemToStringValue])\n\n // Wrapper to adapt Popover's event details to our handleOpenChange\n const handlePopoverOpenChange = React.useCallback(\n (nextOpen: boolean, popoverDetails: Popover.Root.ChangeEventDetails) => {\n // Forward to our internal handler with the reason and event\n handleOpenChange(\n nextOpen,\n popoverDetails.reason as SelectOpenChangeEventDetails['reason'],\n popoverDetails.event,\n )\n },\n [handleOpenChange],\n )\n\n // Handle animation complete - reset positioning state after close animation\n const handleOpenChangeComplete = React.useCallback(\n (nextOpen: boolean) => {\n // Reset positioning state after close animation completes\n // This preserves the aligned position during the exit animation\n if (!nextOpen) {\n resetPositioningCallbackRef.current?.()\n // Clear first item text ref so it can be set fresh on next open\n firstItemTextRef.current = null\n }\n // Call user's callback\n onOpenChangeComplete?.(nextOpen)\n },\n [onOpenChangeComplete],\n )\n\n return (\n <SelectContext.Provider\n value={selectContextValue as SelectContextValue<unknown>}\n >\n <PopupMenuProviders\n store={store}\n focusOwnerStore={focusOwnerStore}\n openChainStore={openChainStore}\n depth={0}\n closeAll={closeAll}\n registerSurface={registerSurface}\n virtualization={virtualization}\n menuType=\"dropdown\"\n componentName=\"select\"\n >\n {hiddenInputs}\n <Popover.Root\n {...rest}\n open={open}\n onOpenChange={handlePopoverOpenChange}\n onOpenChangeComplete={handleOpenChangeComplete}\n modal={modal}\n >\n {children}\n </Popover.Root>\n </PopupMenuProviders>\n </SelectContext.Provider>\n )\n}\n\nexport namespace SelectRoot {\n export interface Props<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n > extends SelectRootProps<Value, Multiple> {}\n export type OpenChangeEventDetails = SelectOpenChangeEventDetails\n export type HighlightChangeEventDetails = SelectHighlightChangeEventDetails\n export type Actions = Popover.Root.Actions\n}\n","'use client'\n\nimport * as React from 'react'\nimport {\n PopupMenuSurface,\n type PopupMenuSurfaceProps,\n} from '../../internal/popup-menu/index.js'\nimport { stringifyAsValue } from '../../utils/resolve-value-label.js'\nimport { useSelectContext } from '../contexts/select-context.js'\nimport { useSelectPositionerContext } from '../contexts/select-positioner-context.js'\nimport { SelectSurfaceDataAttributes } from './surface.data-attrs.js'\n\nexport { SelectSurfaceDataAttributes }\n\nexport interface SelectSurfaceProps\n extends Omit<PopupMenuSurfaceProps, 'autoHighlightFirst'> {\n /**\n * Controls auto-highlighting behavior when the select opens.\n * - `true`: highlight the first item (default when alignItemWithTrigger is inactive)\n * - `false`: don't auto-highlight any item\n * - `'selected'`: highlight the currently selected item, or first item if none selected\n * - `string`: highlight the item with this specific value\n *\n * Note: When the Positioner's `alignItemWithTrigger` is active and this prop\n * is not explicitly set, the selected item is automatically highlighted.\n *\n * @default true (or selected value when alignItemWithTrigger is active)\n */\n autoHighlightFirst?: boolean | 'selected' | string\n}\n\n/**\n * Provides search context and manages item registration for Select.\n * Automatically configures `autoHighlightFirst` based on the Positioner's\n * `alignItemWithTrigger` prop - when active, highlights the selected item\n * instead of the first item.\n *\n * Place inside Select.Popup to enable search functionality.\n * Renders a `<div>` element.\n */\nexport const SelectSurface = React.forwardRef<\n HTMLDivElement,\n SelectSurface.Props\n>(function SelectSurface(props, forwardedRef) {\n const { autoHighlightFirst: autoHighlightFirstProp, ...rest } = props\n\n const selectContext = useSelectContext()\n const positionerContext = useSelectPositionerContext()\n\n // Determine autoHighlightFirst value:\n // - 'selected': use the current selected value (falls back to true if no selection)\n // - If alignItemWithTrigger is active and prop is not set, highlight the selected item\n // - Otherwise, use the prop value (defaulting to true)\n const autoHighlightFirst = React.useMemo(() => {\n // Helper to serialize a value to a string for highlighting\n // Returns true (highlight first) when there's no meaningful value\n const serializeValue = (value: unknown): string | true => {\n if (value == null || value === '') return true\n return stringifyAsValue(value, selectContext.itemToStringValue)\n }\n\n // Handle 'selected' shorthand - resolve to actual selected value\n if (autoHighlightFirstProp === 'selected') {\n // For single-select, use the selected value\n // For multi-select, use the first selected value\n const selectedValue = selectContext.multiple\n ? selectContext.values[0]\n : selectContext.value\n\n // If there's a selected value, serialize and use for highlighting\n return serializeValue(selectedValue)\n }\n\n // If user explicitly passed a value (other than 'selected'), respect it\n if (autoHighlightFirstProp !== undefined) {\n return autoHighlightFirstProp\n }\n\n // If alignItemWithTrigger is active and we have a selected value,\n // auto-highlight the selected item\n if (positionerContext?.alignItemWithTriggerActive) {\n // For single-select, use the value\n // For multi-select, use the first selected value (or fall back to true)\n const selectedValue = selectContext.multiple\n ? selectContext.values[0]\n : selectContext.value\n return serializeValue(selectedValue)\n }\n\n // Default behavior\n return true\n }, [\n autoHighlightFirstProp,\n positionerContext?.alignItemWithTriggerActive,\n selectContext.multiple,\n selectContext.value,\n selectContext.values,\n selectContext.itemToStringValue,\n ])\n\n return (\n <PopupMenuSurface\n ref={forwardedRef}\n autoHighlightFirst={autoHighlightFirst}\n {...{ [SelectSurfaceDataAttributes.slot]: '' }}\n {...rest}\n />\n )\n})\n\nexport namespace SelectSurface {\n export type State = PopupMenuSurface.State\n export interface Props extends SelectSurfaceProps {}\n}\n","export const SelectSurfaceDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-surface'}\n */\n slot: 'bazzaui-select-surface',\n} as const\n","'use client'\n\nimport { Popover, type PopoverTriggerProps } from '@base-ui/react/popover'\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { usePopupMenuContext } from '../../internal/popup-menu/contexts/popup-menu-context.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useSelectContext } from '../contexts/select-context.js'\nimport { SelectTriggerDataAttributes } from './trigger.data-attrs.js'\n\nexport { SelectTriggerDataAttributes }\n\nexport interface SelectTriggerState extends Record<string, unknown> {\n /**\n * Whether the select is open.\n */\n open: boolean\n /**\n * Whether the select is disabled.\n */\n disabled: boolean\n /**\n * Whether the select currently shows placeholder (no value selected).\n */\n placeholder: boolean\n}\n\nexport interface SelectTriggerProps\n extends ComponentProps<'button', SelectTrigger.State> {\n /**\n * Whether the trigger is disabled.\n */\n disabled?: boolean\n}\n\nconst stateAttributesMapping = {\n open: (value: unknown): Record<string, string> | null =>\n value ? { [SelectTriggerDataAttributes.open]: '' } : null,\n disabled: (value: unknown): Record<string, string> | null =>\n value ? { [SelectTriggerDataAttributes.disabled]: '' } : null,\n placeholder: (value: unknown): Record<string, string> | null =>\n value ? { [SelectTriggerDataAttributes.placeholder]: '' } : null,\n}\n\n/**\n * Inner component that renders using useRender.\n * This allows us to use hooks while being called from Popover.Trigger's render prop.\n */\nconst SelectTriggerInner = React.forwardRef<\n HTMLButtonElement,\n SelectTriggerProps & {\n triggerProps: React.ComponentPropsWithRef<'button'>\n triggerState: { open: boolean }\n }\n>(function SelectTriggerInner(props, forwardedRef) {\n const {\n render,\n children,\n disabled: disabledProp,\n className,\n style,\n triggerProps,\n triggerState,\n ...rest\n } = props\n\n const selectContext = useSelectContext()\n const disabled = disabledProp ?? selectContext.disabled\n\n // Determine if showing placeholder\n // Match Base UI: null, undefined, or empty string = no selection\n const hasValue = selectContext.multiple\n ? selectContext.values.length > 0\n : selectContext.value != null && selectContext.value !== ''\n\n const state: SelectTrigger.State = React.useMemo(\n () => ({\n open: triggerState.open,\n disabled,\n placeholder: !hasValue,\n }),\n [triggerState.open, disabled, hasValue],\n )\n\n // Register trigger element for positioning\n const internalRef = React.useCallback(\n (node: HTMLButtonElement | null) => {\n selectContext.setTriggerElement(node)\n },\n [selectContext],\n )\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...triggerProps,\n ...rest,\n [SelectTriggerDataAttributes.slot]: '',\n ref: internalRef,\n role: 'combobox' as const,\n 'aria-haspopup': 'listbox' as const,\n 'aria-controls': selectContext.listId,\n className,\n style,\n children,\n },\n defaultTagName: 'button',\n })\n})\n\n/**\n * A button that opens the select dropdown.\n * Renders a `<button>` element with combobox ARIA semantics.\n */\nexport const SelectTrigger = React.forwardRef<\n HTMLButtonElement,\n SelectTrigger.Props\n>(function SelectTrigger(props, forwardedRef) {\n const { disabled: disabledProp, ...rest } = props\n const selectContext = useSelectContext()\n const disabled = disabledProp ?? selectContext.disabled\n\n return (\n <Popover.Trigger\n ref={forwardedRef}\n disabled={disabled}\n render={(triggerProps, triggerState) => (\n <SelectTriggerInner\n {...rest}\n disabled={disabled}\n triggerProps={triggerProps}\n triggerState={triggerState}\n ref={triggerProps.ref as React.Ref<HTMLButtonElement>}\n />\n )}\n />\n )\n})\n\nexport namespace SelectTrigger {\n export interface Props extends SelectTriggerProps {}\n export type State = SelectTriggerState\n}\n","export const SelectTriggerDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-trigger'}\n */\n slot: 'bazzaui-select-trigger',\n /**\n * Present when the select dropdown is open.\n */\n open: 'data-open',\n /**\n * Present when the select dropdown is closed.\n */\n closed: 'data-closed',\n /**\n * Present when the trigger is disabled.\n */\n disabled: 'data-disabled',\n /**\n * Present when no value is selected (showing placeholder).\n */\n placeholder: 'data-placeholder',\n} as const\n","'use client'\n\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport {\n resolveLabel,\n stringifyAsValue,\n} from '../../utils/resolve-value-label.js'\nimport type { ComponentProps } from '../../utils/types.js'\nimport { useSelectContext } from '../contexts/select-context.js'\nimport { SelectValueDataAttributes } from './value.data-attrs.js'\n\nexport { SelectValueDataAttributes }\n\nexport interface SelectValueState<Value = unknown>\n extends Record<string, unknown> {\n /**\n * The currently selected value (single-select mode).\n */\n value: Value | null\n /**\n * The currently selected values (multi-select mode).\n */\n values: Value[]\n /**\n * Whether the select is in multi-select mode.\n */\n multiple: boolean\n /**\n * Whether a value is currently selected.\n */\n hasValue: boolean\n /**\n * The placeholder text.\n */\n placeholder: string\n /**\n * Get the display content for a value.\n * First checks the item text registry (populated when items mount),\n * then falls back to the `items` prop passed to SelectRoot,\n * then falls back to `itemToStringLabel` for object values.\n */\n getValueText: (value: Value) => React.ReactNode | undefined\n}\n\nexport interface SelectValueProps<Value = unknown>\n extends Omit<ComponentProps<'span', SelectValueState<Value>>, 'children'> {\n /**\n * Placeholder text when no value is selected.\n * Overrides the placeholder set on Select.Root.\n */\n placeholder?: string\n\n /**\n * Custom render function for the selected value content.\n * Receives the current state and should return the content to render.\n * This is different from the `render` prop which replaces the element.\n */\n children?:\n | React.ReactNode\n | ((state: SelectValueState<Value>) => React.ReactNode)\n}\n\nconst stateAttributesMapping = {\n hasValue: (value: unknown): Record<string, string> | null =>\n !value ? { [SelectValueDataAttributes.placeholder]: '' } : null,\n multiple: (value: unknown): Record<string, string> | null =>\n value ? { [SelectValueDataAttributes.multiple]: '' } : null,\n // Exclude function from data attributes to avoid hydration mismatch\n getValueText: () => null,\n}\n\n/**\n * Displays the currently selected value(s) or placeholder.\n * Typically placed inside Select.Trigger.\n * Renders a `<span>` element.\n */\nfunction SelectValueImpl<Value = unknown>(\n props: SelectValueProps<Value>,\n forwardedRef: React.ForwardedRef<HTMLSpanElement>,\n) {\n const {\n render,\n className,\n style,\n placeholder: placeholderProp,\n children,\n ...rest\n } = props\n\n const selectContext = useSelectContext<Value>()\n\n const placeholder = placeholderProp ?? selectContext.placeholder\n\n const hasValue = selectContext.multiple\n ? selectContext.values.length > 0\n : Boolean(selectContext.value)\n\n // Helper to get text for a value\n // First check the item text registry (populated when items mount),\n // then fall back to the items prop (available immediately for initial render),\n // then fall back to itemToStringLabel for object values\n const getValueText = React.useCallback(\n (value: Value): React.ReactNode | undefined => {\n // Serialize for registry lookup\n const serializedValue = stringifyAsValue(\n value,\n selectContext.itemToStringValue,\n )\n\n // First try the registry (populated when items mount)\n const registryText = selectContext.itemTextRegistry.get(serializedValue)\n if (registryText !== undefined) {\n return registryText\n }\n\n // Fall back to the items prop (for initial render before popup opens)\n const items = selectContext.items\n if (items) {\n // Handle record format: { value: label }\n if (!Array.isArray(items)) {\n const label = items[serializedValue]\n if (label !== undefined) {\n return label\n }\n } else {\n // Handle array format: [{ value, label }]\n const item = items.find((item) => item.value === serializedValue)\n if (item?.label !== undefined) {\n return item.label\n }\n }\n }\n\n // Fall back to itemToStringLabel for object values\n const resolvedLabel = resolveLabel(value, selectContext.itemToStringLabel)\n // Only return if it's different from the serialized value (meaning we got a real label)\n if (resolvedLabel && resolvedLabel !== serializedValue) {\n return resolvedLabel\n }\n\n return undefined\n },\n [\n selectContext.itemTextRegistry,\n selectContext.items,\n selectContext.itemToStringLabel,\n selectContext.itemToStringValue,\n ],\n )\n\n const state: SelectValueState<Value> = React.useMemo(\n () => ({\n value: selectContext.value,\n values: selectContext.values,\n multiple: selectContext.multiple,\n hasValue,\n placeholder,\n getValueText,\n }),\n [\n selectContext.value,\n selectContext.values,\n selectContext.multiple,\n hasValue,\n placeholder,\n getValueText,\n ],\n )\n\n // Determine what to render as content\n let content: React.ReactNode\n\n if (typeof children === 'function') {\n // Custom render function\n content = children(state)\n } else if (children !== undefined) {\n // Static children\n content = children\n } else if (!hasValue) {\n // Show placeholder when no value\n content = placeholder\n } else if (selectContext.multiple) {\n // Multi-select: show count or comma-separated values\n const texts = selectContext.values\n .map((v) => {\n const text = getValueText(v)\n if (text !== undefined) return text\n // Fall back to resolved label or serialized value\n return (\n resolveLabel(v, selectContext.itemToStringLabel) ||\n stringifyAsValue(v, selectContext.itemToStringValue)\n )\n })\n .filter(Boolean)\n content = texts.length > 2 ? `${texts.length} selected` : texts.join(', ')\n } else {\n // Single-select: show value text\n const value = selectContext.value\n if (value != null) {\n const text = getValueText(value)\n if (text !== undefined) {\n content = text\n } else {\n // Fall back to resolved label or serialized value\n content =\n resolveLabel(value, selectContext.itemToStringLabel) ||\n stringifyAsValue(value, selectContext.itemToStringValue)\n }\n }\n }\n\n // Register value element for positioning\n const internalRef = React.useCallback(\n (node: HTMLSpanElement | null) => {\n selectContext.setValueElement(node)\n },\n [selectContext],\n )\n\n return useRender({\n render,\n ref: forwardedRef,\n state,\n stateAttributesMapping,\n props: {\n ...rest,\n [SelectValueDataAttributes.slot]: '',\n ref: internalRef,\n className,\n style,\n children: content,\n },\n defaultTagName: 'span',\n })\n}\n\nexport const SelectValue = React.forwardRef(SelectValueImpl) as <\n Value = unknown,\n>(\n props: SelectValueProps<Value> & React.RefAttributes<HTMLSpanElement>,\n) => React.ReactElement\n\nexport namespace SelectValue {\n // Props uses unknown default for simpler usage when type doesn't matter\n export interface Props extends SelectValueProps<unknown> {}\n export type State = SelectValueState<unknown>\n}\n","export const SelectValueDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-value'}\n */\n slot: 'bazzaui-select-value',\n /**\n * Present when showing placeholder (no value selected).\n */\n placeholder: 'data-placeholder',\n /**\n * Present when in multi-select mode.\n */\n multiple: 'data-multiple',\n} as const\n","export enum SelectArrowDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-arrow'}\n */\n slot = 'bazzaui-select-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","export enum SelectBackdropDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-backdrop'}\n */\n slot = 'bazzaui-select-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","/**\n * Data attributes applied to Select.Empty for styling.\n * Displayed when no items match the current search filter.\n *\n * @example\n * ```css\n * [data-bazzaui-select-empty] {\n * padding: 8px 16px;\n * color: var(--muted);\n * text-align: center;\n * }\n * ```\n */\nexport enum SelectEmptyDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-empty'}\n */\n slot = 'bazzaui-select-empty',\n}\n","export enum SelectGroupDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-group'}\n */\n slot = 'bazzaui-select-group',\n}\n","export enum SelectGroupLabelDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-group-label'}\n */\n slot = 'bazzaui-select-group-label',\n}\n","export const SelectIconDataAttributes = {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-icon'}\n */\n slot: 'bazzaui-select-icon',\n /** Present when the popup is open. */\n open: 'data-popup-open',\n} as const\n","export enum SelectInputDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-input'}\n */\n slot = 'bazzaui-select-input',\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","/**\n * Data attributes applied to Select.List for styling.\n * Container for select items with role=\"listbox\".\n *\n * @example\n * ```css\n * [data-bazzaui-select-list] {\n * max-height: 300px;\n * overflow-y: auto;\n * }\n * ```\n */\nexport enum SelectListDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-list'}\n */\n slot = 'bazzaui-select-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","// Re-export all base popup data attributes\nexport { PopupMenuPopupDataAttributes } from '../../internal/popup-menu/components/popup/popup.data-attrs.js'\n\n/**\n * Select-specific popup data attributes (in addition to PopupMenuPopupDataAttributes).\n */\nexport enum SelectPopupDataAttributes {\n /**\n * Present when the popup is using align-item-with-trigger positioning.\n * This reflects the actual state, not just the prop value.\n */\n alignItemWithTrigger = 'data-align-item-with-trigger',\n}\n","export const SelectScrollArrowDataAttributes = {\n /**\n * Identifies the component part for scroll up arrow.\n * @type {'bazzaui-select-scroll-up-arrow'}\n */\n slotUp: 'bazzaui-select-scroll-up-arrow',\n /**\n * Identifies the component part for scroll down arrow.\n * @type {'bazzaui-select-scroll-down-arrow'}\n */\n slotDown: 'bazzaui-select-scroll-down-arrow',\n /**\n * Direction of the scroll arrow.\n * @type {'up' | 'down'}\n */\n direction: 'data-direction',\n /**\n * Side of the popup.\n * @type {'top' | 'bottom' | 'left' | 'right'}\n */\n side: 'data-side',\n} as const\n","export enum SelectSeparatorDataAttributes {\n /**\n * Identifies the component part.\n * @type {'bazzaui-select-separator'}\n */\n slot = 'bazzaui-select-separator',\n}\n"],"mappings":"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","names":["src_exports","__export","index_parts_exports","ComboboxArrowDataAttributes","ComboboxBackdropDataAttributes","ComboboxClear","ComboboxEmptyDataAttributes","ComboboxGroupDataAttributes","ComboboxGroupLabelDataAttributes","ComboboxIconDataAttributes","ComboboxInput","ComboboxInputDataAttributes","ComboboxInputWrapper","ComboboxInputWrapperDataAttributes","ComboboxItem","ComboboxItemDataAttributes","ComboboxItemIndicator","ComboboxItemIndicatorDataAttributes","ComboboxItemLabel","PopupMenuListCssVars","ComboboxListDataAttributes","ComboboxPopupDataAttributes","ComboboxPositioner","PopupMenuPositionerCssVars","ComboboxPositionerDataAttributes","ComboboxRoot","ComboboxScrollArrowDataAttributes","ComboboxSeparatorDataAttributes","ListboxStore","ComboboxSurface","ContextMenuArrowDataAttributes","ContextMenuBackdropDataAttributes","ContextMenuCheckboxItemDataAttributes","ContextMenuCheckboxItemIndicatorDataAttributes","PopupMenuInput","PopupMenuDataList","PopupMenuDataSurface","ContextMenuEmptyDataAttributes","ContextMenuGroupDataAttributes","ContextMenuGroupLabelDataAttributes","ContextMenuIconDataAttributes","ContextMenuInputDataAttributes","ContextMenuItemDataAttributes","ContextMenuListDataAttributes","ContextMenuPopupDataAttributes","ContextMenuPositionerDataAttributes","ContextMenuRadioGroupDataAttributes","PopupMenuRadioGroupValue","ContextMenuRadioItemDataAttributes","ContextMenuRadioItemIndicatorDataAttributes","ContextMenuScrollArrowDataAttributes","ContextMenuSeparatorDataAttributes","ContextMenuShortcutDataAttributes","ContextMenuSubmenuTriggerDataAttributes","ContextMenuSubmenuTriggerIndicatorDataAttributes","ContextMenuSurfaceDataAttributes","ContextMenuTriggerDataAttributes","DataSurfaceContext","DropdownMenuArrowDataAttributes","DropdownMenuBackdropDataAttributes","DropdownMenuCheckboxItemDataAttributes","DropdownMenuCheckboxItemIndicatorDataAttributes","DropdownMenuEmptyDataAttributes","DropdownMenuGroupDataAttributes","DropdownMenuGroupLabelDataAttributes","DropdownMenuIconDataAttributes","DropdownMenuInputDataAttributes","DropdownMenuItemDataAttributes","DropdownMenuListDataAttributes","DropdownMenuPopupDataAttributes","DropdownMenuPositionerDataAttributes","DropdownMenuRadioGroupDataAttributes","DropdownMenuRadioItemDataAttributes","DropdownMenuRadioItemIndicatorDataAttributes","DropdownMenuScrollArrowDataAttributes","DropdownMenuSeparatorDataAttributes","DropdownMenuShortcutDataAttributes","DropdownMenuSubmenuTriggerDataAttributes","DropdownMenuSubmenuTriggerIndicatorDataAttributes","DropdownMenuSurfaceDataAttributes","DropdownMenuTriggerDataAttributes","SelectArrowDataAttributes","SelectBackdropDataAttributes","SelectEmptyDataAttributes","SelectGroupDataAttributes","SelectGroupLabelDataAttributes","SelectIconDataAttributes","SelectInputDataAttributes","SelectItem","SelectItemDataAttributes","SelectItemIndicator","SelectItemIndicatorDataAttributes","SelectItemLabel","SelectListDataAttributes","SelectPopup","SelectPopupDataAttributes","SelectPositioner","SelectPositionerDataAttributes","SelectRoot","SelectScrollArrowDataAttributes","SelectSeparatorDataAttributes","SelectSurface","SelectTrigger","SelectTriggerDataAttributes","SelectValue","commandScore","createLoaderComponent","createQueryLoader","createStaticLoader","createVanillaQueryLoader","createVanillaStaticLoader","defaultFilter","defineRadioGroup","isDisplayGroupNode","isDisplayRadioGroupNode","isDisplayRowNode","isDisplaySeparatorNode","toAsyncLoaderResult","useComboboxContext","useComboboxItemContext","useComboboxPositionerContext","useDataSurfaceContext","usePopupMenuItem","useItemContext","useMaybeComboboxContext","useMaybeComboboxItemContext","useMaybeDataSurfaceContext","useMaybeItemContext","useMaybePopupMenuContext","useMaybeSelectContext","useMaybeSelectItemContext","useMaybeSubmenuContext","useMaybeSurfaceContext","usePopupMenuContext","useSelectContext","useSelectItemContext","useSelectPositionerContext","useSubmenuContext","useSurfaceContext","__toCommonJS","import_jsx_runtime","toAsyncLoaderResult","result","createStaticLoader","props","useQuery","children","createQueryLoader","minQueryLength","initialQuery","loadStrategy","belowMinBehavior","placeholderNodes","query","createLoaderComponent","useQueryFn","React","import_jsx_runtime","useAsyncState","fetcher","options","enabled","state","setState","fetcherRef","refetch","s","data","error","createVanillaStaticLoader","props","children","result","createVanillaQueryLoader","minQueryLength","initialQuery","belowMinBehavior","placeholderNodes","query","index_parts_exports","__export","PopupMenuArrow","PopupMenuBackdrop","ComboboxClear","PopupMenuEmpty","PopupMenuGroup","PopupMenuGroupLabel","PopupMenuIcon","ComboboxInput","ComboboxInputWrapper","ComboboxItem","ComboboxItemIndicator","ComboboxItemLabel","PopupMenuList","PopupMenuPopup","PopupMenuPortal","ComboboxPositioner","ComboboxRoot","PopupMenuScrollDownArrow","PopupMenuScrollUpArrow","PopupMenuSeparator","ComboboxSurface","useComboboxPositionerContext","React","ComponentNameContext","useMaybeComponentName","ComponentNameContext","getSlotAttribute","componentName","partName","React","FocusOwnerContext","useFocusOwner","context","React","OpenChainContext","useOpenChain","context","React","PopupMenuContext","usePopupMenuContext","context","useMaybePopupMenuContext","React","PopupSurfaceIdContext","usePopupSurfaceId","React","SubmenuContext","useSubmenuContext","context","useMaybeSubmenuContext","React","import_jsx_runtime","AimGuardCtx","useAimGuard","AimGuardProvider","children","aimGuardActive","setAimGuardActive","guardedTriggerId","setGuardedTriggerId","guardedDepth","setGuardedDepth","guardedSubmenuSurfaceId","setGuardedSubmenuSurfaceId","aimGuardActiveRef","guardedTriggerIdRef","guardedDepthRef","guardedSubmenuSurfaceIdRef","guardTimerRef","clearAimGuard","activateAimGuard","triggerId","depth","submenuSurfaceId","timeoutMs","isGuardBlocking","rowId","value","import_store","selectors","state","surfaceId","FocusOwnerStore","id","import_store","selectors","state","surfaceId","depth","OpenChainStore","newChain","id","resolveAnchorSide","rect","tRect","mx","tx","dL","dR","getSmoothedHeading","trail","exitX","exitY","anchor","dx","dy","n","i","x1","y1","x2","y2","ty","edgeX","edgeCy","willHitSubmenu","heading","triggerRect","t","yAtEdge","baseBand","extra","top","bottom","React","useMouseTrail","n","trailRef","onMove","e","a","React","reason_parts_exports","__export","auto","clearPress","closePress","escapeKey","focusOut","imperativeAction","inputChange","inputClear","itemKeyboardSelect","itemPress","keyboard","listNavigation","none","outsidePress","pointer","siblingOpen","submenuTrigger","triggerContextMenu","triggerFocus","triggerHover","triggerPress","createChangeEventDetails","reason","event","trigger","customProperties","canceled","propagationAllowed","createGenericEventDetails","React","GroupContext","useGroupContext","React","ItemContext","useItemContext","context","useMaybeItemContext","React","ListboxContext","useListboxContext","context","useMaybeListboxContext","React","RowWidthContext","useMaybeRowWidthContext","RowWidthContext","React","SurfaceContext","useSurfaceContext","context","useMaybeSurfaceContext","React","normalizeValue","value","slugify","useListboxItem","params","idProp","valueProp","keywords","disabled","forceMount","shortcut","isSubmenuTrigger","onSelect","closeOnClick","onAfterSelect","children","aimGuard","store","useSurfaceContext","groupContext","useGroupContext","depth","useListboxContext","ref","inferredValue","setInferredValue","textContent","registrationId","normalizeValue","generatedDomId","domId","normalizedKeywords","k","keywordsKey","rowWidthContext","useMaybeRowWidthContext","search","isHighlighted","score","filterDisabled","hasSearch","isVisible","handleClick","event","handlePointerDown","handlePointerMove","aimGuardActiveRef","guardedDepthRef","contextValue","registerSelect","handler","handlers","React","useListboxKeyboard","params","store","surfaceId","enabled","onKeyDown","onSelect","closeAll","focusOwner","depth","submenuContext","enableTypeToSearch","skipFocusOwnerCheck","focusOwnerIsOwner","isOwner","event","hideUntilActive","inputActive","shortcutItemId","item","selectedId","hasActiveSearch","itemId","React","DEBUG_ROW_WIDTH","DEBUG_FREEZE_MEASUREMENT","debugLog","args","px","n","useStickyRowWidth","options","listRef","targetRef","maxWidth","enabled","getTargetElement","maxSeenRef","readQueue","writeQueue","scheduled","measuredIds","applyVar","width","el","capped","schedule","measurements","foundNewMax","element","id","prevWidth","prevMaxWidth","w","computed","rect","write","queueMeasurement","resetMeasurements","prevMax","prevCount","container","rafId","ro","entries","import_store","import_useRefWithInit","IS_GAP_REGEXP","COUNT_GAPS_REGEXP","IS_SPACE_REGEXP","COUNT_SPACE_REGEXP","commandScoreInner","string","abbreviation","lowerString","lowerAbbreviation","stringIndex","abbreviationIndex","memoizedResults","memoizeKey","abbreviationChar","index","highScore","score","transposedScore","wordBreaks","spaceBreaks","formatInput","commandScore","keywords","fullString","defaultFilter","selectors","state","itemId","groupId","ListboxStore","_ListboxStore","initialState","context","defaultContext","commandScore","createInitialState","open","deferInputHide","search","prevSearch","reason","reason_parts_exports","event","eventDetails","createChangeEventDetails","id","cause","onHighlightChange","index","createGenericEventDetails","refs","listEl","itemEl","hasInput","active","enabled","virtualized","items","prevItems","prevFirstItem","item","firstItemChanged","firstRegisteredItem","orderedItems","callback","ref","x","y","last","dx","dy","virtualItems","registration","existing","groupItems","key","onSelect","onOpen","onClose","exceptId","visibleIds","nextIndex","nextId","prevIndex","prevId","score","autoHighlight","value","highlightedId","result","filteredItems","unregisteredItems","options","forceFirst","newSearch","optionsPrevSearch","effectiveSearch","searchChanged","currentHighlight","filter","shouldForceFirst","isCurrentValid","isVisible","virtualItem","v","isDisabled","isRegistered","inVirtualItems","newHighlightId","groups","visibleGroups","filteredCount","_","filterFn","externalStore","usePopupMenuRoot","params","onOpenChange","defaultOpen","virtualized","itemsProp","onHighlightChange","closeOnOutsidePress","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","virtualization","import_popover","React","import_jsx_runtime","PopupMenuArrow","props","forwardedRef","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","import_popover","React","import_jsx_runtime","PopupMenuBackdrop","props","forwardedRef","showOnProp","rest","submenuContext","useMaybeSubmenuContext","openChainStore","useOpenChain","focusOwnerStore","useFocusOwner","isSubmenu","surfaceId","showOn","isInOpenChain","isLastInChain","isFocusOwner","shouldShow","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","style","import_popover","React","React","ComboboxContext","useComboboxContext","context","useMaybeComboboxContext","import_jsx_runtime","PopupMenuPopup","props","forwardedRef","children","classNameProp","rest","submenuContext","useMaybeSubmenuContext","clearAimGuard","aimGuardActiveRef","guardedSubmenuSurfaceIdRef","useAimGuard","focusOwnerStore","useFocusOwner","openChainStore","useOpenChain","depth","useMaybePopupMenuContext","comboboxContext","useMaybeComboboxContext","generatedSurfaceId","surfaceId","openTimeRef","isFocused","hasOpenSubmenu","popupRef","combinedRef","node","handlePointerMove","handleFocusTransferOnMove","event","target","targetElement","closestPopup","initialFocus","finalFocus","isInputEmbedded","isSubmenu","className","baseState","extendedState","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","PopupSurfaceIdContext","import_popover","PopupMenuPortal","PopupMenuPositionerCssVars","import_popover","React","import_jsx_runtime","getDefaultCollisionAvoidance","side","isHorizontalSide","PopupMenuPositioner","props","ref","sideProp","alignProp","alignOffsetProp","collisionAvoidanceProp","virtualAnchorProp","styleProp","rest","depth","contextVirtualAnchor","menuType","usePopupMenuContext","submenuContext","useMaybeSubmenuContext","listStartOffsetRef","hasMeasuredRef","forceUpdate","x","isSubmenu","virtualAnchor","align","useListStartAlign","baseUIAlign","isOpen","measureListStartOffset","contentEl","contentRect","listEl","listRect","listStyles","listPaddingTop","offset","effectiveAlignOffset","collisionAvoidance","anchorProps","style","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","React","import_jsx_runtime","PopupMenuProviders","props","store","focusOwnerStore","openChainStore","depth","closeAll","registerSurface","virtualization","virtualAnchor","menuType","closeOnOutsidePress","getQualifiedRowId","componentName","children","popupMenuContextValue","listboxContextValue","ComponentNameContext","PopupMenuContext","ListboxContext","AimGuardProvider","FocusOwnerContext","OpenChainContext","React","usePopupMenuItem","params","closeOnClick","rest","aimGuardActiveRef","guardedDepthRef","useAimGuard","closeAll","useListboxContext","aimGuard","handleAfterSelect","itemId","useListboxItem","React","usePopupMenuKeyboard","params","store","surfaceId","focusOwnerStore","depth","submenuContext","enabled","enableTypeToSearch","onKeyDown","closeAll","skipFocusOwnerCheck","submenuInterface","handleSelect","details","useListboxKeyboard","PopupMenuIconDataAttributes","import_use_render","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","import_use_render","React","PopupMenuEmpty","props","forwardedRef","render","className","style","children","rest","store","useSurfaceContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","import_use_render","React","PopupMenuInput","props","forwardedRef","controlledValue","onValueChange","hideUntilActive","render","className","style","onKeyDown","rest","store","surfaceId","useSurfaceContext","depth","closeAll","useListboxContext","submenuContext","useMaybeSubmenuContext","focusOwnerStore","useFocusOwner","internalRef","search","highlightedId","listId","inputId","inputActive","pendingSearch","shouldRender","displayValue","handleChange","event","newValue","handleKeyDown","usePopupMenuKeyboard","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","import_use_render","React","PopupMenuListCssVars","import_jsx_runtime","PopupMenuList","props","forwardedRef","children","label","measureRowWidth","maxRowWidth","render","className","style","onKeyDown","onPointerDown","rest","store","surfaceId","useSurfaceContext","depth","closeAll","useListboxContext","submenuContext","useMaybeSubmenuContext","focusOwnerStore","useFocusOwner","comboboxContext","useMaybeComboboxContext","internalRef","popupRef","popup","queueMeasurement","resetMeasurements","useStickyRowWidth","rowWidthContextValue","search","filteredCount","hasInput","highlightedId","listId","shouldHandleKeyboard","handleKeyDown","usePopupMenuKeyboard","handlePointerDown","event","childrenState","renderedChildren","wrappedChildren","RowWidthContext","isInputEmbedded","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","PopupMenuScrollArrowDataAttributes","import_use_render","React","import_jsx_runtime","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","event","PopupMenuScrollUpArrow","PopupMenuScrollDownArrow","import_use_render","import_useStableCallback","React","import_jsx_runtime","PopupMenuSurface","props","forwardedRef","filter","defaultFilter","searchProp","onSearchChange","defaultSearch","loop","autoHighlightFirst","clearSearchOnClose","skipAutoFocus","orderedItems","render","className","style","onPointerDown","onPointerMove","children","rest","store","depth","virtualization","useListboxContext","submenuContext","useMaybeSubmenuContext","focusOwnerStore","useFocusOwner","openTimeRef","listId","inputId","generatedSurfaceId","surfaceId","usePopupSurfaceId","isOwner","handleSearchChange","search","open","surfaceRef","timeoutId","input","list","focusTarget","contextValue","handlePointerDown","event","handlePointerMove","target","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","SurfaceContext","import_use_render","React","React","CheckboxItemContext","useCheckboxItemContext","context","import_jsx_runtime","stateAttributesMapping","value","PopupMenuCheckboxItem","props","forwardedRef","id","checkedProp","defaultChecked","onCheckedChange","keywords","disabled","onSelect","forceMount","closeOnClick","shortcut","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","internalChecked","setInternalChecked","isControlled","checked","toggleChecked","reason","reason_parts_exports","event","newChecked","eventDetails","createChangeEventDetails","item","usePopupMenuItem","handleSelect","state","checkboxItemContextValue","handleClick","handlePointerDown","handlePointerMove","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","ItemContext","CheckboxItemContext","import_use_render","React","stateAttributesMapping","value","PopupMenuCheckboxItemIndicator","props","forwardedRef","keepMounted","render","className","style","children","rest","checked","highlighted","disabled","toggle","useCheckboxItemContext","state","shouldRender","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","import_use_render","React","import_jsx_runtime","stateAttributesMapping","value","PopupMenuItem","props","forwardedRef","id","keywords","disabled","onSelect","forceMount","closeOnClick","shortcut","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","item","usePopupMenuItem","state","handleClick","event","handlePointerDown","handlePointerMove","wrappedChildren","ItemContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","import_use_render","React","React","RadioGroupContext","useRadioGroupContext","context","import_jsx_runtime","stateAttributesMapping","value","PopupMenuRadioGroup","props","forwardedRef","valueProp","defaultValue","onValueChange","disabled","forceMount","render","className","style","children","rest","store","useSurfaceContext","groupId","internalValue","setInternalValue","isControlled","setValue","newValue","reason","reason_parts_exports","event","eventDetails","createChangeEventDetails","isGroupVisible","isVisible","radioGroupContextValue","groupContextValue","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","RadioGroupContext","GroupContext","React","import_jsx_runtime","PopupMenuRadioGroupValue","props","value","onValueChange","disabled","children","setValue","newValue","reason","reason_parts_exports","event","eventDetails","createChangeEventDetails","contextValue","RadioGroupContext","import_use_render","React","React","RadioItemContext","useRadioItemContext","context","import_jsx_runtime","stateAttributesMapping","value","PopupMenuRadioItem","props","forwardedRef","id","keywords","disabledProp","onSelect","forceMount","closeOnClick","shortcut","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","radioGroupContext","useRadioGroupContext","disabled","checked","item","usePopupMenuItem","handleSelect","state","radioItemContextValue","handleClick","event","handlePointerDown","handlePointerMove","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","ItemContext","RadioItemContext","import_use_render","React","stateAttributesMapping","value","PopupMenuRadioItemIndicator","props","forwardedRef","keepMounted","render","className","style","children","rest","checked","highlighted","disabled","useRadioItemContext","state","shouldRender","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","import_use_render","React","import_jsx_runtime","PopupMenuGroup","props","forwardedRef","forceMount","render","className","style","children","rest","store","useSurfaceContext","groupId","isGroupVisible","isVisible","groupContextValue","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","GroupContext","import_use_render","React","PopupMenuGroupLabel","props","forwardedRef","render","className","style","children","rest","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","import_use_render","React","PopupMenuSeparator","props","forwardedRef","alwaysRender","render","className","style","rest","store","useSurfaceContext","isHidden","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","import_use_render","React","stateAttributesMapping","value","PopupMenuShortcut","props","forwardedRef","children","render","className","style","rest","shortcut","highlighted","useItemContext","state","renderedChildren","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","import_popover","import_useStableCallback","React","import_jsx_runtime","PopupMenuSubmenuRoot","props","openProp","onOpenChange","defaultOpen","closeRootOnEsc","virtualized","itemsProp","onHighlightChange","onOpenChangeCompleteProp","children","rest","parentListboxContext","useMaybeListboxContext","parentPopupMenuContext","useMaybePopupMenuContext","parentDepth","parentCloseAll","parentRegisterSurface","parentSurfaceId","useSurfaceContext","childSurfaceId","triggerRef","contentRef","store","ListboxStore","openChainStore","useOpenChain","open","handlePopoverOpenChange","newOpen","eventDetails","handleOpenChangeComplete","nextOpen","parentOpen","setParentOpen","parentStore","checkParentOpen","isOpen","depth","submenuContextValue","fallbackRegisterSurface","virtualization","listboxContextValue","popupMenuContextValue","SubmenuContext","PopupMenuContext","ListboxContext","import_popover","import_use_render","React","import_use_render","React","stateAttributesMapping","value","PopupMenuSubmenuTriggerIndicator","props","forwardedRef","render","className","style","children","rest","open","childSurfaceId","useSubmenuContext","isPopupFocused","useFocusOwner","state","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","import_jsx_runtime","stateAttributesMapping","value","PopupMenuSubmenuTrigger","props","forwardedRef","idProp","keywords","disabled","forceMount","openOnHighlight","delayProp","closeDelay","render","className","style","onPointerDown","onPointerMove","onPointerEnter","onPointerLeave","children","rest","delay","parentStore","useSurfaceContext","depth","useListboxContext","parentDepth","submenuContext","useSubmenuContext","open","setOpen","triggerRef","contentRef","childSurfaceId","openTimerRef","clearOpenTimer","suppressAutoOpenRef","focusOwnerStore","useFocusOwner","aimGuardActiveRef","guardedTriggerIdRef","guardedDepthRef","activateAimGuard","clearAimGuard","useAimGuard","mouseTrailRef","useMouseTrail","item","usePopupMenuItem","input","list","focusTarget","isPopupFocused","prevOpenRef","keyboardDelay","handlePointerDown","event","handlePointerMove","handlePointerEnter","pointerDelay","handlePointerLeave","contentRect","clientX","clientY","tRect","anchor","resolveAnchorSide","heading","getSmoothedHeading","willHitSubmenu","state","wrappedChildren","ItemContext","componentName","useMaybeComponentName","slotAttr","getSlotAttribute","element","React","import_jsx_runtime","AsyncMenuCoordinatorContext","useAsyncMenuCoordinator","AsyncMenuCoordinatorProvider","props","children","searchQuery","loaders","setLoaders","erroredLoaders","setErroredLoaders","registerLoader","state","prev","next","unregisterLoader","id","updateLoaderResult","result","existing","isStaticLoading","isQueryLoading","isAnyLoading","allResolved","getAsyncNodes","getAsyncState","skippedMenus","contextValue","AsyncMenuCoordinatorContext","React","DataSurfaceContext","useDataSurfaceContext","context","useMaybeDataSurfaceContext","React","defineRadioGroup","def","isDisplayGroupNode","node","isDisplayRadioGroupNode","isDisplaySeparatorNode","isDisplayRowNode","defaultGetQualifiedRowId","ctx","slugValue","slugify","slugBreadcrumbs","b","flattenNodes","nodes","options","deep","breadcrumbs","group","radioGroup","result","node","groupInfo","radioGroupInfo","submenuBreadcrumb","childBreadcrumbs","scoreNodes","flattenedNodes","query","results","normalizedValue","normalizeValue","normalizedKeywords","k","score","commandScore","sortByScore","a","b","partitionByKind","items","n","submenus","deduplicateNodes","seen","scoredNode","compositeId","buildDisplayRowNodes","scoredNodes","highlightedId","isDeepSearchResult","context","buildDisplayRowNode","getBrowseNodesPreserve","nodes","highlightedId","result","node","groupItems","child","itemContext","groupContext","radioItems","context","filterNodesFlatten","options","query","deepSearch","minLength","radioGroupSearchBehavior","shouldDeepSearch","flattened","flattenNodes","allRadioGroupItems","flatNode","existing","scored","scoreNodes","radioGroupItems","regularItems","scoredNode","sorted","sortByScore","partitioned","partitionByKind","unique","deduplicateNodes","regularDisplayNodes","buildDisplayRowNodes","radioGroupDisplayNodes","radioGroupId","radioGroupDef","matchingItems","breadcrumbs","itemsToDisplay","allItems","matchingIds","item","matchingScores","a","b","bestScore","isDeepSearchResult","buildDisplayRowNode","allNodes","r","n","filterNodesPreserve","sortGroups","groupedItems","radioGroupedItems","ungroupedItems","groupDisplayNodes","_groupId","groupDef","items","ungroupedDisplayNodes","g","filterNodes","groupSearchBehavior","collectAsyncSubmenus","nodes","breadcrumbs","result","node","id","normalizeValue","childBreadcrumbs","mergeSubmenuNodes","staticNodes","asyncNodes","static_","async_","mergeAsyncNodesIntoTree","staticContent","asyncData","asyncMap","data","mergeRecursive","currentBreadcrumbs","submenuPath","mergedStaticChildren","mergedChildren","shouldIncludeInDeepSearch","config","shouldLoadEagerly","import_jsx_runtime","computeItemIds","displayNodes","getQualifiedRowId","isDeepSearching","index","displayNode","isDisplayGroupNode","item","isDisplayRadioGroupNode","isDisplaySeparatorNode","getOrderedItemIds","ids","AsyncLoaderRenderer","info","query","enabled","coordinator","useAsyncMenuCoordinator","config","id","breadcrumbs","node","Loader","effectiveQuery","minLength","shouldLoadEagerly","result","AsyncLoaderResultHandler","breadcrumbsRef","configRef","coordinatorRef","resultRef","prevResultRef","coord","state","prev","RootAsyncLoader","dataSurfaceCtx","useDataSurfaceContext","asyncContent","PopupMenuDataList","props","forwardedRef","children","label","className","style","render","measureRowWidth","maxRowWidth","content","deepSearchConfig","store","useSurfaceContext","search","AsyncMenuCoordinatorProvider","DataListInner","asyncSubmenus","collectAsyncSubmenus","isDeepSearchActive","shouldRenderAsyncLoaders","s","asyncNodes","mergedContent","mergeAsyncNodesIntoTree","contentWithRootAsync","rootAsyncData","n","filterNodes","prevOrderedItemIdsRef","newOrderedItemIds","orderedItemIds","current","i","renderRowNode","context","compositeId","submenuAsyncState","asyncResult","isBelowMinLength","staticNodes","submenuBreadcrumb","submenuRenderNode","childNode","groupItems","groupChildren","itemContext","groupContext","renderRadioGroup","childContext","radioGroup","isDeepSearchResult","childElements","renderNode","group","items","separator","asyncState","childrenState","renderedChildren","shouldIncludeInDeepSearch","PopupMenuList","React","import_jsx_runtime","PopupMenuDataSurface","props","forwardedRef","content","asyncContent","deepSearch","filter","searchProp","onSearchChange","defaultSearch","loop","autoHighlightFirst","clearSearchOnClose","getQualifiedRowIdProp","className","style","render","children","popupMenuContext","usePopupMenuContext","getQualifiedRowId","defaultGetQualifiedRowId","deepSearchConfig","listId","contextValue","DataSurfaceContext","PopupMenuSurface","import_use_render","React","ComboboxClearDataAttributes","ComboboxClear","props","forwardedRef","keepMounted","disabledProp","render","className","style","onClick","rest","comboboxContext","useComboboxContext","disabled","hasValue","handleClick","event","handlePointerDown","state","element","ComboboxClearDataAttributes","React","ComboboxPositionerContext","useComboboxPositionerContext","import_use_render","React","React","ComboboxInputWrapperContext","useIsInsideInputWrapper","ComboboxInputDataAttributes","React","resolveLabelFromItems","items","value","label","i","useComboboxDisplayValue","params","comboboxContext","open","hasValue","getValueText","serializedValue","stringifyAsValue","registryText","itemsLabel","resolvedLabel","resolveLabel","selectedLabel","texts","v","text","displayValue","React","useComboboxInputBehavior","params","comboboxContext","store","focusOwnerStore","open","disabled","cursorBehavior","hasValue","getValueText","onFocus","onBlur","onClick","onKeyDown","openedByTypingRef","openedByClickRef","wasAlreadyFocusedRef","clickCursorPositionRef","selectionRef","outsidePointerEventRef","handlePointerDown","event","input","inputWrapper","listbox","target","isInsideInput","isInsideWrapper","isInsideListbox","inputElement","start","end","currentPos","valueLen","prevOpenRef","clickPos","maxPos","safePos","valueLength","handleChange","newValue","handleFocus","isOpen","labelValue","resolveLabel","handleBlur","activeElement","isOnInput","pointerEvent","reason","reason_parts_exports","handleClick","clickPosition","handleKeyDownWhenClosed","handleKeyDownFromHook","usePopupMenuKeyboard","ComboboxInput","props","forwardedRef","placeholderProp","disabledProp","cursorBehavior","render","className","style","onFocus","onBlur","onClick","onKeyDown","rest","comboboxContext","useComboboxContext","popupMenuContext","usePopupMenuContext","focusOwnerStore","useFocusOwner","isInsideInputWrapper","useIsInsideInputWrapper","disabled","placeholder","open","hasValue","displayValue","getValueText","useComboboxDisplayValue","handleChange","handleFocus","handleBlur","handleClick","handleKeyDown","useComboboxInputBehavior","dataAttrs","ComboboxInputDataAttributes","mergedRef","node","state","inputEmbeddedStyles","import_use_render","React","ComboboxInputWrapperDataAttributes","import_jsx_runtime","stateAttributesMapping","value","ComboboxInputWrapperDataAttributes","ComboboxInputWrapper","props","forwardedRef","render","className","style","children","rest","store","usePopupMenuContext","comboboxContext","useComboboxContext","open","state","inputEmbeddedStyles","mergedRef","node","element","ComboboxInputWrapperContext","import_use_render","React","defaultItemEquality","item","value","compareItemEquality","comparer","itemIncludes","collection","removeItem","collection","value","comparer","item","compareItemEquality","ComboboxItemDataAttributes","React","ComboboxItemContext","useComboboxItemContext","context","useMaybeComboboxItemContext","import_jsx_runtime","stateAttributesMapping","value","ComboboxItemDataAttributes","resolveLabelFromItems","items","i","ComboboxItemImpl","props","forwardedRef","textValueProp","keywordsProp","disabled","onSelect","forceMount","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","comboboxContext","useComboboxContext","serializedValue","stringifyAsValue","labelFromItems","labelFromObjectValue","resolveLabel","textValue","keywords","labelStr","textRef","selected","itemIncludes","compareItemEquality","closeOnClick","item","usePopupMenuItem","handleSelect","newValues","removeItem","text","state","itemContextValue","handleClick","event","handlePointerDown","handlePointerMove","element","ComboboxItemContext","ComboboxItem","import_use_render","React","ComboboxItemIndicatorDataAttributes","stateAttributesMapping","value","ComboboxItemIndicatorDataAttributes","ComboboxItemIndicator","props","forwardedRef","keepMounted","render","className","style","rest","itemContext","useComboboxItemContext","state","element","import_use_render","React","ComboboxItemLabelDataAttributes","resolveLabelFromItems","items","valueKey","i","ComboboxItemLabel","props","forwardedRef","render","className","style","children","rest","comboboxContext","useComboboxContext","itemContext","useComboboxItemContext","stringifyAsValue","resolvedLabel","labelFromItems","state","ComboboxItemLabelDataAttributes","import_popover","React","ComboboxPositionerDataAttributes","import_jsx_runtime","getInputEmbeddedStyles","actualSide","inputHeight","inputWidth","popupPadding","popupWidth","popupMarginBottom","popupPaddingBottom","popupMarginTop","popupPaddingTop","ComboboxPositioner","props","forwardedRef","layoutProp","side","alignProp","sideOffset","anchorProp","className","style","children","rest","comboboxContext","useComboboxContext","layout","isInputEmbedded","anchor","effectiveSideOffset","effectiveAlign","basePositionerStyles","ComboboxPositionerDataAttributes","renderProps","state","contextValue","cssVariables","positioningStyles","enhancedChildren","child","ComboboxPositionerContext","positionerStyles","import_popover","React","import_jsx_runtime","ComboboxRoot","props","openProp","onOpenChange","defaultOpen","valueProp","defaultValue","onValueChange","multiple","valuesProp","defaultValues","onValuesChange","isItemEqualToValue","defaultItemEquality","itemToStringLabel","itemToStringValue","inputValueProp","defaultInputValue","onInputValueChange","name","form","required","disabled","placeholder","items","modal","closeOnSelectProp","openOnFocus","virtualized","virtualItems","onHighlightChange","layout","onOpenChangeCompleteProp","children","rest","listId","inputRef","inputWrapperRef","inputHeight","setInputHeight","inputWidth","setInputWidth","setInputElement","element","rect","setInputWrapperElement","store","focusOwnerStore","openChainStore","registerSurface","closeAll","virtualization","baseHandleOpenChange","usePopupMenuRoot","open","handleOpenChange","newOpen","reason","event","handleOpenChangeComplete","nextOpen","handlePopoverOpenChange","popoverDetails","internalValue","setInternalValue","value","handleValueChange","newValue","internalValues","setInternalValues","values","handleValuesChange","newValues","internalInputValue","setInternalInputValue","inputValue","handleInputValueChange","itemTextRegistryRef","registerItemText","itemValue","text","closeOnSelect","filterModeRef","setFilterModeState","setFilterMode","mode","filterMode","setFilterActive","openCombobox","closeCombobox","currentMode","searchToFreeze","comboboxContextValue","hiddenInputs","v","index","serializedValue","stringifyAsValue","ComboboxContext","PopupMenuProviders","React","ComboboxSurfaceDataAttributes","import_jsx_runtime","ComboboxSurface","props","forwardedRef","autoHighlightFirstProp","searchProp","onSearchChangeProp","onPointerMoveProp","rest","comboboxContext","useComboboxContext","handlePointerMove","event","input","autoHighlightFirst","prop","selectedValue","stringifyAsValue","filterMode","search","handleSearchChange","value","PopupMenuSurface","ComboboxSurfaceDataAttributes","ComboboxArrowDataAttributes","ComboboxBackdropDataAttributes","ComboboxEmptyDataAttributes","ComboboxGroupDataAttributes","ComboboxGroupLabelDataAttributes","ComboboxIconDataAttributes","ComboboxListDataAttributes","ComboboxPopupDataAttributes","ComboboxScrollArrowDataAttributes","ComboboxSeparatorDataAttributes","index_parts_exports","__export","PopupMenuArrow","PopupMenuBackdrop","PopupMenuCheckboxItem","PopupMenuCheckboxItemIndicator","PopupMenuInput","PopupMenuDataList","PopupMenuDataSurface","PopupMenuEmpty","PopupMenuGroup","PopupMenuGroupLabel","PopupMenuIcon","PopupMenuItem","PopupMenuList","PopupMenuPopup","PopupMenuPortal","PopupMenuPositioner","PopupMenuRadioGroup","PopupMenuRadioGroupValue","PopupMenuRadioItem","PopupMenuRadioItemIndicator","ContextMenuRoot","PopupMenuScrollDownArrow","PopupMenuScrollUpArrow","PopupMenuSeparator","PopupMenuShortcut","PopupMenuSubmenuRoot","PopupMenuSubmenuTrigger","PopupMenuSubmenuTriggerIndicator","PopupMenuSurface","ContextMenuTrigger","import_popover","React","import_jsx_runtime","ContextMenuInternalContext","useContextMenuInternal","context","createVirtualAnchor","x","y","isTouchEvent","size","ContextMenuRoot","props","openProp","onOpenChange","defaultOpen","virtualized","itemsProp","onHighlightChange","disabled","modal","closeOnOutsidePress","onOpenChangeCompleteProp","getQualifiedRowId","children","store","focusOwnerStore","openChainStore","registerSurface","closeAll","virtualization","handleOpenChange","usePopupMenuRoot","open","virtualAnchor","setVirtualAnchor","setAnchorPosition","openMenu","closeMenu","handleOpenChangeComplete","nextOpen","handlePopoverOpenChange","popoverDetails","internalContextValue","PopupMenuProviders","import_use_render","React","ContextMenuTriggerDataAttributes","LONG_PRESS_DELAY","MOVE_THRESHOLD","stateAttributesMapping","value","ContextMenuTrigger","props","forwardedRef","disabledProp","render","className","style","onContextMenu","onTouchStart","onTouchMove","onTouchEnd","onTouchCancel","children","rest","setAnchorPosition","openMenu","rootDisabled","open","useContextMenuInternal","disabled","pressed","setPressed","longPressTimeoutRef","touchStartPosRef","clearLongPressTimeout","handleContextMenu","event","handleTouchStart","touch","handleTouchMove","dx","dy","handleTouchEnd","handleTouchCancel","state","ContextMenuArrowDataAttributes","ContextMenuBackdropDataAttributes","ContextMenuCheckboxItemDataAttributes","ContextMenuCheckboxItemIndicatorDataAttributes","ContextMenuEmptyDataAttributes","ContextMenuGroupDataAttributes","ContextMenuGroupLabelDataAttributes","ContextMenuIconDataAttributes","ContextMenuInputDataAttributes","ContextMenuItemDataAttributes","ContextMenuListDataAttributes","ContextMenuPopupDataAttributes","ContextMenuPositionerDataAttributes","ContextMenuRadioGroupDataAttributes","ContextMenuRadioItemDataAttributes","ContextMenuRadioItemIndicatorDataAttributes","ContextMenuScrollArrowDataAttributes","ContextMenuSeparatorDataAttributes","ContextMenuShortcutDataAttributes","ContextMenuSubmenuTriggerDataAttributes","ContextMenuSubmenuTriggerIndicatorDataAttributes","ContextMenuSurfaceDataAttributes","index_parts_exports","__export","PopupMenuArrow","PopupMenuBackdrop","PopupMenuCheckboxItem","PopupMenuCheckboxItemIndicator","PopupMenuInput","PopupMenuDataList","PopupMenuDataSurface","PopupMenuEmpty","PopupMenuGroup","PopupMenuGroupLabel","PopupMenuIcon","PopupMenuItem","PopupMenuList","PopupMenuPopup","PopupMenuPortal","PopupMenuPositioner","PopupMenuRadioGroup","PopupMenuRadioGroupValue","PopupMenuRadioItem","PopupMenuRadioItemIndicator","DropdownMenuRoot","PopupMenuScrollDownArrow","PopupMenuScrollUpArrow","PopupMenuSeparator","PopupMenuShortcut","PopupMenuSubmenuRoot","PopupMenuSubmenuTrigger","PopupMenuSubmenuTriggerIndicator","PopupMenuSurface","DropdownMenuTrigger","import_popover","import_react","import_jsx_runtime","DropdownMenuRoot","props","openProp","onOpenChange","defaultOpen","modal","virtualized","itemsProp","onHighlightChange","closeOnOutsidePress","onOpenChangeCompleteProp","getQualifiedRowId","children","rest","store","focusOwnerStore","openChainStore","registerSurface","closeAll","virtualization","handleOpenChange","usePopupMenuRoot","open","handleOpenChangeComplete","nextOpen","handlePopoverOpenChange","popoverDetails","PopupMenuProviders","import_popover","import_use_render","React","DropdownMenuTriggerDataAttributes","import_jsx_runtime","stateAttributesMapping","value","DropdownMenuTriggerInner","props","forwardedRef","render","children","disabled","className","style","triggerProps","triggerState","openOnHover","delay","closeDelay","rest","state","DropdownMenuTrigger","store","closeAll","closeOnOutsidePress","usePopupMenuContext","isOpen","triggerRef","setRef","element","trigger","handlePointerDown","event","reason_parts_exports","clickEvent","DropdownMenuArrowDataAttributes","DropdownMenuBackdropDataAttributes","DropdownMenuCheckboxItemDataAttributes","DropdownMenuCheckboxItemIndicatorDataAttributes","DropdownMenuEmptyDataAttributes","DropdownMenuGroupDataAttributes","DropdownMenuGroupLabelDataAttributes","DropdownMenuIconDataAttributes","DropdownMenuInputDataAttributes","DropdownMenuItemDataAttributes","DropdownMenuListDataAttributes","DropdownMenuPopupDataAttributes","DropdownMenuPositionerDataAttributes","DropdownMenuRadioGroupDataAttributes","DropdownMenuRadioItemDataAttributes","DropdownMenuRadioItemIndicatorDataAttributes","DropdownMenuScrollArrowDataAttributes","DropdownMenuSeparatorDataAttributes","DropdownMenuShortcutDataAttributes","DropdownMenuSubmenuTriggerDataAttributes","DropdownMenuSubmenuTriggerIndicatorDataAttributes","DropdownMenuSurfaceDataAttributes","index_parts_exports","__export","PopupMenuArrow","PopupMenuBackdrop","PopupMenuEmpty","PopupMenuGroup","PopupMenuGroupLabel","PopupMenuIcon","PopupMenuInput","SelectItem","SelectItemIndicator","SelectItemLabel","PopupMenuList","SelectPopup","PopupMenuPortal","SelectPositioner","SelectRoot","PopupMenuScrollDownArrow","PopupMenuScrollUpArrow","PopupMenuSeparator","SelectSurface","SelectTrigger","SelectValue","import_use_render","React","React","SelectContext","useSelectContext","context","useMaybeSelectContext","SelectItemDataAttributes","React","SelectItemContext","useSelectItemContext","context","useMaybeSelectItemContext","import_jsx_runtime","stateAttributesMapping","value","SelectItemDataAttributes","resolveLabelFromItems","items","i","SelectItemImpl","props","forwardedRef","textValueProp","keywordsProp","disabled","onSelect","forceMount","render","className","style","onClick","onPointerDown","onPointerMove","children","rest","selectContext","useSelectContext","serializedValue","stringifyAsValue","labelFromItems","labelFromObjectValue","resolveLabel","textValue","keywords","labelStr","textRef","selected","itemIncludes","compareItemEquality","closeOnClick","item","usePopupMenuItem","handleSelect","newValues","removeItem","text","state","itemContextValue","handleClick","event","handlePointerDown","handlePointerMove","element","SelectItemContext","SelectItem","import_use_render","React","SelectItemIndicatorDataAttributes","stateAttributesMapping","value","SelectItemIndicatorDataAttributes","SelectItemIndicator","props","forwardedRef","render","className","style","forceMount","keepMounted","children","rest","selected","useSelectItemContext","state","shouldRender","content","element","import_use_render","React","SelectItemLabelDataAttributes","resolveLabelFromItems","items","valueKey","i","SelectItemLabel","props","forwardedRef","render","className","style","children","rest","selectContext","useSelectContext","itemContext","useSelectItemContext","textRef","stringifyAsValue","resolvedLabel","labelFromItems","state","mergedRef","node","SelectItemLabelDataAttributes","import_popover","React","React","SelectPositionerContext","useSelectPositionerContext","import_jsx_runtime","SelectPopup","props","forwardedRef","classNameProp","rest","alignItemWithTriggerActive","useSelectPositionerContext","className","baseState","extendedState","PopupMenuPopup","import_popover","React","SelectPositionerDataAttributes","import_jsx_runtime","MARGIN","MIN_HEIGHT","TRIGGER_COLLISION_THRESHOLD","calculateAlignmentPosition","params","triggerElement","positioner","valueElement","itemText","triggerRect","positionerRect","viewportHeight","viewportWidth","triggerTooCloseToTop","triggerTooCloseToBottom","popupTooSmall","offsetX","offsetY","valueRect","textRect","valueLeftFromTrigger","textLeftFromPositioner","valueCenterY","textCenterFromPositioner","left","top","maxLeft","maxTop","availableHeight","SelectPositioner","props","forwardedRef","alignItemWithTrigger","sideProp","alignProp","sideOffset","className","style","children","rest","popupMenuContext","usePopupMenuContext","selectContext","useSelectContext","open","alignItemWithTriggerActive","setAlignItemWithTriggerActive","positionState","setPositionState","positionerRef","scrollUpArrowRef","scrollDownArrowRef","resetPositioningState","selectedItemText","firstItemText","result","renderedSide","contextValue","mergedRef","node","shouldHide","alignmentStyles","SelectPositionerContext","SelectPositionerDataAttributes","import_popover","React","import_jsx_runtime","SelectRoot","props","openProp","onOpenChange","onOpenChangeComplete","defaultOpen","valueProp","defaultValue","onValueChange","multiple","valuesProp","defaultValues","onValuesChange","isItemEqualToValue","defaultItemEquality","itemToStringLabel","itemToStringValue","name","form","required","disabled","placeholder","items","modal","virtualized","virtualItems","onHighlightChange","children","rest","listId","triggerRef","valueRef","selectedItemTextRef","firstItemTextRef","setTriggerElement","element","setValueElement","resetPositioningCallbackRef","registerResetPositioningCallback","callback","store","focusOwnerStore","openChainStore","registerSurface","closeAll","virtualization","handleOpenChange","usePopupMenuRoot","open","internalValue","setInternalValue","value","handleValueChange","newValue","internalValues","setInternalValues","values","handleValuesChange","newValues","itemTextRegistryRef","registerItemText","itemValue","text","selectContextValue","hiddenInputs","v","index","serializedValue","stringifyAsValue","handlePopoverOpenChange","nextOpen","popoverDetails","handleOpenChangeComplete","SelectContext","PopupMenuProviders","React","SelectSurfaceDataAttributes","import_jsx_runtime","SelectSurface","props","forwardedRef","autoHighlightFirstProp","rest","selectContext","useSelectContext","positionerContext","useSelectPositionerContext","autoHighlightFirst","serializeValue","value","stringifyAsValue","selectedValue","PopupMenuSurface","SelectSurfaceDataAttributes","import_popover","import_use_render","React","SelectTriggerDataAttributes","import_jsx_runtime","stateAttributesMapping","value","SelectTriggerDataAttributes","SelectTriggerInner","props","forwardedRef","render","children","disabledProp","className","style","triggerProps","triggerState","rest","selectContext","useSelectContext","disabled","hasValue","state","internalRef","node","SelectTrigger","import_use_render","React","SelectValueDataAttributes","stateAttributesMapping","value","SelectValueDataAttributes","SelectValueImpl","props","forwardedRef","render","className","style","placeholderProp","children","rest","selectContext","useSelectContext","placeholder","hasValue","getValueText","serializedValue","stringifyAsValue","registryText","items","item","label","resolvedLabel","resolveLabel","state","content","texts","v","text","internalRef","node","SelectValue","SelectArrowDataAttributes","SelectBackdropDataAttributes","SelectEmptyDataAttributes","SelectGroupDataAttributes","SelectGroupLabelDataAttributes","SelectIconDataAttributes","SelectInputDataAttributes","SelectListDataAttributes","SelectPopupDataAttributes","SelectScrollArrowDataAttributes","SelectSeparatorDataAttributes"]}
|