@republicroad/seal-editor 1.24.0 → 1.26.0
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/field-picker-popup-DynXyvQG.js +2453 -0
- package/dist/field-picker-popup-DynXyvQG.js.map +1 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +6023 -5434
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/utils-CX-Pz5p6.js +10 -0
- package/dist/utils-CX-Pz5p6.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-picker-popup-DynXyvQG.js","names":[],"sources":["../src/reui/scroll-area.tsx","../src/reui/cascader/cascader-context.tsx","../src/reui/cascader/cascader-lib.tsx","../src/reui/cascader/cascader-async.tsx","../src/reui/cascader/cascader-i18n.tsx","../src/reui/cascader/icon-placeholder.tsx","../src/reui/cascader/cascader.tsx","../src/reui/spinner.tsx","../src/reui/cascader/cascader-item.tsx","../src/reui/cascader/cascader-nav.tsx","../src/reui/cascader/field-picker-popup.tsx"],"sourcesContent":["import { cn } from '#lib/utils';\nimport { ScrollArea as ScrollAreaPrimitive } from '@base-ui/react/scroll-area';\n\n/**\n * ScrollArea 薄封装(reui/base-nova API 面:`<ScrollArea className>` 即完整),\n * 走 Base UI scroll-area——external 依赖,零 kernel 包体成本。\n */\nfunction ScrollArea({ className, children, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root data-slot='scroll-area' className={cn('relative', className)} {...props}>\n <ScrollAreaPrimitive.Viewport\n data-slot='scroll-area-viewport'\n className='size-full rounded-[inherit] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1'\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = 'vertical',\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Scrollbar>) {\n return (\n <ScrollAreaPrimitive.Scrollbar\n data-slot='scroll-area-scrollbar'\n orientation={orientation}\n className={cn(\n 'flex touch-none select-none p-px opacity-0 transition-opacity duration-150 data-[hovering]:opacity-100 data-[scrolling]:opacity-100',\n orientation === 'vertical' ? 'w-2.5 border-l border-l-transparent' : 'h-2.5 border-t border-t-transparent',\n className,\n )}\n {...props}\n >\n <ScrollAreaPrimitive.Thumb data-slot='scroll-area-thumb' className='relative flex-1 rounded-full bg-border' />\n </ScrollAreaPrimitive.Scrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n","import * as React from 'react';\n\nimport type {\n CascaderActionItem,\n CascaderChangeReason,\n CascaderFlatNode,\n CascaderIndex,\n CascaderLabels,\n CascaderLoadState,\n CascaderMode,\n CascaderNode,\n CascaderSearchScope,\n} from './cascader-types';\n\n/**\n * Four contexts, not one: actions (config and callbacks, near-stable), state\n * (every keystroke), render (`renderItem` identity) and highlight (every arrow\n * key and pointer move). One combined context re-rendered every row on every\n * keystroke, which is what made `React.memo` on the row worth nothing.\n */\n\n/* -------------------------------------------------------------------------- */\n/* Shared types */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderColumn<T = unknown> {\n parent: CascaderNode<T> | null;\n items: CascaderNode<T>[];\n depth: number;\n /** The node in this column that is drilled into, if any. */\n activeValue: string | null;\n /** Whether this is the deepest column, the one Base UI owns. */\n active: boolean;\n}\n\nexport interface CascaderItemState<T = unknown> {\n branch: boolean;\n selected: boolean;\n /** The node's own flag or a disabled ancestor's, as `isCascaderDisabled`. */\n disabled: boolean;\n depth: number;\n count: number;\n /** Ancestor chain, root first. Populated for deep and global search rows. */\n path: CascaderNode<T>[];\n}\n\n/* -------------------------------------------------------------------------- */\n/* State */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Everything derived from the query, the path and the selection. One keystroke\n * rebuilds most of it, so never subscribe to it from a row.\n */\nexport interface CascaderStateContextValue<T = unknown> {\n /** Same `useMemo` identity as the actions context's `index`. */\n index: CascaderIndex<T>;\n path: string[];\n expanded: ReadonlySet<string>;\n query: string;\n currentParent: CascaderNode<T> | null;\n /** Rows for the current level, already filtered. */\n levelItems: CascaderNode<T>[];\n deepResults: CascaderNode<T>[] | null;\n /** What `Combobox.Root` is currently rendering, in render order. */\n renderedItems: CascaderNode<T>[];\n columns: CascaderColumn<T>[];\n treeRows: CascaderFlatNode<T>[];\n selectedValues: string[];\n /** Selected nodes below each value, at any depth. Absent means zero. */\n selectedDescendants: ReadonlyMap<string, number>;\n /**\n * Per level, keyed by parent value or `CASCADER_ROOT_KEY`. MEMBERSHIP is the\n * discriminator: no entry means never fetched, an entry with no `loading`, no\n * `error` and no children means fetched and genuinely empty.\n */\n loadStates: ReadonlyMap<string, CascaderLoadState>;\n /** Async search, `null` when idle. Separate: a search belongs to no level. */\n searchState: CascaderLoadState | null;\n announcement: string;\n}\n\nconst CascaderStateContext = React.createContext<CascaderStateContextValue | undefined>(undefined);\n\n/**\n * One provider serves every `T`, so the context holds an erased `unknown` value\n * and this cast restores it. The primitive never inspects the payload.\n */\nexport function useCascaderState<T = unknown>(): CascaderStateContextValue<T> {\n const context = React.useContext(CascaderStateContext);\n if (!context) {\n throw new Error('useCascaderState must be used within a Cascader');\n }\n return context as unknown as CascaderStateContextValue<T>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Actions */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Config and callbacks, slow enough that a memoised row can subscribe: the\n * mutators are `[]`-dep callbacks over a latest-props ref. The predicates are\n * the exception, read DURING RENDER where a ref written in an effect would\n * return the previous commit's answer, so each is memoised on its own input.\n */\nexport interface CascaderActionsContextValue<T = unknown> {\n index: CascaderIndex<T>;\n mode: CascaderMode;\n multiple: boolean;\n /** Multi-select only: a commit propagates over the LOADED subtree. */\n cascade: boolean;\n /** Whether a BRANCH is committable. Per-LIST: the check gutter is a COLUMN. */\n branchesSelectable: boolean;\n /** Draws the SINGLE-SELECT check and its gutter. Ignored in multi-select. */\n indicator: boolean;\n expandTrigger?: 'click' | 'hover';\n actions: CascaderActionItem[];\n searchScope: CascaderSearchScope;\n maxHeight?: number | string;\n inline: boolean;\n invalid: boolean;\n /**\n * Id prefix; columns are `${baseId}-column-${depth}`. The SCHEME is contract:\n * the filters primitive's `FilterMenuPinKeeper` restores its highlight across\n * a live re-pin through `${baseId}-column-0` and the `cascader-item` slot.\n */\n baseId: string;\n labels: CascaderLabels;\n\n /**\n * Whether rows are WINDOWED. Also handed to `Combobox.Root`, which is what\n * makes an explicit row `index` legal: forwarding one while this is false\n * makes `aria-activedescendant` resolve to nothing. Latched per level.\n */\n virtualized: boolean;\n /** Mounts a windowing renderer, returns its unregister. LAYOUT effect only. */\n registerVirtualRenderer: () => () => void;\n /** The root's `virtualize` prop. `undefined` means \"decide by count\". */\n virtualize?: boolean;\n virtualizeThreshold: number;\n estimateRowSize: number;\n overscan: number;\n\n /** Tells \"this level is empty\" from \"not fetched yet\" before a load state. */\n hasLoader: boolean;\n /** Next page of a level. Latched: a page with nothing new is not re-asked. */\n loadMore: (parentKey: string) => void;\n retryLevel: (parentKey: string) => void;\n /**\n * Evicts one level's async cache, `null` for the root, so membership reads\n * never-loaded. A level that is on screen when evicted refetches at once.\n */\n invalidateLevel: (value: string | null) => void;\n\n /** Index as of the last commit. Use in the stable callbacks, not `index`. */\n getIndex: () => CascaderIndex<T>;\n getState: () => CascaderStateContextValue<T>;\n /** Highlighted row or null. A getter: the highlight moves per arrow key. */\n getHighlighted: () => CascaderNode<T> | null;\n\n setPath: (next: string[] | ((prev: string[]) => string[])) => void;\n pushLevel: (value: string) => void;\n popLevel: () => void;\n goToDepth: (depth: number) => void;\n toggleExpanded: (value: string) => void;\n /**\n * Registers a footer submenu as open or closed. `Combobox` has no\n * `FloatingTree`, so one Escape would dismiss the flyout AND the cascader;\n * the root's `onOpenChange` guard cancels the close while any is open, from a\n * ref so it reads as of that event without re-rendering the root.\n */\n setFlyoutOpen: (key: string, open: boolean) => void;\n hasOpenFlyout: () => boolean;\n setQuery: (next: string) => void;\n /**\n * Replaces the selection. `onValueChange` diffs it against the current one\n * for its node and reason; pass `reason` only when the caller knows better.\n */\n setSelection: (values: string[], reason?: CascaderChangeReason) => void;\n /** Commits a node, for rows outside the listbox such as ancestor columns. */\n commit: (node: CascaderNode<T>) => void;\n navigate: (node: CascaderNode<T>) => void;\n /** Into `node` as a child of `depth`, replacing anything deeper. */\n navigateAt: (node: CascaderNode<T>, depth: number) => void;\n /** Never undefined: falls back to a remembered label, then a synthetic node. */\n resolveNode: (value: string) => CascaderNode<T>;\n isBranch: (node: CascaderNode<T>) => boolean;\n isSelectable: (node: CascaderNode<T>) => boolean;\n /**\n * The node or an ancestor is `disabled`. Rows render it disabled; row\n * presses, keys, `commit`, `navigate`, `navigateAt` and a held navigation\n * refuse it. `pushLevel`, `setPath`, `toggleExpanded` and `setSelection` are\n * raw setters and do not ask.\n */\n isDisabled: (node: CascaderNode<T>) => boolean;\n isSelected: (node: CascaderNode<T>) => boolean;\n /** Always `false` without `cascade`: partial selection needs propagation. */\n isIndeterminate: (node: CascaderNode<T>) => boolean;\n /**\n * O(1) read of `selectedDescendants`; a memoised row may not subscribe.\n * Unlike `isIndeterminate` this answers in every mode.\n */\n selectedDescendantCount: (node: CascaderNode<T>) => number;\n}\n\nconst CascaderActionsContext = React.createContext<CascaderActionsContextValue | undefined>(undefined);\n\nexport function useCascaderActions<T = unknown>(): CascaderActionsContextValue<T> {\n const context = React.useContext(CascaderActionsContext);\n if (!context) {\n throw new Error('useCascaderActions must be used within a Cascader');\n }\n return context as unknown as CascaderActionsContextValue<T>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Render props */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Their own context, republished every render. They cannot ride on the actions\n * context: an inline closure read off a memoised object is whichever closure\n * that object captured, so the row would call a stale prop over stale state.\n */\nexport interface CascaderRenderContextValue<T = unknown> {\n renderItem?: (node: CascaderNode<T>, state: CascaderItemState<T>) => React.ReactNode;\n renderLabel?: (node: CascaderNode<T>, state: CascaderItemState<T>) => React.ReactNode;\n}\n\nconst CascaderRenderContext = React.createContext<CascaderRenderContextValue>({});\n\nexport function useCascaderRender<T = unknown>(): CascaderRenderContextValue<T> {\n return React.useContext(CascaderRenderContext) as CascaderRenderContextValue<T>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Highlight store */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderHighlight {\n index: number;\n value: string | null;\n}\n\n/**\n * An external store, deliberately NOT React state: `onItemHighlighted` fires on\n * every arrow key AND every pointer move over the list, so `setState` would\n * re-render the whole root at mousemove rate. A store re-renders subscribers\n * only, which inside the primitive is the virtualizer.\n */\nexport interface CascaderHighlightStore {\n subscribe: (onStoreChange: () => void) => () => void;\n getSnapshot: () => CascaderHighlight;\n set: (next: CascaderHighlight) => void;\n}\n\nconst NO_HIGHLIGHT: CascaderHighlight = { index: -1, value: null };\n\nexport function createCascaderHighlightStore(): CascaderHighlightStore {\n let snapshot: CascaderHighlight = NO_HIGHLIGHT;\n const listeners = new Set<() => void>();\n\n return {\n subscribe(onStoreChange) {\n listeners.add(onStoreChange);\n return () => {\n listeners.delete(onStoreChange);\n };\n },\n // The SAME object until something changes; `useSyncExternalStore` needs it.\n getSnapshot() {\n return snapshot;\n },\n set(next) {\n if (next.index === snapshot.index && next.value === snapshot.value) return;\n snapshot = next;\n for (const listener of listeners) listener();\n },\n };\n}\n\n/** Shared and permanently empty, so the hook degrades outside a `Cascader`. */\nconst FALLBACK_HIGHLIGHT_STORE = createCascaderHighlightStore();\n\nconst CascaderHighlightContext = React.createContext<CascaderHighlightStore>(FALLBACK_HIGHLIGHT_STORE);\n\n/** Subscribes to the highlight. Re-renders ONLY the calling component. */\nexport function useCascaderHighlight(): CascaderHighlight {\n const store = React.useContext(CascaderHighlightContext);\n return React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n}\n\nexport { CascaderActionsContext, CascaderHighlightContext, CascaderRenderContext, CascaderStateContext };\n","import type {\n CascaderCollapse,\n CascaderFlatNode,\n CascaderIndex,\n CascaderNode,\n CascaderPathSegment,\n CascaderSelectable,\n} from './cascader-types';\n\n/** Root level key in `childrenOf`. NUL-prefixed so no real value collides. */\nexport const CASCADER_ROOT_KEY = '\\u0000root';\n\n/**\n * Paging pseudo-node prefix. Written as an escape sequence, not a raw 0x00\n * byte: a literal NUL makes this module read as binary and `grep -I` skips it.\n */\nexport const CASCADER_MORE_PREFIX = '\\u0000more:';\n\n/* -------------------------------------------------------------------------- */\n/* Scroll layout */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The four scroll classes. In the lib because `cascader-columns.tsx` needs them\n * too and must not import `cascader.tsx`. Shell > bound > scrollport > rows.\n */\n\n/**\n * The bound. `min()` over an undefined custom property is an INVALID\n * declaration that drops the whole max-height, hence the `100vh` fallback: an\n * inline panel has no positioner, so no `--available-height`. `24rem` is the\n * default cap, so the common case sets no variable at all.\n */\nexport const CASCADER_LIST_HEIGHT_CLASS = 'max-h-[min(var(--available-height,100vh),var(--cascader-max-height,24rem))]';\n\n/**\n * Each style's list padding: rows take it as `padding`, the scrollport as\n * `scroll-padding` floored at 4px so lyra's `0` does not strand a row.\n * Mirrored per style from `registry/styles/style-*.css`; keep them in step.\n */\nexport const CASCADER_LIST_PAD_CLASS = '[--cascader-list-pad:4px]';\n\n/** The scrollport: a `max-h-*` on the ScrollArea ROOT bounds nothing. */\nexport const CASCADER_SCROLL_CLASS =\n 'size-full min-h-0 **:data-[slot=scroll-area-viewport]:h-full **:data-[slot=scroll-area-viewport]:overscroll-contain **:data-[slot=scroll-area-viewport]:scroll-py-[max(var(--cascader-list-pad,4px),4px)]';\n\n/** The rows' box; `data-empty:p-0` keeps an empty state from double inset. */\nexport const CASCADER_ROWS_CLASS = 'p-(--cascader-list-pad,4px) data-empty:p-0';\n\n/* -------------------------------------------------------------------------- */\n/* Tab order */\n/* -------------------------------------------------------------------------- */\n\n/**\n * What counts as a keyboard stop. Base UI's ScrollArea viewport makes ITSELF\n * tabbable when content overflows (`hiddenState.x && hiddenState.y ? -1 : 0`),\n * an unnamed stop per level that `ui/scroll-area.tsx` will not let us suppress.\n */\nconst CASCADER_TAB_STOP_SELECTOR =\n 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\n/** The stop to step over: nothing here focuses the scrollport on purpose. */\nconst CASCADER_TAB_SKIP_SELECTOR = '[data-slot=\"scroll-area-viewport\"]';\n\n/** Out of the tab order whatever they contain; layout is never consulted. */\nconst CASCADER_TAB_HIDDEN_SELECTOR = \"[hidden],[inert],[aria-hidden='true']\";\n\n/** The panel's real keyboard stops, in DOM order. */\nfunction getCascaderTabStops(panel: HTMLElement): HTMLElement[] {\n const stops = Array.from(panel.querySelectorAll<HTMLElement>(CASCADER_TAB_STOP_SELECTOR));\n return stops.filter(\n (stop) =>\n // Option and trail rows are real `<button>`s with `tabindex=\"-1\"`.\n stop.getAttribute('tabindex') !== '-1' &&\n !stop.matches(CASCADER_TAB_SKIP_SELECTOR) &&\n !stop.closest(CASCADER_TAB_HIDDEN_SELECTOR),\n );\n}\n\n/** The footer's own stops; an `aria-disabled` command still counts as one. */\nexport function getCascaderFooterStops(scope: HTMLElement): HTMLElement[] {\n const footer = scope.matches('[data-slot=\"cascader-footer\"]')\n ? scope\n : scope.querySelector<HTMLElement>('[data-slot=\"cascader-footer\"]');\n if (!footer) return [];\n return getCascaderTabStops(footer);\n}\n\n/** Where Tab lands, or `null` to let the browser out: focus is never trapped. */\nexport function getCascaderTabTarget(panel: HTMLElement, from: Element | null, backwards: boolean): HTMLElement | null {\n const stops = getCascaderTabStops(panel);\n if (stops.length === 0 || !from) return null;\n\n const index = stops.indexOf(from as HTMLElement);\n if (index !== -1) return stops[index + (backwards ? -1 : 1)] ?? null;\n\n if (backwards) {\n for (let i = stops.length - 1; i >= 0; i -= 1) {\n const position = from.compareDocumentPosition(stops[i]);\n if (position & Node.DOCUMENT_POSITION_PRECEDING) return stops[i];\n }\n return null;\n }\n\n for (const stop of stops) {\n const position = from.compareDocumentPosition(stop);\n if (position & Node.DOCUMENT_POSITION_FOLLOWING) return stop;\n }\n return null;\n}\n\n/**\n * The writing direction at `element`. `DirectionProvider` may only vote yes:\n * unmounted it answers `\"ltr\"`, which would override a real `<html dir=\"rtl\">`.\n */\nexport function isCascaderRtl(element: Element, provided: string): boolean {\n if (provided === 'rtl') return true;\n const explicit = element.closest('[dir]')?.getAttribute('dir')?.toLowerCase();\n if (explicit === 'rtl') return true;\n if (explicit === 'ltr') return false;\n return element.ownerDocument?.defaultView?.getComputedStyle(element).direction === 'rtl';\n}\n\n/**\n * The paging row as a REAL node, not a DOM-only row after the list: every index\n * Base UI hands out indexes the RENDERED array, so a DOM-only row shifts them.\n */\nexport function createCascaderMoreNode<T = unknown>(parentKey: string, loadedCount = 0): CascaderNode<T> {\n return {\n value: `${CASCADER_MORE_PREFIX}${parentKey}`,\n // Empty on purpose: a typeahead letter must never reach the paging row.\n label: '',\n // Feeds the row's \"Loading more...\" wording, with no second prop to thread.\n count: loadedCount,\n };\n}\n\nexport function isCascaderMoreNode<T>(node: CascaderNode<T>): boolean {\n return node.value.startsWith(CASCADER_MORE_PREFIX);\n}\n\n/** The level key a paging pseudo-node belongs to, or `null` for a real node. */\nexport function getCascaderMoreParent<T>(node: CascaderNode<T>): string | null {\n if (!isCascaderMoreNode(node)) return null;\n return node.value.slice(CASCADER_MORE_PREFIX.length);\n}\n\n/** Either input shape into one index. Cycle-guarded depths; first wins. */\nexport function buildCascaderIndex<T = unknown>(\n items: readonly CascaderNode<T>[] | undefined,\n getParent?: (node: CascaderNode<T>) => string | null | undefined,\n): CascaderIndex<T> {\n const byValue = new Map<string, CascaderNode<T>>();\n const childrenOf = new Map<string, CascaderNode<T>[]>();\n const parentOf = new Map<string, string | null>();\n const depthOf = new Map<string, number>();\n const all: CascaderNode<T>[] = [];\n\n const push = (parentKey: string, node: CascaderNode<T>) => {\n const bucket = childrenOf.get(parentKey);\n if (bucket) {\n bucket.push(node);\n } else {\n childrenOf.set(parentKey, [node]);\n }\n };\n\n if (getParent) {\n for (const node of items ?? []) {\n // A nullish entry is a data bug: skip it like a duplicate, say so in dev.\n if (node == null) {\n if (process.env.NODE_ENV !== 'production') {\n warnCascaderOnce(\n 'nullish-entry',\n 'Ignored a null or undefined entry in `items` or `children`. Check the arrays you pass in.',\n );\n }\n continue;\n }\n if (byValue.has(node.value)) continue;\n byValue.set(node.value, node);\n all.push(node);\n }\n\n for (const node of all) {\n const rawParent = getParent(node);\n // An unknown parent makes the node a root rather than dropping the row.\n const parent = rawParent != null && byValue.has(rawParent) ? rawParent : null;\n parentOf.set(node.value, parent);\n push(parent ?? CASCADER_ROOT_KEY, node);\n }\n\n for (const node of all) {\n let depth = 0;\n let cursor = parentOf.get(node.value) ?? null;\n const seen = new Set<string>([node.value]);\n while (cursor != null && !seen.has(cursor)) {\n seen.add(cursor);\n depth += 1;\n cursor = parentOf.get(cursor) ?? null;\n }\n depthOf.set(node.value, depth);\n }\n } else {\n const walk = (nodes: readonly CascaderNode<T>[] | undefined, parent: string | null, depth: number) => {\n for (const node of nodes ?? []) {\n // Same degradation as the flat path above.\n if (node == null) {\n if (process.env.NODE_ENV !== 'production') {\n warnCascaderOnce(\n 'nullish-entry',\n 'Ignored a null or undefined entry in `items` or `children`. Check the arrays you pass in.',\n );\n }\n continue;\n }\n if (byValue.has(node.value)) continue;\n byValue.set(node.value, node);\n parentOf.set(node.value, parent);\n depthOf.set(node.value, depth);\n all.push(node);\n push(parent ?? CASCADER_ROOT_KEY, node);\n if (node.children?.length) walk(node.children, node.value, depth + 1);\n }\n };\n walk(items, null, 0);\n }\n\n return {\n byValue,\n childrenOf,\n parentOf,\n depthOf,\n roots: childrenOf.get(CASCADER_ROOT_KEY) ?? [],\n all,\n };\n}\n\n/**\n * Folds loaded pages into an index built from `items`, so a re-render with a\n * new `items` array keeps what the user drilled into. Static `items` wins;\n * `detached` is `byValue` ONLY, or deep search doubles it and `childrenOf` lies.\n */\nexport function mergeCascaderIndex<T = unknown>(\n base: CascaderIndex<T>,\n pages: ReadonlyMap<string, readonly CascaderNode<T>[]>,\n detached?: ReadonlyMap<string, CascaderNode<T>>,\n): CascaderIndex<T> {\n // Identity stability: every downstream `useMemo` is keyed on this index.\n if (pages.size === 0 && !detached?.size) return base;\n\n const byValue = new Map(base.byValue);\n const childrenOf = new Map(base.childrenOf);\n const parentOf = new Map(base.parentOf);\n const depthOf = new Map(base.depthOf);\n\n // Copy-on-write per bucket: only levels that got a page pay for a new array.\n const copied = new Set<string>();\n const append = (parentKey: string, node: CascaderNode<T>) => {\n let bucket = childrenOf.get(parentKey);\n if (!copied.has(parentKey)) {\n bucket = bucket ? bucket.slice() : [];\n childrenOf.set(parentKey, bucket);\n copied.add(parentKey);\n }\n bucket!.push(node);\n };\n\n const insert = (parentKey: string, nodes: readonly CascaderNode<T>[]) => {\n for (const node of nodes) {\n if (byValue.has(node.value)) continue;\n byValue.set(node.value, node);\n parentOf.set(node.value, parentKey === CASCADER_ROOT_KEY ? null : parentKey);\n append(parentKey, node);\n if (node.children?.length) insert(node.value, node.children);\n }\n };\n\n for (const [parentKey, nodes] of pages) insert(parentKey, nodes);\n\n for (const value of byValue.keys()) {\n if (depthOf.has(value)) continue;\n let depth = 0;\n let cursor = parentOf.get(value) ?? null;\n const seen = new Set<string>([value]);\n while (cursor != null && !seen.has(cursor)) {\n seen.add(cursor);\n depth += 1;\n cursor = parentOf.get(cursor) ?? null;\n }\n depthOf.set(value, depth);\n }\n\n const roots = childrenOf.get(CASCADER_ROOT_KEY) ?? [];\n\n // Depth first over the MERGED tree, so `all` keeps document order.\n const all: CascaderNode<T>[] = [];\n const visited = new Set<string>();\n const walk = (nodes: readonly CascaderNode<T>[]) => {\n for (const node of nodes) {\n if (visited.has(node.value)) continue;\n visited.add(node.value);\n all.push(node);\n const children = childrenOf.get(node.value);\n if (children?.length) walk(children);\n }\n };\n walk(roots);\n\n // A page whose parent never arrived stays searchable rather than vanishing.\n for (const [value, node] of byValue) {\n if (visited.has(value)) continue;\n visited.add(value);\n all.push(node);\n }\n\n if (detached) {\n for (const [value, node] of detached) {\n if (byValue.has(value)) continue;\n byValue.set(value, node);\n }\n }\n\n return { byValue, childrenOf, parentOf, depthOf, roots, all };\n}\n\n/** Children of `parent`, or the root level when `parent` is nullish. */\nexport function getCascaderChildren<T>(index: CascaderIndex<T>, parent?: string | null): CascaderNode<T>[] {\n return index.childrenOf.get(parent ?? CASCADER_ROOT_KEY) ?? [];\n}\n\n/** A branch has known children, or `hasChildren` for an unfetched level. */\nexport function isCascaderBranch<T>(index: CascaderIndex<T>, node: CascaderNode<T>): boolean {\n if (node.hasChildren) return true;\n return (index.childrenOf.get(node.value)?.length ?? 0) > 0;\n}\n\n/** Trailing count for the default row. Explicit `count` wins over the tree. */\nexport function getCascaderCount<T>(index: CascaderIndex<T>, node: CascaderNode<T>): number {\n if (typeof node.count === 'number') return node.count;\n return index.childrenOf.get(node.value)?.length ?? 0;\n}\n\n/**\n * Whether a node is disabled: its own flag, or any ancestor's, since a disabled\n * branch keeps its whole subtree shut. The index's copy counts as its own, so a\n * server hit that omits the flag `items` sets is still caught. Ancestry is\n * `parentOf`: a detached hit the index has never placed answers for itself.\n */\nexport function isCascaderDisabled<T>(index: CascaderIndex<T>, node: CascaderNode<T>): boolean {\n if (node.disabled || index.byValue.get(node.value)?.disabled) return true;\n const seen = new Set<string>([node.value]);\n let cursor = index.parentOf.get(node.value) ?? null;\n while (cursor != null && !seen.has(cursor)) {\n seen.add(cursor);\n if (index.byValue.get(cursor)?.disabled) return true;\n cursor = index.parentOf.get(cursor) ?? null;\n }\n return false;\n}\n\n/** Whether a node may be committed as a selection. */\nexport function isCascaderSelectable<T>(\n index: CascaderIndex<T>,\n node: CascaderNode<T>,\n selectable: CascaderSelectable<T>,\n): boolean {\n // Before the branches a consumer controls: `selectable=\"any\"` says yes to\n // every node, and committing the paging row would select a level's name.\n if (isCascaderMoreNode(node)) return false;\n // Rows render this answer and their presses, keys, `commit`, `navigate` and\n // `navigateAt` check it, so a search lists a disabled subtree none of them\n // opens. The raw setters (`pushLevel`, `setPath`, `toggleExpanded`,\n // `setSelection`) do not ask.\n if (isCascaderDisabled(index, node)) return false;\n if (typeof selectable === 'function') return selectable(node);\n if (selectable === 'any') return true;\n return !isCascaderBranch(index, node);\n}\n\n/** Ancestor chain for `value`, root first. Empty while async data loads. */\nexport function getCascaderPath<T>(index: CascaderIndex<T>, value: string | null | undefined): CascaderNode<T>[] {\n if (value == null) return [];\n const chain: CascaderNode<T>[] = [];\n const seen = new Set<string>();\n let cursor: string | null | undefined = value;\n while (cursor != null && !seen.has(cursor)) {\n seen.add(cursor);\n const node = index.byValue.get(cursor);\n if (!node) break;\n chain.push(node);\n cursor = index.parentOf.get(cursor) ?? null;\n }\n return chain.reverse();\n}\n\n/**\n * `toLocaleLowerCase`, not `toLowerCase`: the invariant mapping turns Turkish\n * \"I\" into \"i\" not \"ı\", so \"ışık\" would never match \"IŞIK\". Both sides fold here.\n */\nexport function foldCascaderText(text: string): string {\n return text.toLocaleLowerCase();\n}\n\n/** Folds once so callers can hoist the cost out of a per-node loop. */\nexport function normalizeCascaderQuery(query: string): string {\n return foldCascaderText(query.trim());\n}\n\n/** Case-insensitive substring over label and keywords; pre-fold the query. */\nexport function matchesCascaderQuery<T>(node: CascaderNode<T>, normalized: string): boolean {\n if (!normalized) return true;\n // Coerced, not trusted: a label-less node is malformed data, not a crash.\n if (foldCascaderText(node.label ?? '').includes(normalized)) return true;\n if (node.keywords) {\n for (const keyword of node.keywords) {\n if (foldCascaderText(keyword).includes(normalized)) return true;\n }\n }\n return false;\n}\n\n/** Filters one level in place-order. Returns the input when the query is empty. */\nexport function filterCascaderLevel<T>(\n nodes: readonly CascaderNode<T>[],\n query: string,\n matches: (node: CascaderNode<T>, normalized: string) => boolean = matchesCascaderQuery,\n): CascaderNode<T>[] {\n const normalized = normalizeCascaderQuery(query);\n if (!normalized) return nodes as CascaderNode<T>[];\n return nodes.filter((node) => matches(node, normalized));\n}\n\n/** Searches every node, optionally under `within`, in one pass over `all`. */\nexport function searchCascaderDeep<T>(\n index: CascaderIndex<T>,\n query: string,\n options: {\n within?: string | null;\n limit?: number;\n matches?: (node: CascaderNode<T>, normalized: string) => boolean;\n } = {},\n): CascaderNode<T>[] {\n const normalized = normalizeCascaderQuery(query);\n if (!normalized) return [];\n\n const { within, limit = 200, matches = matchesCascaderQuery } = options;\n const results: CascaderNode<T>[] = [];\n\n // One memoised ancestry map per query. The provisional `false` written on the\n // way up doubles as the cycle guard; the trail is promoted once `within` hits.\n const ancestry = within == null ? null : new Map<string, boolean>();\n const isWithin = (node: CascaderNode<T>) => {\n if (within == null || !ancestry) return true;\n const trail: string[] = [];\n let answer = false;\n let cursor: string | null | undefined = index.parentOf.get(node.value);\n while (cursor != null) {\n if (cursor === within) {\n answer = true;\n break;\n }\n const cached = ancestry.get(cursor);\n if (cached !== undefined) {\n answer = cached;\n break;\n }\n ancestry.set(cursor, false);\n trail.push(cursor);\n cursor = index.parentOf.get(cursor) ?? null;\n }\n if (answer) for (const value of trail) ancestry.set(value, true);\n return answer;\n };\n\n for (const node of index.all) {\n if (results.length >= limit) break;\n if (!matches(node, normalized)) continue;\n if (!isWithin(node)) continue;\n results.push(node);\n }\n\n return results;\n}\n\n/**\n * Flattens the tree into tree mode's visible rows. A `sentinels` paging row\n * COUNTS as a sibling in `aria-setsize`: it holds an index of its own.\n */\nexport function flattenCascaderTree<T>(\n index: CascaderIndex<T>,\n expanded: ReadonlySet<string>,\n sentinels?: ReadonlySet<string>,\n): CascaderFlatNode<T>[] {\n const rows: CascaderFlatNode<T>[] = [];\n\n const walk = (nodes: readonly CascaderNode<T>[], parentKey: string, depth: number) => {\n const sentinel = sentinels?.has(parentKey) ?? false;\n const setSize = nodes.length + (sentinel ? 1 : 0);\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n const branch = isCascaderBranch(index, node);\n const isExpanded = branch && expanded.has(node.value);\n rows.push({\n node,\n depth,\n branch,\n expanded: isExpanded,\n setSize,\n posInSet: i + 1,\n });\n if (isExpanded) {\n walk(index.childrenOf.get(node.value) ?? [], node.value, depth + 1);\n }\n }\n if (sentinel) {\n rows.push({\n node: createCascaderMoreNode<T>(parentKey, nodes.length),\n depth,\n branch: false,\n expanded: false,\n setSize,\n posInSet: setSize,\n });\n }\n };\n\n walk(index.roots, CASCADER_ROOT_KEY, 0);\n return rows;\n}\n\n/** Shortens a path; the ellipsis segment still carries the hidden nodes. */\nexport function collapseCascaderPath<T>(\n path: readonly CascaderNode<T>[],\n options: { maxSegments?: number; collapse?: CascaderCollapse } = {},\n): CascaderPathSegment<T>[] {\n const { maxSegments = 3, collapse = 'middle' } = options;\n\n const asNodes = (nodes: readonly CascaderNode<T>[]): CascaderPathSegment<T>[] =>\n nodes.map((node) => ({ type: 'node' as const, node }));\n\n if (collapse === 'none' || maxSegments <= 0 || path.length <= maxSegments) {\n return asNodes(path);\n }\n\n if (collapse === 'start') {\n const tail = path.slice(path.length - maxSegments);\n return [{ type: 'ellipsis', hidden: path.slice(0, path.length - maxSegments) }, ...asNodes(tail)];\n }\n\n // \"middle\": keep the root for orientation and as much of the tail as fits.\n const head = path.slice(0, 1);\n const tailCount = maxSegments - 1;\n const tail = path.slice(path.length - tailCount);\n const hidden = path.slice(1, path.length - tailCount);\n\n if (hidden.length === 0) return asNodes(path);\n\n return [...asNodes(head), { type: 'ellipsis', hidden }, ...asNodes(tail)];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Cascade selection */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Every LOADED node under `value`, root first. Reaching an unfetched descendant\n * would mean a network request per level of the subtree on every selection.\n */\nexport function collectCascaderSubtree<T>(index: CascaderIndex<T>, value: string): CascaderNode<T>[] {\n const root = index.byValue.get(value);\n if (!root) return [];\n\n const out: CascaderNode<T>[] = [];\n const seen = new Set<string>();\n const walk = (node: CascaderNode<T>) => {\n if (seen.has(node.value)) return;\n seen.add(node.value);\n out.push(node);\n const children = index.childrenOf.get(node.value);\n if (children) for (const child of children) walk(child);\n };\n walk(root);\n return out;\n}\n\n/**\n * Toggles `value` with its loaded subtree, then reconciles ancestors. One flat\n * array, no hidden \"checked\" state: a branch is in the selection exactly when\n * every selectable loaded child of it is, which keeps a row's checked state an\n * O(1) lookup. Nodes `isSelectable` rejects are skipped down AND ignored up,\n * the pressed node excepted.\n */\nexport function applyCascadeSelection<T>(\n index: CascaderIndex<T>,\n selected: readonly string[],\n value: string,\n select: boolean,\n isSelectable: (node: CascaderNode<T>) => boolean = () => true,\n): string[] {\n const next = new Set(selected);\n const subtree = collectCascaderSubtree(index, value);\n\n // An unknown value still toggles itself, so an early async selection lands.\n if (subtree.length === 0) {\n if (select) next.add(value);\n else next.delete(value);\n }\n\n for (const node of subtree) {\n // The pressed node is exempt: it was committed, so it is selectable.\n if (node.value !== value && !isSelectable(node)) continue;\n if (select) next.add(node.value);\n else next.delete(node.value);\n }\n\n // Bottom up: a parent can only answer once its children have.\n const seen = new Set<string>([value]);\n let cursor = index.parentOf.get(value) ?? null;\n while (cursor != null && !seen.has(cursor)) {\n seen.add(cursor);\n const parent = index.byValue.get(cursor);\n const children = index.childrenOf.get(cursor) ?? [];\n const selectable = children.filter((child) => isSelectable(child));\n const full =\n selectable.length > 0 &&\n selectable.every((child) => next.has(child.value)) &&\n // Never promote a node the consumer said may not be committed. Under\n // `selectable=\"leaf\"` no branch qualifies, hence the `cascade` warning.\n !!parent &&\n isSelectable(parent);\n if (full) next.add(cursor);\n else next.delete(cursor);\n cursor = index.parentOf.get(cursor) ?? null;\n }\n\n return Array.from(next);\n}\n\n/**\n * How many selected nodes each value has BELOW it, itself excluded. Walks UP\n * from each selection: a per-row subtree scan would be quadratic and re-paid.\n */\nexport function getCascaderSelectedDescendants<T>(\n index: CascaderIndex<T>,\n selected: readonly string[],\n): Map<string, number> {\n const counts = new Map<string, number>();\n\n for (const value of selected) {\n const seen = new Set<string>([value]);\n let cursor = index.parentOf.get(value) ?? null;\n while (cursor != null && !seen.has(cursor)) {\n seen.add(cursor);\n counts.set(cursor, (counts.get(cursor) ?? 0) + 1);\n cursor = index.parentOf.get(cursor) ?? null;\n }\n }\n\n return counts;\n}\n\n/** The PARTIALLY selected values, read off counts the caller already holds. */\nexport function getCascaderIndeterminateFrom(\n counts: ReadonlyMap<string, number>,\n selected: readonly string[],\n): Set<string> {\n const selectedSet = new Set(selected);\n const partial = new Set<string>();\n\n for (const [value, count] of counts) {\n if (count > 0 && !selectedSet.has(value)) partial.add(value);\n }\n\n return partial;\n}\n\n/** The one-call form; the root uses the two halves above and its own counts. */\nexport function getCascaderIndeterminate<T>(index: CascaderIndex<T>, selected: readonly string[]): Set<string> {\n return getCascaderIndeterminateFrom(getCascaderSelectedDescendants(index, selected), selected);\n}\n\n/** How `getCascaderCheckedValues` condenses a full-closure selection. */\nexport type CascaderCheckedStrategy = 'all' | 'parent' | 'child';\n\n/**\n * The cascade selection under a reporting strategy. DERIVED OUTPUT ONLY: the\n * STORED value stays the full closure, which keeps a checked state an O(1)\n * lookup. `\"all\"` is the closure; `\"parent\"` drops a value whose parent is\n * selected; `\"child\"` drops one with a selected child.\n */\nexport function getCascaderCheckedValues<T>(\n index: CascaderIndex<T>,\n selected: readonly string[],\n strategy: CascaderCheckedStrategy,\n): readonly string[] {\n if (strategy === 'all') return selected;\n\n const set = new Set(selected);\n if (strategy === 'parent') {\n return selected.filter((value) => {\n const parent = index.parentOf.get(value);\n return parent == null || !set.has(parent);\n });\n }\n\n return selected.filter((value) => {\n const children = index.childrenOf.get(value);\n if (!children?.length) return true;\n return !children.some((child) => set.has(child.value));\n });\n}\n\n/** Values in `nodes` whose label collides, so the chip must show its path. */\nexport function findAmbiguousCascaderLabels<T>(nodes: readonly CascaderNode<T>[]): Set<string> {\n const firstByLabel = new Map<string, string>();\n const ambiguous = new Set<string>();\n\n for (const node of nodes) {\n const first = firstByLabel.get(node.label);\n if (first === undefined) {\n firstByLabel.set(node.label, node.value);\n continue;\n }\n ambiguous.add(node.value);\n ambiguous.add(first);\n }\n\n return ambiguous;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Development only */\n/* -------------------------------------------------------------------------- */\n\n/** Warnings already emitted. Module scoped, or they repeat once per render. */\nconst CASCADER_WARNED = new Set<string>();\n\n/** Warns once per `key`, never in production, never by throwing. */\nexport function warnCascaderOnce(key: string, message: string): void {\n if (process.env.NODE_ENV === 'production') return;\n if (CASCADER_WARNED.has(key)) return;\n CASCADER_WARNED.add(key);\n console.warn(`[Cascader] ${message}`);\n}\n\n/** Empties the ledger. Tests only; a warning is meant to be seen once. */\nexport function resetCascaderWarnings(): void {\n CASCADER_WARNED.clear();\n}\n\n/** What a dev-time scan of the consumer's `items` found wrong with it. */\nexport interface CascaderDataIssues {\n /** Values appearing more than once. First wins, so a duplicate drops a row. */\n duplicates: string[];\n /** Values on a `getParent` cycle. Depth is clamped, so the tree reads wrong. */\n cycles: string[];\n}\n\n/** Dev-time scan, kept out of `buildCascaderIndex` so the build stays hot. */\nexport function findCascaderDataIssues<T>(\n items: readonly CascaderNode<T>[] | undefined,\n getParent?: (node: CascaderNode<T>) => string | null | undefined,\n): CascaderDataIssues {\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n const flat: CascaderNode<T>[] = [];\n\n const visit = (nodes: readonly CascaderNode<T>[] | undefined) => {\n for (const node of nodes ?? []) {\n // The build skips a nullish entry, and this runs BEFORE its warning.\n if (node == null) continue;\n if (seen.has(node.value)) duplicates.add(node.value);\n else seen.add(node.value);\n flat.push(node);\n // Flat mode walks them too: BOTH `children` and `getParent` is a bug.\n if (node.children?.length) visit(node.children);\n }\n };\n visit(items);\n\n const cycles: string[] = [];\n if (getParent) {\n const parentOf = new Map<string, string | null>();\n for (const node of flat) {\n if (parentOf.has(node.value)) continue;\n const raw = getParent(node);\n parentOf.set(node.value, raw != null && seen.has(raw) ? raw : null);\n }\n for (const node of flat) {\n const walked = new Set<string>([node.value]);\n let cursor = parentOf.get(node.value) ?? null;\n while (cursor != null) {\n if (walked.has(cursor)) {\n cycles.push(node.value);\n break;\n }\n walked.add(cursor);\n cursor = parentOf.get(cursor) ?? null;\n }\n }\n }\n\n return { duplicates: Array.from(duplicates), cycles };\n}\n","import * as React from 'react';\n\nimport { useCascaderState } from './cascader-context';\nimport { CASCADER_ROOT_KEY, isCascaderMoreNode } from './cascader-lib';\nimport type {\n CascaderIndex,\n CascaderLoadContext,\n CascaderLoadReason,\n CascaderLoadResult,\n CascaderLoadState,\n CascaderNode,\n CascaderSearchContext,\n} from './cascader-types';\n\n/**\n * Async data for the cascader. Loaded pages live in their own store and are\n * MERGED onto the index built from `items`, never folded into that build:\n * `items` changes identity on any parent re-render, and folding would discard\n * every level the user drilled into. Map membership is the load discriminator:\n * no `states` entry means never fetched, while an entry with no `loading`, no\n * `error` and no children means empty for real.\n */\n\n/* -------------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------------- */\n\n/** Fetches one level. `node` is `null` for the root level. */\nexport type CascaderGetChildren<T = unknown> = (\n node: CascaderNode<T> | null,\n context: CascaderLoadContext,\n) => CascaderNode<T>[] | CascaderLoadResult<T> | Promise<CascaderNode<T>[] | CascaderLoadResult<T>>;\n\n/** Server-side search, replacing the local index scan while the query is set. */\nexport type CascaderOnSearch<T = unknown> = (\n query: string,\n context: CascaderSearchContext,\n) => CascaderNode<T>[] | CascaderLoadResult<T> | Promise<CascaderNode<T>[] | CascaderLoadResult<T>>;\n\n/** Resolves a selected value to its ancestor chain, root first, node last. */\nexport type CascaderResolveValue<T = unknown> = (\n value: string,\n context: CascaderLoadContext,\n) => CascaderNode<T>[] | Promise<CascaderNode<T>[]>;\n\nexport interface CascaderLoaderStore<T = unknown> {\n /** Keyed by LEVEL: a parent's value, or `CASCADER_ROOT_KEY` for the root. */\n pages: Map<string, CascaderNode<T>[]>;\n states: Map<string, CascaderLoadState>;\n /** Keyed by node value: search hits and resolved selections, level-less. */\n detached: Map<string, CascaderNode<T>>;\n}\n\nexport interface UseCascaderLoaderOptions<T = unknown> {\n /** The index built from `items`, before any pages are merged in. */\n base: CascaderIndex<T>;\n getChildren?: CascaderGetChildren<T>;\n onSearch?: CascaderOnSearch<T>;\n resolveValue?: CascaderResolveValue<T>;\n /** Milliseconds of quiet before `onSearch` fires. */\n searchDebounce?: number;\n /** Changing this drops every cached page, state and detached node. */\n loadKey?: unknown;\n /** Speculatively fetch a branch's children when it is highlighted. */\n prefetch?: boolean;\n /** Called when a request fails. Never for an aborted or superseded one. */\n onLoadError?: (error: unknown, context: { parent: string | null; reason: string }) => void;\n /** Whether the panel is live: the popup is open, or the cascader is inline. */\n enabled: boolean;\n query: string;\n /** Level keys that are currently on screen. Root is `CASCADER_ROOT_KEY`. */\n levels: string[];\n /** Handed to `onSearch` as its scope and read for nothing else: the\n * navigation path, or `[]` when the search covers the whole tree. */\n path: string[];\n /** Current selection, for `resolveValue`. */\n values: string[];\n}\n\nexport interface CascaderLoader<T = unknown> {\n /** Whether a `getChildren` loader is configured at all. */\n active: boolean;\n store: CascaderLoaderStore<T>;\n states: ReadonlyMap<string, CascaderLoadState>;\n /**\n * Async search hits, `null` when no `onSearch` is running. EMPTY while the\n * first request is in flight, so the level behind is not shown as the answer.\n */\n searchResults: CascaderNode<T>[] | null;\n searchState: CascaderLoadState | null;\n /**\n * Fetches a level's FIRST page. No-ops on a `states` entry (in flight,\n * loaded or failed) or when `items` fills the level; pages are never\n * consulted, so a `resolveValue` chain still fetches. The level effect fires\n * only for on-screen levels, so a branch merely PRESSED is asked for by hand.\n */\n ensureLevel: (parentKey: string, reason: CascaderLoadReason) => void;\n /** Fetches the next page of a level. No-ops unless one is available. */\n loadMore: (parentKey: string) => void;\n /** Refires a failed level. No-ops unless that level is in an error state. */\n retryLevel: (parentKey: string) => void;\n /** Schedules a speculative fetch. Safe to call on every highlight move. */\n prefetchNode: (node: CascaderNode<T> | null | undefined) => void;\n /**\n * Evicts ONE level: aborts its request, drops its `states`/`pages` entries\n * and paging latch, so the level effect refetches it. `null` = root level.\n */\n invalidateLevel: (value: string | null) => void;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Constants */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Highlight dwell before `prefetch` fetches: long enough that holding ArrowDown\n * does not fire a request per row, short enough to beat the ArrowRight press.\n */\nconst PREFETCH_DELAY = 150;\n\n/** Request keys for the two non-level requests. Never collide with a value. */\nconst SEARCH_KEY = '\\u0000search';\nconst RESOLVE_PREFIX = '\\u0000resolve:';\n\nconst NO_STATE: CascaderLoadState = {\n loading: false,\n error: false,\n hasMore: false,\n};\n\n/** Stable empty result, so an idle search never churns the state context. */\nconst NO_RESULTS: CascaderNode<never>[] = [];\n\nfunction createStore<T>(): CascaderLoaderStore<T> {\n return { pages: new Map(), states: new Map(), detached: new Map() };\n}\n\nfunction sameLoadState(a: CascaderLoadState, b: CascaderLoadState): boolean {\n return a.loading === b.loading && a.error === b.error && a.hasMore === b.hasMore && a.cursor === b.cursor;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Store transitions */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Copy-on-write, and a NO-OP when nothing changed: the merged index is memoised\n * on store identity, so a fresh object for an unchanged state would rebuild it.\n */\nfunction withLoadState<T>(\n store: CascaderLoaderStore<T>,\n key: string,\n update: (state: CascaderLoadState) => CascaderLoadState,\n): CascaderLoaderStore<T> {\n const current = store.states.get(key) ?? NO_STATE;\n const next = update(current);\n if (store.states.has(key) && sameLoadState(current, next)) return store;\n const states = new Map(store.states);\n states.set(key, next);\n return { pages: store.pages, states, detached: store.detached };\n}\n\nfunction withPage<T>(\n store: CascaderLoaderStore<T>,\n key: string,\n items: readonly CascaderNode<T>[],\n options: { append: boolean; hasMore: boolean; cursor?: string },\n): CascaderLoaderStore<T> {\n // A fresh level REPLACES its page so a `resolveValue` stub can be superseded.\n const previous = options.append ? (store.pages.get(key) ?? []) : [];\n const seen = new Set(previous.map((node) => node.value));\n const merged = previous.slice();\n for (const item of items) {\n if (seen.has(item.value)) continue;\n seen.add(item.value);\n merged.push(item);\n }\n\n const pages = new Map(store.pages);\n pages.set(key, merged);\n const states = new Map(store.states);\n states.set(key, {\n loading: false,\n error: false,\n hasMore: options.hasMore,\n cursor: options.cursor,\n });\n return { pages, states, detached: store.detached };\n}\n\nfunction withDetached<T>(store: CascaderLoaderStore<T>, items: readonly CascaderNode<T>[]): CascaderLoaderStore<T> {\n let detached: Map<string, CascaderNode<T>> | null = null;\n for (const item of items) {\n if (store.detached.get(item.value) === item) continue;\n detached = detached ?? new Map(store.detached);\n detached.set(item.value, item);\n }\n if (!detached) return store;\n return { pages: store.pages, states: store.states, detached };\n}\n\n/**\n * Places a resolved ancestor chain into `pages`, root first. Writes no\n * `states`, so those levels still read as unloaded and a drill-in still fetches\n * for real. Mirrored into `detached` so the trigger keeps its label.\n */\nfunction withChain<T>(store: CascaderLoaderStore<T>, chain: readonly CascaderNode<T>[]): CascaderLoaderStore<T> {\n if (chain.length === 0) return store;\n const pages = new Map(store.pages);\n const detached = new Map(store.detached);\n let parentKey = CASCADER_ROOT_KEY;\n\n for (const node of chain) {\n const bucket = pages.get(parentKey);\n if (!bucket) {\n pages.set(parentKey, [node]);\n } else if (!bucket.some((entry) => entry.value === node.value)) {\n pages.set(parentKey, [...bucket, node]);\n }\n detached.set(node.value, node);\n parentKey = node.value;\n }\n\n return { pages, states: store.states, detached };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Hook */\n/* -------------------------------------------------------------------------- */\n\ninterface CascaderLoaderLatest<T> {\n base: CascaderIndex<T>;\n store: CascaderLoaderStore<T>;\n getChildren?: CascaderGetChildren<T>;\n onSearch?: CascaderOnSearch<T>;\n resolveValue?: CascaderResolveValue<T>;\n onLoadError?: (error: unknown, context: { parent: string | null; reason: string }) => void;\n prefetch: boolean;\n path: string[];\n}\n\ninterface CascaderSearchSlice<T> {\n query: string;\n results: CascaderNode<T>[];\n loading: boolean;\n error: boolean;\n}\n\n/**\n * The loader. A SIBLING of the `buildCascaderIndex` memo, never inside it: the\n * build stays pure in `items`, the merge pure in that build plus this store.\n */\nexport function useCascaderLoader<T = unknown>({\n base,\n getChildren,\n onSearch,\n resolveValue,\n searchDebounce = 250,\n loadKey,\n prefetch = false,\n onLoadError,\n enabled,\n query,\n levels,\n path,\n values,\n}: UseCascaderLoaderOptions<T>): CascaderLoader<T> {\n const [store, setStore] = React.useState<CascaderLoaderStore<T>>(createStore);\n const [search, setSearch] = React.useState<CascaderSearchSlice<T> | null>(null);\n\n /**\n * Latest callbacks, WRITTEN IN AN EFFECT: `getChildren` is inline in most\n * consumers, so closing over it would refire every in-flight request per\n * re-render. The ref is what keeps the request machinery `[]`-dep. Declared\n * FIRST, since effects run in declaration order, so the level effect below\n * already sees the current commit.\n */\n const latest = React.useRef<CascaderLoaderLatest<T>>({\n base,\n store,\n getChildren,\n onSearch,\n resolveValue,\n onLoadError,\n prefetch,\n path,\n });\n\n React.useEffect(() => {\n latest.current = {\n base,\n store,\n getChildren,\n onSearch,\n resolveValue,\n onLoadError,\n prefetch,\n path,\n };\n });\n\n /** One AbortController PER KEY: columns mode runs several levels at once. */\n const controllers = React.useRef(new Map<string, AbortController>());\n /** Monotonic per key. The stale guard for out-of-order responses. */\n const requestIds = React.useRef(new Map<string, number>());\n /** In-flight `(level, cursor)` signatures, so a duplicate ask is free. */\n const inflight = React.useRef(new Map<string, string>());\n /**\n * The `(child count, cursor)` signature at the last paging fire, per level.\n * Guards what `hasMore` cannot: a page of zero new items while the server\n * still says `hasMore`. Cursor is IN the signature because an all-duplicates\n * page advances it while the count stands still - real progress, which a\n * count-only latch would brick forever.\n */\n const moreLatch = React.useRef(new Map<string, string>());\n /** Values `resolveValue` has already been asked about, so it asks once. */\n const attempted = React.useRef(new Set<string>());\n /** Every node the loader has seen, so a level key can name its own node. */\n const known = React.useRef(new Map<string, CascaderNode<T>>());\n const timers = React.useRef<{\n prefetch: ReturnType<typeof setTimeout> | null;\n }>({ prefetch: null });\n /** Bumped by a `loadKey` change, so responses from before it are dropped. */\n const epoch = React.useRef(0);\n\n const remember = React.useCallback((nodes: readonly CascaderNode<T>[]) => {\n const map = known.current;\n const walk = (list: readonly CascaderNode<T>[]) => {\n for (const node of list) {\n map.set(node.value, node);\n if (node.children?.length) walk(node.children);\n }\n };\n walk(nodes);\n }, []);\n\n const abortKey = React.useCallback((key: string) => {\n const controller = controllers.current.get(key);\n if (!controller) return;\n controllers.current.delete(key);\n inflight.current.delete(key);\n controller.abort();\n }, []);\n\n /* ------------------------------- level load ------------------------------ */\n\n const runLoad = React.useCallback(\n (key: string, reason: CascaderLoadReason, cursor: string | undefined, append: boolean) => {\n const { getChildren: loader, base: currentBase } = latest.current;\n if (!loader) return;\n\n const signature = `${append ? '1' : '0'}:${cursor ?? ''}`;\n if (inflight.current.get(key) === signature) return;\n\n abortKey(key);\n const controller = new AbortController();\n controllers.current.set(key, controller);\n inflight.current.set(key, signature);\n\n const requestId = (requestIds.current.get(key) ?? 0) + 1;\n requestIds.current.set(key, requestId);\n const startEpoch = epoch.current;\n\n const node = key === CASCADER_ROOT_KEY ? null : (currentBase.byValue.get(key) ?? known.current.get(key) ?? null);\n\n setStore((prev) =>\n withLoadState(prev, key, (state) => ({\n ...state,\n loading: true,\n error: false,\n })),\n );\n\n const settle = () => {\n if (inflight.current.get(key) === signature) inflight.current.delete(key);\n if (controllers.current.get(key) === controller) {\n controllers.current.delete(key);\n }\n };\n\n const stale = () =>\n controller.signal.aborted || startEpoch !== epoch.current || requestId !== requestIds.current.get(key);\n\n // `Promise.resolve().then(...)`, not a direct call: it normalises a\n // SYNCHRONOUS throw into a rejection instead of taking the render down.\n Promise.resolve()\n .then(() => loader(node, { signal: controller.signal, cursor, reason }))\n .then((result) => {\n settle();\n if (stale()) return;\n const items = Array.isArray(result) ? result : result.items;\n const nextCursor = Array.isArray(result) ? undefined : result.nextCursor;\n const hasMore = Array.isArray(result) ? false : (result.hasMore ?? nextCursor != null);\n\n if (!append) moreLatch.current.delete(key);\n remember(items);\n setStore((prev) => withPage(prev, key, items, { append, hasMore, cursor: nextCursor }));\n })\n .catch((error: unknown) => {\n settle();\n if (stale()) return;\n setStore((prev) =>\n withLoadState(prev, key, (state) => ({\n ...state,\n loading: false,\n error: true,\n })),\n );\n // Behind the stale guard: an abort is navigation, not a failure.\n latest.current.onLoadError?.(error, {\n parent: key === CASCADER_ROOT_KEY ? null : key,\n reason,\n });\n });\n },\n [abortKey, remember],\n );\n\n const ensureLevel = React.useCallback(\n (key: string, reason: CascaderLoadReason) => {\n const { getChildren: loader, store: current, base: index } = latest.current;\n if (!loader) return;\n if (current.states.has(key)) return;\n // A level `items` already fills is not the loader's business: that is how\n // a static root plus `getChildren` for the branches works with no flag.\n if (index.childrenOf.has(key)) return;\n runLoad(key, reason, undefined, false);\n },\n [runLoad],\n );\n\n const loadMore = React.useCallback(\n (key: string) => {\n const { getChildren: loader, store: current } = latest.current;\n if (!loader) return;\n const state = current.states.get(key);\n if (!state || state.loading || !state.hasMore) return;\n\n const loaded = current.pages.get(key)?.length ?? 0;\n const signature = `${loaded}:${state.cursor ?? ''}`;\n if (moreLatch.current.get(key) === signature) return;\n moreLatch.current.set(key, signature);\n\n runLoad(key, 'more', state.cursor, true);\n },\n [runLoad],\n );\n\n const retryLevel = React.useCallback(\n (key: string) => {\n const { getChildren: loader, store: current } = latest.current;\n if (!loader) return;\n const state = current.states.get(key);\n if (!state?.error) return;\n\n const loaded = current.pages.get(key)?.length ?? 0;\n // A retry must be able to re-fire the page the latch just blocked.\n moreLatch.current.delete(key);\n runLoad(key, 'retry', loaded > 0 ? state.cursor : undefined, loaded > 0);\n },\n [runLoad],\n );\n\n /**\n * `detached` is deliberately untouched: chains and search hits belong to no\n * level, and the trigger needs their labels while the new page is in flight.\n */\n const invalidateLevel = React.useCallback(\n (value: string | null) => {\n const key = value ?? CASCADER_ROOT_KEY;\n abortKey(key);\n // Bump the id too: a response past its signal check must still be stale.\n requestIds.current.set(key, (requestIds.current.get(key) ?? 0) + 1);\n moreLatch.current.delete(key);\n setStore((prev) => {\n if (!prev.states.has(key) && !prev.pages.has(key)) return prev;\n const states = new Map(prev.states);\n states.delete(key);\n const pages = new Map(prev.pages);\n pages.delete(key);\n return { pages, states, detached: prev.detached };\n });\n },\n [abortKey],\n );\n\n const prefetchNode = React.useCallback(\n (node: CascaderNode<T> | null | undefined) => {\n const { prefetch: on, getChildren: loader, store: current } = latest.current;\n if (!on || !loader || !node) return;\n if (isCascaderMoreNode(node)) return;\n if (!node.hasChildren) return;\n if (current.states.has(node.value)) return;\n\n const holder = timers.current;\n if (holder.prefetch) clearTimeout(holder.prefetch);\n // A TIMEOUT, not a direct call: `onItemHighlighted` fires from a layout\n // effect, where a synchronous setState is a render-phase cascade.\n holder.prefetch = setTimeout(() => {\n holder.prefetch = null;\n ensureLevel(node.value, 'prefetch');\n }, PREFETCH_DELAY);\n },\n [ensureLevel],\n );\n\n /* --------------------------------- search -------------------------------- */\n\n const runSearch = React.useCallback(\n (text: string) => {\n const { onSearch: searcher, path: currentPath } = latest.current;\n if (!searcher) return;\n\n abortKey(SEARCH_KEY);\n const controller = new AbortController();\n controllers.current.set(SEARCH_KEY, controller);\n const requestId = (requestIds.current.get(SEARCH_KEY) ?? 0) + 1;\n requestIds.current.set(SEARCH_KEY, requestId);\n const startEpoch = epoch.current;\n\n setSearch((prev) => ({\n query: text,\n results: prev?.results ?? [],\n loading: true,\n error: false,\n }));\n\n const settle = () => {\n if (controllers.current.get(SEARCH_KEY) === controller) {\n controllers.current.delete(SEARCH_KEY);\n }\n };\n const stale = () =>\n controller.signal.aborted || startEpoch !== epoch.current || requestId !== requestIds.current.get(SEARCH_KEY);\n\n Promise.resolve()\n .then(() => searcher(text, { signal: controller.signal, path: currentPath }))\n .then((result) => {\n settle();\n if (stale()) return;\n const items = Array.isArray(result) ? result : result.items;\n remember(items);\n // Search hits go to `detached`, never a level: a hit lives anywhere in\n // the tree, and filing it under the open level would misplace it.\n setStore((prev) => withDetached(prev, items));\n setSearch({\n query: text,\n results: items,\n loading: false,\n error: false,\n });\n })\n .catch((error: unknown) => {\n settle();\n if (stale()) return;\n setSearch((prev) => ({\n query: text,\n results: prev?.results ?? [],\n loading: false,\n error: true,\n }));\n latest.current.onLoadError?.(error, {\n parent: null,\n reason: 'search',\n });\n });\n },\n [abortKey, remember],\n );\n\n /* --------------------------------- resolve ------------------------------- */\n\n const runResolve = React.useCallback(\n (value: string) => {\n const { resolveValue: resolver } = latest.current;\n if (!resolver) return;\n\n const key = `${RESOLVE_PREFIX}${value}`;\n abortKey(key);\n const controller = new AbortController();\n controllers.current.set(key, controller);\n const startEpoch = epoch.current;\n\n const settle = () => {\n if (controllers.current.get(key) === controller) {\n controllers.current.delete(key);\n }\n };\n\n Promise.resolve()\n .then(() => resolver(value, { signal: controller.signal, reason: 'resolve' }))\n .then((chain) => {\n settle();\n if (controller.signal.aborted || startEpoch !== epoch.current) return;\n if (!chain?.length) return;\n remember(chain);\n setStore((prev) => withChain(prev, chain));\n })\n .catch((error: unknown) => {\n settle();\n // Un-attempt on failure: `attempted` is written BEFORE the call, so\n // without this a resolver that failed once could never be retried.\n attempted.current.delete(value);\n if (controller.signal.aborted || startEpoch !== epoch.current) return;\n latest.current.onLoadError?.(error, {\n parent: null,\n reason: 'resolve',\n });\n });\n },\n [abortKey, remember],\n );\n\n /* --------------------------------- resets -------------------------------- */\n\n const cancelAll = React.useCallback(() => {\n const keys = Array.from(controllers.current.keys());\n for (const controller of controllers.current.values()) controller.abort();\n controllers.current.clear();\n inflight.current.clear();\n\n const holder = timers.current;\n if (holder.prefetch) {\n clearTimeout(holder.prefetch);\n holder.prefetch = null;\n }\n if (keys.length === 0) return;\n\n setStore((prev) => {\n let states: Map<string, CascaderLoadState> | null = null;\n for (const key of keys) {\n const state = prev.states.get(key);\n if (!state?.loading) continue;\n states = states ?? new Map(prev.states);\n if ((prev.pages.get(key)?.length ?? 0) > 0) {\n states.set(key, { ...state, loading: false });\n } else {\n // No entry AT ALL: membership is what says \"loaded\", so a stranded\n // `loading: true` would read as loaded-and-empty forever.\n states.delete(key);\n }\n }\n return states ? { ...prev, states } : prev;\n });\n setSearch((prev) => (prev?.loading ? { ...prev, loading: false } : prev));\n }, []);\n\n // A `loadKey` change drops everything. Declared BEFORE the level effect, so\n // a reset always lands before the levels are asked for again.\n const loadKeyRef = React.useRef<{ key: unknown } | null>(null);\n React.useEffect(() => {\n const previous = loadKeyRef.current;\n loadKeyRef.current = { key: loadKey };\n if (!previous || Object.is(previous.key, loadKey)) return;\n\n epoch.current += 1;\n for (const controller of controllers.current.values()) controller.abort();\n controllers.current.clear();\n inflight.current.clear();\n // `requestIds` is deliberately NOT cleared: the ids are stale-response\n // guards, not cache. Reusing an aborted predecessor's id would leave only\n // the epoch bump and the abort to reject the old response; monotonic per\n // key keeps all three guards independent. The unmount cleanup clears them.\n moreLatch.current.clear();\n attempted.current.clear();\n known.current.clear();\n\n const holder = timers.current;\n if (holder.prefetch) {\n clearTimeout(holder.prefetch);\n holder.prefetch = null;\n }\n\n setStore(createStore);\n setSearch(null);\n }, [loadKey]);\n\n // Closing the popup aborts every request but does NOT drop the cache:\n // reopening onto an already-loaded level is the point of keeping it.\n React.useEffect(() => {\n if (enabled) return;\n if (controllers.current.size === 0) return;\n cancelAll();\n }, [enabled, cancelAll]);\n\n React.useEffect(() => {\n const active = controllers.current;\n const holder = timers.current;\n const pending = inflight.current;\n const ids = requestIds.current;\n return () => {\n for (const controller of active.values()) controller.abort();\n active.clear();\n // Cleared WITH the controllers, for StrictMode's dev remount: a stale\n // inflight signature would make `runLoad` skip the refetch forever. The\n // aborted promises are stale-guarded, so emptying the ids is safe.\n pending.clear();\n ids.clear();\n if (holder.prefetch) clearTimeout(holder.prefetch);\n };\n }, []);\n\n /* ------------------------------- the effects ----------------------------- */\n\n const hasLoader = typeof getChildren === 'function';\n const hasSearch = typeof onSearch === 'function';\n const hasResolve = typeof resolveValue === 'function';\n const trimmed = query.trim();\n\n // Serialised so the effects key on CONTENT, not on the array identity.\n const levelsKey = JSON.stringify(levels);\n const valuesKey = JSON.stringify(values);\n\n // THE load trigger: one declarative effect on the levels on screen, not a\n // call from `pushLevel`/`navigate`, which a controlled `path` never touches.\n React.useEffect(() => {\n if (!enabled || !hasLoader) return;\n for (const key of levels) ensureLevel(key, 'level');\n // `levels` enters through `levelsKey`; `store` re-runs after a load lands.\n }, [enabled, hasLoader, levelsKey, store, ensureLevel]);\n\n React.useEffect(() => {\n if (!hasSearch) return undefined;\n if (!enabled || !trimmed) {\n abortKey(SEARCH_KEY);\n setSearch((prev) => (prev === null ? prev : null));\n return undefined;\n }\n const timer = setTimeout(() => runSearch(trimmed), searchDebounce);\n return () => {\n clearTimeout(timer);\n abortKey(SEARCH_KEY);\n };\n }, [hasSearch, enabled, trimmed, searchDebounce, abortKey, runSearch]);\n\n React.useEffect(() => {\n if (!enabled || !hasResolve) return;\n for (const value of values) {\n if (!value) continue;\n if (attempted.current.has(value)) continue;\n if (base.byValue.has(value) || known.current.has(value)) continue;\n attempted.current.add(value);\n runResolve(value);\n }\n // `values` is depended on through `valuesKey`.\n }, [enabled, hasResolve, valuesKey, base, runResolve]);\n\n /* -------------------------------- the value ------------------------------ */\n\n const searchResults = React.useMemo(() => {\n if (!hasSearch || !trimmed) return null;\n if (!search || search.query !== trimmed) {\n return NO_RESULTS as CascaderNode<T>[];\n }\n return search.results;\n }, [hasSearch, trimmed, search]);\n\n const searchState = React.useMemo<CascaderLoadState | null>(() => {\n if (!hasSearch || !trimmed) return null;\n const settled = search?.query === trimmed;\n return {\n loading: !settled || !!search?.loading,\n error: settled && !!search?.error,\n hasMore: false,\n };\n }, [hasSearch, trimmed, search]);\n\n return React.useMemo(\n () => ({\n active: hasLoader,\n store,\n states: store.states,\n searchResults,\n searchState,\n ensureLevel,\n loadMore,\n retryLevel,\n invalidateLevel,\n prefetchNode,\n }),\n [hasLoader, store, searchResults, searchState, ensureLevel, loadMore, retryLevel, invalidateLevel, prefetchNode],\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Consumers */\n/* -------------------------------------------------------------------------- */\n\n/** One level's load state, `null` when never fetched. Omit for the root. */\nexport function useCascaderLoadState(parent?: string | null): CascaderLoadState | null {\n const { loadStates } = useCascaderState();\n return loadStates.get(parent ?? CASCADER_ROOT_KEY) ?? null;\n}\n","import type { CascaderLabels, CascaderMode } from './cascader-types';\n\n/** Name of the root level. Hoisted so the root announcement can reuse it. */\nconst ROOT_LEVEL = 'Top level';\n\n/** Hoisted for the same reason: several defaults end in an item count. */\nconst itemCount = (count: number) => `${count} ${count === 1 ? 'item' : 'items'}`;\n\n/**\n * English defaults. Every string the primitive can render lives here, so a\n * consumer can translate the whole surface by passing `labels`.\n */\nexport const CASCADER_LABELS: CascaderLabels = {\n // Deliberately NOT lowercased. `toLowerCase()` is locale-hostile - it maps\n // Turkish \"İ\" to a two-code-point sequence and German \"İstanbul\" style\n // proper nouns lose their casing - and a label is already written the way\n // its author wants it read.\n search: (parentLabel) => (parentLabel ? `Search ${parentLabel}...` : 'Search...'),\n back: 'Back',\n loading: 'Loading...',\n loadingMore: 'Loading more...',\n loadMore: 'Load more',\n error: 'Could not load items.',\n retry: 'Retry',\n empty: 'No results found.',\n selectedCount: (count) => `${count} selected`,\n breadcrumbLabel: 'Breadcrumb',\n chipsLabel: 'Selected items',\n removeChip: (label) => `Remove ${label}`,\n pathSeparator: '/',\n rootLevel: ROOT_LEVEL,\n itemCount,\n branchAffordance: 'submenu',\n selectedState: 'selected',\n partiallySelectedState: 'partially selected',\n columnsLabel: 'Levels',\n actionsLabel: 'Actions',\n submenuAffordance: 'opens a menu',\n panelLabel: 'Options',\n keyboardHint: (mode: CascaderMode, dir: 'ltr' | 'rtl') => {\n // \"Deeper\" is the direction the text runs, so the level keys mirror in\n // RTL and the hint has to name the mirrored pair there - an LTR-worded\n // hint would teach exactly the wrong keys.\n const open = dir === 'rtl' ? 'Left' : 'Right';\n const back = dir === 'rtl' ? 'Right' : 'Left';\n if (mode === 'tree') {\n return `Use the ${open} Arrow key to expand and the ${back} Arrow key to collapse.`;\n }\n if (mode === 'columns') {\n return `Use the ${open} Arrow key to open the next column and the ${back} Arrow key to go back.`;\n }\n return `Use the ${open} Arrow key to open a branch and the ${back} Arrow key to go back.`;\n },\n rootAnnouncement: (count) => `${ROOT_LEVEL}, ${itemCount(count)}`,\n expandedAnnouncement: (label, count) => `${label} expanded, ${itemCount(count)}`,\n collapsedAnnouncement: (label) => `${label} collapsed`,\n levelAnnouncement: (parentLabel, depth, count) => `${parentLabel}, level ${depth}, ${itemCount(count)}`,\n resultsAnnouncement: (count) => (count === 1 ? '1 result' : `${count} results`),\n maxReachedAnnouncement: (max) => `Selection limit of ${max} reached`,\n cascadeAnnouncement: (label, count, selecting) =>\n `${label} ${selecting ? 'selected' : 'deselected'}, ${itemCount(count)} followed`,\n searchingAnnouncement: 'Searching...',\n};\n\n/**\n * Shallow-merges consumer overrides over the defaults, so `labels` can carry a\n * single key without restating the rest.\n */\nexport function resolveCascaderLabels(labels?: Partial<CascaderLabels>): CascaderLabels {\n if (!labels) return CASCADER_LABELS;\n return { ...CASCADER_LABELS, ...labels };\n}\n\n/** Resolves the search placeholder, which may be a string or a function. */\nexport function resolveCascaderSearchLabel(labels: CascaderLabels, parentLabel?: string): string {\n return typeof labels.search === 'function' ? labels.search(parentLabel) : labels.search;\n}\n","import {\n CheckIcon,\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n LoaderCircleIcon,\n MinusIcon,\n RotateCwIcon,\n XIcon,\n} from 'lucide-react';\nimport type { ComponentProps } from 'react';\n\n/**\n * 上游 reui create-app 的 IconPlaceholder 垫片:按 lucide prop 名取图标,\n * 保存 vendored 调用点零改动(移植裁剪的接缝件)。\n */\nconst ICONS = {\n CheckIcon,\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n LoaderCircleIcon,\n MinusIcon,\n RotateCwIcon,\n XIcon,\n} as const;\n\nexport function IconPlaceholder({\n lucide,\n // 上游调用点携带全图标集名字(tabler/hugeicons/phosphor/remixicon)——吞掉\n\n tabler: _tabler,\n hugeicons: _hugeicons,\n phosphor: _phosphor,\n remixicon: _remixicon,\n ...props\n}: {\n lucide: keyof typeof ICONS;\n} & Record<string, unknown> &\n Omit<ComponentProps<(typeof ICONS)['ChevronRightIcon']>, 'ref'>) {\n const Icon = ICONS[lucide] ?? ChevronRightIcon;\n return <Icon {...(props as ComponentProps<typeof ChevronRightIcon>)} />;\n}\n","import { cn } from '#lib/utils';\nimport { ScrollArea } from '#reui/scroll-area';\nimport { Combobox as ComboboxPrimitive } from '@base-ui/react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport * as React from 'react';\n\nimport { useCascaderLoadState, useCascaderLoader } from './cascader-async';\nimport type { CascaderGetChildren, CascaderOnSearch, CascaderResolveValue } from './cascader-async';\nimport {\n CascaderActionsContext,\n CascaderHighlightContext,\n CascaderRenderContext,\n CascaderStateContext,\n createCascaderHighlightStore,\n useCascaderActions,\n useCascaderHighlight,\n useCascaderRender,\n useCascaderState,\n} from './cascader-context';\nimport type {\n CascaderActionsContextValue,\n CascaderColumn,\n CascaderHighlight,\n CascaderHighlightStore,\n CascaderItemState,\n CascaderRenderContextValue,\n CascaderStateContextValue,\n} from './cascader-context';\nimport { resolveCascaderLabels } from './cascader-i18n';\nimport {\n CASCADER_LIST_HEIGHT_CLASS,\n CASCADER_LIST_PAD_CLASS,\n CASCADER_ROOT_KEY,\n CASCADER_ROWS_CLASS,\n CASCADER_SCROLL_CLASS,\n applyCascadeSelection,\n buildCascaderIndex,\n collapseCascaderPath,\n createCascaderMoreNode,\n filterCascaderLevel,\n findAmbiguousCascaderLabels,\n findCascaderDataIssues,\n flattenCascaderTree,\n getCascaderCheckedValues,\n getCascaderChildren,\n getCascaderCount,\n getCascaderIndeterminateFrom,\n getCascaderPath,\n getCascaderSelectedDescendants,\n getCascaderTabTarget,\n isCascaderBranch,\n isCascaderDisabled,\n isCascaderMoreNode,\n isCascaderSelectable,\n matchesCascaderQuery,\n mergeCascaderIndex,\n normalizeCascaderQuery,\n searchCascaderDeep,\n warnCascaderOnce,\n} from './cascader-lib';\nimport type { CascaderCheckedStrategy } from './cascader-lib';\nimport type {\n CascaderActionItem,\n CascaderChangeDetails,\n CascaderChangeReason,\n CascaderFlatNode,\n CascaderIndex,\n CascaderLabels,\n CascaderLoadState,\n CascaderMode,\n CascaderNode,\n CascaderSearchScope,\n CascaderSelectable,\n} from './cascader-types';\nimport { IconPlaceholder } from './icon-placeholder';\n\n/** Stable `filteredItems` for a level swap; a fixed identity cannot loop. */\nconst EMPTY: CascaderNode<never>[] = [];\n\n/** Stable empty array for the `actions` prop, so a cascader with no footer\n * does not republish the actions context on every render. */\nconst EMPTY_ACTIONS: CascaderActionItem[] = [];\n\n/** The `onSearch` scope of a global search: no path, so the whole tree. */\nconst GLOBAL_SEARCH_PATH: string[] = [];\n\n// Word joiner. A polite region reads only MUTATIONS, so alternate it.\nconst ANNOUNCE_MARKER = '\\u2060';\n\n// Delay before a query result-count reaches the live region: polite\n// announcements queue, and re-announcing per keystroke plays back stale\n// counts. Only the count defers; every event-shaped one stays immediate.\nconst ANNOUNCE_DEBOUNCE = 150;\n\n/* -------------------------------------------------------------------------- */\n/* State */\n/* -------------------------------------------------------------------------- */\n\n// Minimal controlled/uncontrolled resolver, hand-rolled because the repo has\n// no shared `useControllableState`; the root needs it five times.\nfunction useControllable<V>(\n controlled: V | undefined,\n defaultValue: V,\n onChange?: (value: V) => void,\n /** Prop name, used only by the development-time switching warning. */\n devName?: string,\n): [V, (next: V | ((prev: V) => V)) => void] {\n const [uncontrolled, setUncontrolled] = React.useState(defaultValue);\n const isControlled = controlled !== undefined;\n const value = isControlled ? controlled : uncontrolled;\n\n // Switching controlled/uncontrolled mid-life strands half the state.\n const wasControlled = React.useRef(isControlled);\n React.useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n if (wasControlled.current === isControlled || !devName) return;\n const from = wasControlled.current ? 'controlled' : 'uncontrolled';\n const to = isControlled ? 'controlled' : 'uncontrolled';\n wasControlled.current = isControlled;\n warnCascaderOnce(\n `controlled-switch:${devName}`,\n `\\`${devName}\\` switched from ${from} to ${to}. Decide once: pass \\`${devName}\\` for the whole life of the component, or pass only the default and let the cascader own it.`,\n );\n }, [isControlled, devName]);\n\n // Written in an EFFECT: a discarded render would still have mutated a ref.\n const latest = React.useRef({ value, isControlled, onChange });\n React.useEffect(() => {\n latest.current = { value, isControlled, onChange };\n });\n\n // The last PROP seen: it differs from the optimistic advance exactly when a\n // controlled parent declines a change and re-renders nothing.\n const lastProp = React.useRef(controlled);\n React.useEffect(() => {\n lastProp.current = controlled;\n });\n\n const set = React.useCallback((next: V | ((prev: V) => V)) => {\n const current = latest.current.value;\n const resolved = typeof next === 'function' ? (next as (prev: V) => V)(current) : next;\n if (Object.is(resolved, current)) {\n // Dedup against the last PROP, not the optimistic advance: a parent that\n // declines re-renders nothing, so deduping on the advance left the popup\n // un-dismissable from the second Escape on.\n if (!latest.current.isControlled || Object.is(resolved, lastProp.current)) {\n return;\n }\n }\n\n // Advance now so two updates in ONE batch compose, rather than the second\n // reading a stale value and its `Object.is` dedup dropping it.\n latest.current = { ...latest.current, value: resolved };\n\n if (!latest.current.isControlled) setUncontrolled(resolved);\n latest.current.onChange?.(resolved);\n }, []);\n\n return [value, set];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Shallow stability */\n/* -------------------------------------------------------------------------- */\n\nfunction shallowEqualRecords(a: object, b: object): boolean {\n const left = a as Record<string, unknown>;\n const right = b as Record<string, unknown>;\n const keys = Object.keys(left);\n if (keys.length !== Object.keys(right).length) return false;\n for (const key of keys) {\n if (!Object.is(left[key], right[key])) return false;\n }\n return true;\n}\n\nfunction shallowEqualItemLists(a: readonly object[], b: readonly object[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i] && !shallowEqualRecords(a[i], b[i])) return false;\n }\n return true;\n}\n\n// Reuses the previous value while the next merely says the same thing: an\n// inline `labels`/`actions` otherwise republishes the actions context, and\n// with it every row. Adjust-state-during-render, not a ref.\nfunction useShallowStable<V>(value: V, equal: (a: V & object, b: V & object) => boolean): V {\n const [stable, setStable] = React.useState(value);\n if (Object.is(value, stable)) return stable;\n const comparable = typeof value === 'object' && value !== null && typeof stable === 'object' && stable !== null;\n if (comparable && equal(value as V & object, stable as V & object)) {\n return stable;\n }\n setStable(value);\n return value;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Context */\n/* -------------------------------------------------------------------------- */\n\n/** The pre-split shape, merged, so `useCascader()` returns what it always did. */\nexport interface CascaderContextValue<T = unknown>\n extends CascaderActionsContextValue<T>, CascaderStateContextValue<T> {}\n\n/**\n * The cascader's internals, typed for the caller's own item payload.\n * @deprecated Reads BOTH halves, so a caller re-renders on every keystroke.\n * Prefer `useCascaderActions()` or `useCascaderState()`. Kept for compat.\n */\nexport function useCascader<T = unknown>(): CascaderContextValue<T> {\n const actions = useCascaderActions<T>();\n const state = useCascaderState<T>();\n\n return React.useMemo(() => ({ ...actions, ...state }), [actions, state]);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Headless selection */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderSelection<T = unknown> {\n /** The selected nodes, resolved. Empty when nothing is selected. */\n selected: CascaderNode<T>[];\n /** Ancestor chain per selected node, root first, node last. */\n paths: CascaderNode<T>[][];\n /** The single selection, or the first one in `multiple` mode. */\n first: CascaderNode<T> | null;\n /** Ancestor chain of `first`. */\n firstPath: CascaderNode<T>[];\n count: number;\n isEmpty: boolean;\n multiple: boolean;\n remove: (value: string) => void;\n clear: () => void;\n}\n\n/** Headless access to the selection, for a trigger that is not\n * `CascaderValue`. Pass the payload explicitly to get `node.data` typed. */\nexport function useCascaderSelection<T = unknown>(): CascaderSelection<T> {\n const { multiple, setSelection } = useCascaderActions<T>();\n const { index, selectedValues } = useCascaderState<T>();\n\n return React.useMemo(() => {\n const selected = selectedValues.map((value) => index.byValue.get(value)).filter(Boolean) as CascaderNode<T>[];\n const paths = selectedValues.map((value) => getCascaderPath(index, value));\n\n return {\n selected,\n paths,\n first: selected[0] ?? null,\n firstPath: paths[0] ?? [],\n count: selectedValues.length,\n isEmpty: selectedValues.length === 0,\n multiple,\n remove: (value: string) => setSelection(selectedValues.filter((entry) => entry !== value)),\n // Explicit reason: emptying on purpose is not \"deselect the last node\".\n clear: () => setSelection([], 'clear'),\n };\n }, [index, selectedValues, multiple, setSelection]);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Root */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Why the navigation path changed.\n * - `\"drill\"`: a branch was entered (row press, level arrow, search hit).\n * - `\"back\"`: one level up (back control, Backspace on an empty query).\n * - `\"breadcrumb\"`: a jump to an exact depth in the trail.\n * - `\"reveal\"`: the reopen navigated to the level holding the selection.\n * - `\"external\"`: `setPath` called from outside the primitive's own flows.\n */\nexport type CascaderPathChangeReason = 'drill' | 'back' | 'breadcrumb' | 'reveal' | 'external';\n\n/** Everything independent of the selection mode; the rest is on the two arms. */\nexport interface CascaderBaseProps<T = unknown> {\n /** Nested tree, or a flat list when `getParent` is supplied. */\n items: CascaderNode<T>[];\n /** Opt in to flat adjacency input by returning each node's parent value. */\n getParent?: (node: CascaderNode<T>) => string | null | undefined;\n\n /**\n * Fetches one level on demand; `node` is `null` for the root. Return an\n * array, or a `CascaderLoadResult` when the level pages. Pages cache apart\n * from `items`; mark unfetched branches `hasChildren` or they read as leaves.\n */\n getChildren?: CascaderGetChildren<T>;\n /**\n * Server-side search, debounced by `searchDebounce`; replaces the local scan\n * while the query is set. Results are detached: resolvable by value, in no\n * level. Ignored in `mode=\"tree\"`, where a hit belongs to no visible branch.\n */\n onSearch?: CascaderOnSearch<T>;\n /** Milliseconds of quiet before `onSearch` fires. */\n searchDebounce?: number;\n /**\n * Resolves a value the loader has never seen into its ancestor chain, root\n * first, so the trigger can path a server-supplied selection. Does NOT mark\n * those levels loaded: opening one still fetches.\n */\n resolveValue?: CascaderResolveValue<T>;\n /** Cache key. Changing it drops every page and aborts anything in flight. */\n loadKey?: unknown;\n /** Prefetch a highlighted branch's children after a pause. Off by default. */\n prefetch?: boolean;\n /**\n * Called when a load fails. `context.parent` is the level (`null` for root);\n * `context.reason` is `\"level\"`, `\"more\"`, `\"retry\"`, `\"prefetch\"`,\n * `\"search\"` or `\"resolve\"`. Never for an aborted or superseded request.\n */\n onLoadError?: (error: unknown, context: { parent: string | null; reason: string }) => void;\n\n /** Which nodes may be committed. Defaults to leaves only. */\n selectable?: CascaderSelectable<T>;\n\n /**\n * Whether the built-in SINGLE-SELECT check is drawn. Defaults to true.\n * `false` also gives back the inline-end gutter every style reserves for it;\n * `data-selected` and `aria-selected` stay. A no-op under `multiple`, where\n * the checkbox is the selection CONTROL rather than a decoration.\n */\n indicator?: boolean;\n\n /**\n * Footer ACTIONS: commands pinned below the list, never rows in it, and never\n * touching the data tree. A childless `<CascaderFooter />` draws these; an\n * action with `items` opens a side-anchored flyout rather than firing.\n */\n actions?: CascaderActionItem[];\n\n /**\n * Parent/child cascading. Multi-select only, off by default, and it needs\n * committable branches (`selectable=\"any\"` or a predicate). A commit selects\n * or deselects every SELECTABLE node in the LOADED subtree and reconciles\n * ancestors. LOADED is the semantic, not a hedge: a commit must not fan out\n * into a request per level, so children arriving later arrive unchecked.\n */\n cascade?: boolean;\n\n mode?: CascaderMode;\n\n /** How a branch opens from the pointer in columns mode's ACTIVE column.\n * `\"click\"` is the default, and neither value ever commits a selection. */\n expandTrigger?: 'click' | 'hover';\n\n path?: string[];\n defaultPath?: string[];\n /** The second argument says WHY. An existing `(path) => void` still works. */\n onPathChange?: (path: string[], details: { reason: CascaderPathChangeReason }) => void;\n\n expanded?: string[];\n defaultExpanded?: string[];\n onExpandedChange?: (expanded: string[]) => void;\n\n open?: boolean;\n defaultOpen?: boolean;\n /** Forwards Base UI's reason; a leaf commit's close says `\"item-press\"`. */\n onOpenChange?: (open: boolean, details: { reason: string }) => void;\n\n /**\n * Whether a SINGLE-SELECT leaf commit closes the popup. Defaults to true.\n * `false` is for a compare-and-repick flow; Escape, outside press and the\n * trigger still close. Ignored under `multiple`, which never closes.\n */\n closeOnSelect?: boolean;\n\n inputValue?: string;\n defaultInputValue?: string;\n onInputValueChange?: (value: string) => void;\n\n /**\n * `\"level\"` (default) filters the level on screen, `\"deep\"` also searches\n * below it, `\"global\"` searches the whole tree from any level.\n */\n searchScope?: CascaderSearchScope;\n /** Custom matcher, replacing label + keywords substring matching. */\n filter?: (node: CascaderNode<T>, normalizedQuery: string) => boolean;\n\n /** On open, navigate to the level holding the selection. Default true. */\n revealSelected?: boolean;\n\n maxHeight?: number | string;\n\n /**\n * Window the rendered rows. `undefined` decides per level from\n * `virtualizeThreshold`; `true`/`false` force it. Also opt-in at the markup\n * level, so the base install pulls in no virtualization library.\n */\n virtualize?: boolean;\n /** Row count at which windowing turns itself on. */\n virtualizeThreshold?: number;\n /** Row height handed to the virtualizer before a row has been measured. */\n estimateRowSize?: number;\n /** Rows rendered beyond each edge of the viewport. */\n overscan?: number;\n\n labels?: Partial<CascaderLabels>;\n /** Replaces the entire row, affordances included. */\n renderItem?: (node: CascaderNode<T>, state: CascaderItemState<T>) => React.ReactNode;\n /** Replaces only the label block; icon, count, chevron and check stay. */\n renderLabel?: (node: CascaderNode<T>, state: CascaderItemState<T>) => React.ReactNode;\n\n disabled?: boolean;\n /** Native form field name. Submits the selected value(s). */\n name?: string;\n /** Id of the owning form, for a cascader rendered outside it. */\n form?: string;\n /** Id of the control. Pairs the field with a `<label htmlFor>`. */\n id?: string;\n /** Marks the field required for native form validation. */\n required?: boolean;\n /** The value can be read and submitted, but not changed. */\n readOnly?: boolean;\n /** Marks the field invalid: `aria-invalid` and `data-invalid` on the trigger,\n * the chips and the input, which every style's error treatment reads. */\n invalid?: boolean;\n /** Ref to the hidden input Base UI submits with, for form-library focus. */\n inputRef?: React.Ref<HTMLInputElement>;\n /** Renders without a floating popup, for an embedded `CascaderPanel`. */\n inline?: boolean;\n\n children?: React.ReactNode;\n}\n\nexport interface CascaderSingleProps<T = unknown> extends CascaderBaseProps<T> {\n multiple?: false;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string, details: CascaderChangeDetails<T>) => void;\n /** `never` so passing it is a compile error, not a silent no-op. */\n max?: never;\n}\n\n/** Multi-select props. Enables checkbox rows and chip display. */\nexport interface CascaderMultipleProps<T = unknown> extends CascaderBaseProps<T> {\n multiple: true;\n value?: string[];\n defaultValue?: string[];\n onValueChange?: (value: string[], details: CascaderChangeDetails<T>) => void;\n /** Cap on selections. Further picks are refused, the existing ones survive. */\n max?: number;\n}\n\n/** `multiple` discriminates: `value`, `onValueChange` and `max` narrow with it. */\nexport type CascaderProps<T = unknown> = CascaderSingleProps<T> | CascaderMultipleProps<T>;\n\n/** Normalizes to an array. `\"\"` is \"no selection\", not a node: it is the\n * uncontrolled default, and resolving it would render a blank chip. */\nfunction toArray(value: string | string[] | undefined): string[] {\n if (value == null) return [];\n if (Array.isArray(value)) return value.filter((entry) => entry !== '');\n return value === '' ? [] : [value];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Development warnings */\n/* -------------------------------------------------------------------------- */\n\ninterface CascaderDevOptions<T> {\n items: CascaderNode<T>[];\n getParent?: (node: CascaderNode<T>) => string | null | undefined;\n mode: CascaderMode;\n multiple: boolean;\n cascade: boolean;\n indicator: boolean;\n selectable: CascaderSelectable<T>;\n searchScope: CascaderSearchScope;\n max: number | undefined;\n value: string | string[] | undefined;\n defaultValue: string | string[] | undefined;\n hasExpanded: boolean;\n hasPath: boolean;\n hasOnSearch: boolean;\n}\n\n/** Misconfigurations that are SILENT by design. Once each, never in prod. */\nfunction useCascaderDevWarnings<T>(options: CascaderDevOptions<T>) {\n const {\n items,\n getParent,\n mode,\n multiple,\n cascade,\n indicator,\n selectable,\n searchScope,\n max,\n value,\n defaultValue,\n hasExpanded,\n hasPath,\n hasOnSearch,\n } = options;\n\n // O(n) over the raw input, so the memo is skipped outright in production.\n const issues = React.useMemo(\n () => (process.env.NODE_ENV === 'production' ? null : findCascaderDataIssues(items, getParent)),\n [items, getParent],\n );\n\n React.useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n\n for (const duplicate of issues?.duplicates ?? []) {\n warnCascaderOnce(\n `duplicate-value:${duplicate}`,\n `Duplicate node value ${JSON.stringify(duplicate)}. \\`value\\` is the selection key, so only the first occurrence is indexed and the rest never render.`,\n );\n }\n\n for (const cycle of issues?.cycles ?? []) {\n warnCascaderOnce(\n `cycle:${cycle}`,\n `\\`getParent\\` puts ${JSON.stringify(cycle)} on a cycle. The depth walk is cycle-guarded so nothing hangs, but every depth on that chain is clamped rather than derived.`,\n );\n }\n }, [issues]);\n\n React.useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n\n for (const [prop, current] of [\n ['value', value],\n ['defaultValue', defaultValue],\n ] as const) {\n if (current == null) continue;\n if (multiple && !Array.isArray(current)) {\n warnCascaderOnce(\n `value-shape:multiple:${prop}`,\n `\\`multiple\\` is set but \\`${prop}\\` is a string. Multi-select reads and writes a \\`string[]\\`; a string is treated as no selection at all.`,\n );\n } else if (!multiple && Array.isArray(current)) {\n warnCascaderOnce(\n `value-shape:single:${prop}`,\n `\\`${prop}\\` is an array but \\`multiple\\` is not set. Single-select reads and writes a \\`string\\`; only the first entry would survive a commit.`,\n );\n }\n }\n\n if (cascade && !multiple) {\n warnCascaderOnce(\n 'cascade-without-multiple',\n '`cascade` does nothing without `multiple`: a single selection has no subtree to propagate over.',\n );\n }\n\n if (cascade && selectable === 'leaf') {\n warnCascaderOnce(\n 'cascade-with-leaf-selectable',\n '`cascade` does nothing while `selectable=\"leaf\"`: no branch can be committed, so no commit ever has a subtree under it. Pass `selectable=\"any\"` or a predicate that accepts branches.',\n );\n }\n\n if (!indicator && multiple) {\n warnCascaderOnce(\n 'indicator-false-with-multiple',\n '`indicator={false}` does nothing with `multiple`: the checkbox is the selection control rather than a decoration, so it and its gutter stay. Mark selection your own way from `data-selected` on the row, and drop the prop.',\n );\n }\n\n if (max != null && !multiple) {\n warnCascaderOnce(\n 'max-without-multiple',\n '`max` does nothing without `multiple`: there is only ever one selection to cap.',\n );\n }\n\n if (hasExpanded && mode !== 'tree') {\n warnCascaderOnce(\n `expanded-outside-tree:${mode}`,\n `\\`expanded\\` only does something in \\`mode=\"tree\"\\`, and this cascader is in \\`mode=\"${mode}\"\\`. Drill and columns navigate with \\`path\\`.`,\n );\n }\n\n if (hasPath && mode === 'tree') {\n warnCascaderOnce(\n 'path-in-tree',\n '`path` does nothing in `mode=\"tree\"`: branches expand in place rather than replacing the level. Use `expanded`.',\n );\n }\n\n if (searchScope === 'deep' && mode === 'tree') {\n warnCascaderOnce(\n 'deep-search-in-tree',\n '`searchScope=\"deep\"` does nothing in `mode=\"tree\"`: a tree query already matches at any depth and auto-expands the ancestors of every hit.',\n );\n }\n\n if (searchScope === 'global' && mode === 'tree') {\n warnCascaderOnce(\n 'global-search-in-tree',\n '`searchScope=\"global\"` does nothing in `mode=\"tree\"`: a tree query already searches the whole tree and auto-expands the ancestors of every hit.',\n );\n }\n\n if (hasOnSearch && mode === 'tree') {\n warnCascaderOnce(\n 'onsearch-in-tree',\n '`onSearch` does nothing in `mode=\"tree\"`: a tree query filters the loaded tree in place, and a server hit belongs to no visible branch, so its results would never render. The request is not fired. Filter the tree locally, or use drill or columns for server search.',\n );\n }\n }, [\n mode,\n multiple,\n cascade,\n indicator,\n selectable,\n searchScope,\n max,\n value,\n defaultValue,\n hasExpanded,\n hasPath,\n hasOnSearch,\n ]);\n}\n\n/** What the `[]`-dep callbacks would otherwise close over. One ref, one\n * effect, so \"the last committed render\" is defined in exactly one place. */\ninterface CascaderLatest<T> {\n index: CascaderIndex<T>;\n state: CascaderStateContextValue<T>;\n mode: CascaderMode;\n multiple: boolean;\n cascade: boolean;\n max: number | undefined;\n labels: CascaderLabels;\n closeOnSelect: boolean;\n selectedValues: string[];\n deepResults: CascaderNode<T>[] | null;\n onValueChange: ((value: string | string[], details: CascaderChangeDetails<T>) => void) | undefined;\n resolveNode: (value: string) => CascaderNode<T>;\n isSelectable: (node: CascaderNode<T>) => boolean;\n needsChildren: (node: CascaderNode<T>) => boolean;\n expanded: ReadonlySet<string>;\n}\n\n/** A navigation waiting on a fetch. The `kind`s differ: a drill appends, a\n * columns press replaces the trail from `depth`, a search hit swaps in its own\n * `trail`, a tree press expands. */\ntype CascaderPendingNavigation =\n | {\n value: string;\n kind: 'push' | 'at' | 'expand';\n /** `kind: \"at\"` only. The depth the pressed row belongs to. */\n depth: number;\n }\n | {\n value: string;\n kind: 'trail';\n /** The hit's ancestor chain, root first, the hit itself last. */\n trail: string[];\n };\n\n/** No default on `T`: inferred from `items`, so `node.data` arrives typed. */\nfunction Cascader<T>({\n items,\n getParent,\n getChildren,\n onSearch,\n searchDebounce,\n resolveValue,\n loadKey,\n prefetch,\n onLoadError,\n value: valueProp,\n defaultValue,\n onValueChange: onValueChangeProp,\n multiple = false,\n selectable = 'leaf',\n indicator = true,\n actions,\n cascade = false,\n max,\n mode = 'drill',\n expandTrigger,\n path: pathProp,\n defaultPath,\n onPathChange,\n expanded: expandedProp,\n defaultExpanded,\n onExpandedChange,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n closeOnSelect = true,\n inputValue: inputValueProp,\n defaultInputValue = '',\n onInputValueChange,\n searchScope = 'level',\n filter,\n revealSelected = true,\n maxHeight,\n virtualize,\n virtualizeThreshold = 100,\n estimateRowSize = 32,\n overscan = 8,\n labels: labelsProp,\n renderItem,\n renderLabel,\n disabled,\n name,\n form,\n id,\n required,\n readOnly,\n invalid,\n inputRef,\n inline,\n children,\n}: CascaderProps<T>) {\n const baseIndex = React.useMemo(\n () => buildCascaderIndex(items, getParent),\n // `getParent` is stable by design: an inline accessor must not rebuild a\n // 50k-node index.\n\n [items],\n );\n\n const baseId = React.useId();\n\n // Shallow-stabilized first: an inline `labels` would republish the context.\n const stableLabelsProp = useShallowStable(labelsProp, shallowEqualRecords);\n\n const labels = React.useMemo(() => resolveCascaderLabels(stableLabelsProp), [stableLabelsProp]);\n\n useCascaderDevWarnings({\n items,\n getParent,\n mode,\n multiple,\n cascade,\n indicator,\n selectable,\n searchScope,\n max,\n value: valueProp,\n defaultValue,\n hasExpanded: expandedProp !== undefined || defaultExpanded !== undefined || onExpandedChange !== undefined,\n hasPath: pathProp !== undefined || defaultPath !== undefined || onPathChange !== undefined,\n hasOnSearch: onSearch !== undefined,\n });\n\n // Public props are discriminated, internals are not: one assertion.\n const onValueChange = onValueChangeProp as\n ((value: string | string[], details: CascaderChangeDetails<T>) => void) | undefined;\n\n // No `onChange`: `onValueChange` takes a second argument, so `emitSelection`\n // invokes it rather than the state hook, which only knows the value.\n const [value, setValue] = useControllable<string | string[]>(\n valueProp,\n defaultValue ?? (multiple ? [] : ''),\n undefined,\n 'value',\n );\n // Why the current path (or open) change is happening. Refs, not arguments:\n // `useControllable` only passes a value, and its onChange runs synchronously\n // inside the setter, so a ref written just before is exact. The path ref\n // resets to `\"external\"`, which is what the consumer's `setPath` reports.\n const pathReasonRef = React.useRef<CascaderPathChangeReason>('external');\n const openReasonRef = React.useRef<string>('none');\n\n const [path, setPath] = useControllable<string[]>(\n pathProp,\n defaultPath ?? [],\n (next) => onPathChange?.(next, { reason: pathReasonRef.current }),\n 'path',\n );\n const [expandedList, setExpandedList] = useControllable<string[]>(\n expandedProp,\n defaultExpanded ?? [],\n onExpandedChange,\n 'expanded',\n );\n const [open, setOpen] = useControllable<boolean>(\n openProp,\n defaultOpen,\n (next) => onOpenChange?.(next, { reason: openReasonRef.current }),\n 'open',\n );\n\n /** The internal `setPath`: names its reason, then hands back to \"external\". */\n const setPathWithReason = React.useCallback(\n (next: string[] | ((prev: string[]) => string[]), reason: CascaderPathChangeReason) => {\n pathReasonRef.current = reason;\n try {\n setPath(next);\n } finally {\n pathReasonRef.current = 'external';\n }\n },\n [setPath],\n );\n const [query, setQuery] = useControllable<string>(\n inputValueProp,\n defaultInputValue,\n onInputValueChange,\n 'inputValue',\n );\n\n const expanded = React.useMemo(() => new Set(expandedList), [expandedList]);\n const selectedValues = React.useMemo(() => toArray(value), [value]);\n\n /* --------------------------------- async -------------------------------- */\n\n // On-screen levels, so the ones worth fetching. Columns shows the whole\n // trail at once, which is why the loader is per-level, not one flag.\n const levels = React.useMemo(() => {\n if (mode === 'tree') return [CASCADER_ROOT_KEY, ...expandedList];\n if (mode === 'columns') return [CASCADER_ROOT_KEY, ...path];\n return [path.length ? path[path.length - 1] : CASCADER_ROOT_KEY];\n }, [mode, path, expandedList]);\n\n // A SIBLING of the index build, never a step inside it: the build stays pure\n // in `items`, the loader owns the pages, the merge is pure in both, and that\n // is what makes loaded data survive an `items` change.\n const loader = useCascaderLoader<T>({\n base: baseIndex,\n getChildren,\n // Gated, not merely unrendered: a tree hit belongs to no visible branch.\n onSearch: mode === 'tree' ? undefined : onSearch,\n resolveValue,\n searchDebounce,\n loadKey,\n prefetch,\n onLoadError,\n // An inline cascader is never \"open\", but its panel is live.\n enabled: open || !!inline,\n query,\n levels,\n path: searchScope === 'global' ? GLOBAL_SEARCH_PATH : path,\n values: selectedValues,\n });\n\n const loadStates = loader.states;\n\n // Destructured here, not at the actions memo, because `navigate` sits above\n // it. All three are `[]`-dep inside the loader, so identity is stable.\n const { ensureLevel, retryLevel: retryLoaderLevel, invalidateLevel } = loader;\n\n /**\n * Whether pressing this branch has to FETCH first: in flight, failed, or\n * never asked. `baseIndex`, NOT the merged `index`: `resolveValue` writes an\n * ancestor chain into `pages` without touching `states`, so the merged index\n * shows children for levels never requested. Must agree with `ensureLevel`'s\n * own guards or a press parks a navigation nothing will ever settle.\n */\n const needsChildren = React.useCallback(\n (node: CascaderNode<T>) => {\n if (!loader.active) return false;\n const state = loadStates.get(node.value);\n if (state) return state.loading || state.error;\n return !baseIndex.childrenOf.has(node.value);\n },\n [loader.active, loadStates, baseIndex],\n );\n\n // Keyed on the two maps the merge reads, NOT the store: `withLoadState`\n // returns a fresh store over the SAME maps, so keying on it rebuilt the\n // whole index on every loading flip that changed no data.\n const index = React.useMemo(\n () => mergeCascaderIndex(baseIndex, loader.store.pages, loader.store.detached),\n [baseIndex, loader.store.pages, loader.store.detached],\n );\n\n /** Whether a level needs the paging pseudo-row. A never-fetched level gets\n * nothing; that is the empty state's job. Tree has no per-level empty state,\n * so there the row is also the branch's loading and error surface. */\n const needsMoreRow = React.useCallback(\n (key: string, childCount: number) => {\n const state = loadStates.get(key);\n if (!state) return false;\n if (childCount > 0) return state.hasMore || state.loading || state.error;\n return mode === 'tree' && (state.loading || state.error);\n },\n [loadStates, mode],\n );\n\n // Remembers every selected node, so the trigger keeps a label after it\n // leaves the loaded set (or was never in it).\n const labelCacheRef = React.useRef(new Map<string, CascaderNode<T>>());\n\n // Populated during render, since the trigger reads it while rendering.\n // Idempotent and prop-derived, so a discarded render is harmless.\n for (const selected of selectedValues) {\n const node = index.byValue.get(selected);\n if (node) labelCacheRef.current.set(selected, node);\n }\n\n const resolveNode = React.useCallback(\n (nodeValue: string): CascaderNode<T> =>\n index.byValue.get(nodeValue) ??\n labelCacheRef.current.get(nodeValue) ?? {\n value: nodeValue,\n label: nodeValue,\n },\n [index],\n );\n\n /* ------------------------------ derived view ----------------------------- */\n\n const currentParentValue = path.length ? path[path.length - 1] : null;\n const currentParent = currentParentValue ? (index.byValue.get(currentParentValue) ?? null) : null;\n\n const currentLevelKey = currentParentValue ?? CASCADER_ROOT_KEY;\n\n const isDeepSearching =\n (searchScope === 'deep' || searchScope === 'global') && query.trim().length > 0 && mode !== 'tree';\n // Global is the same scan from the root, whatever level is on screen.\n const deepSearchWithin = searchScope === 'global' ? null : currentParentValue;\n\n const localDeepResults = React.useMemo(() => {\n if (!isDeepSearching) return null;\n return searchCascaderDeep(index, query, {\n within: deepSearchWithin,\n matches: filter,\n });\n }, [isDeepSearching, index, query, deepSearchWithin, filter]);\n\n // Server search wins over the local scan, or each hit shows up twice.\n const deepResults = loader.searchResults ?? localDeepResults;\n\n const levelItems = React.useMemo(() => {\n const level = getCascaderChildren(index, currentParentValue);\n return filterCascaderLevel(level, query, filter);\n }, [index, currentParentValue, query, filter]);\n\n /** The active level's rows plus the paging pseudo-row, appended HERE because\n * every index Base UI hands out indexes this array: a DOM row missing from\n * it shifts the highlight and every windowed row by one. */\n const levelRendered = React.useMemo(() => {\n if (deepResults) return deepResults;\n if (!needsMoreRow(currentLevelKey, levelItems.length)) return levelItems;\n return [...levelItems, createCascaderMoreNode<T>(currentLevelKey, levelItems.length)];\n }, [deepResults, levelItems, currentLevelKey, needsMoreRow]);\n\n // Columns renders the whole trail, but only the deepest column is\n // interactive through Base UI, so `renderedItems` stays what drill uses.\n const columns = React.useMemo<CascaderColumn<T>[]>(() => {\n if (mode !== 'columns') return [];\n const trail: CascaderColumn<T>[] = [];\n for (let depth = 0; depth <= path.length; depth += 1) {\n const parentValue = depth === 0 ? null : path[depth - 1];\n const parent = parentValue ? (index.byValue.get(parentValue) ?? null) : null;\n const isActive = depth === path.length;\n let columnItems: CascaderNode<T>[];\n if (isActive) {\n columnItems = levelRendered;\n } else {\n // A trail column pages on its own, without losing the columns right of it.\n const key = parentValue ?? CASCADER_ROOT_KEY;\n const children = getCascaderChildren(index, parentValue);\n columnItems = needsMoreRow(key, children.length)\n ? [...children, createCascaderMoreNode<T>(key, children.length)]\n : children;\n }\n trail.push({\n parent,\n depth,\n activeValue: path[depth] ?? null,\n active: isActive,\n // Only the active column is filtered: a query narrows what you type\n // into, never the trail behind it.\n items: columnItems,\n });\n }\n return trail;\n }, [mode, path, index, levelRendered, needsMoreRow]);\n\n // Tree level keys needing a paging pseudo-row. With no per-level empty\n // state, this is also where a still-loading branch says so.\n const treeSentinels = React.useMemo(() => {\n if (mode !== 'tree') return undefined;\n const keys = new Set<string>();\n const consider = (key: string) => {\n if (needsMoreRow(key, index.childrenOf.get(key)?.length ?? 0)) {\n keys.add(key);\n }\n };\n consider(CASCADER_ROOT_KEY);\n for (const value of expanded) consider(value);\n return keys.size ? keys : undefined;\n }, [mode, index, expanded, needsMoreRow]);\n\n const treeRows = React.useMemo<CascaderFlatNode<T>[]>(() => {\n if (mode !== 'tree') return [];\n const rows = flattenCascaderTree(index, expanded, treeSentinels);\n // Same normalizer as the level filter, so the two cannot disagree.\n const normalized = normalizeCascaderQuery(query);\n if (!normalized) return rows;\n // Matches every node, not just visible rows, and keeps the ancestors, or a\n // hit inside a collapsed branch disappears. Same matcher as every other\n // path, so keyword-only hits do not vanish in tree mode alone.\n const keep = new Set<string>();\n for (const node of index.all) {\n if (!(filter ? filter(node, normalized) : matchesCascaderQuery(node, normalized))) {\n continue;\n }\n for (const ancestor of getCascaderPath(index, node.value)) {\n keep.add(ancestor.value);\n }\n }\n // No sentinels while filtering: that page would not have the query applied.\n return flattenCascaderTree(index, new Set([...expanded, ...keep])).filter((row) => keep.has(row.node.value));\n }, [mode, index, expanded, treeSentinels, query, filter]);\n\n // What `Combobox.Root` receives. Tree flattens to the same linear list, so\n // selection and highlighting need no per-mode case.\n const renderedItems = React.useMemo(\n () => (mode === 'tree' ? treeRows.map((row) => row.node) : levelRendered),\n [mode, treeRows, levelRendered],\n );\n\n /* ---------------------------- level swap reset --------------------------- */\n\n /** Base UI never resets the highlighted index on an `items` change and has\n * no imperative setter; its one automatic reset is an out-of-range clamp, so\n * a single empty frame trips it. The frame rides `filteredItems`, so the\n * `items` identity stays put. */\n const levelKey = currentParentValue ?? '';\n\n // STATE, not a ref: a replayed render would see a ref advanced and skip it.\n const [swap, setSwap] = React.useState({ key: levelKey, active: false });\n\n if (swap.key !== levelKey) {\n setSwap({ key: levelKey, active: true });\n }\n const swapping = swap.active && swap.key === levelKey;\n\n React.useLayoutEffect(() => {\n if (swap.active) setSwap((prev) => ({ ...prev, active: false }));\n }, [swap.active]);\n\n // The same frame on demand, for a navigation that lands on the level already\n // on screen: the key never moves, so the check above never fires.\n const resetHighlight = React.useCallback(() => {\n setSwap((prev) => (prev.active ? prev : { ...prev, active: true }));\n }, []);\n\n /* ----------------------------- virtualization ---------------------------- */\n\n // A COUNT: columns mounts one per column, and StrictMode remounts effects.\n const [virtualRenderers, setVirtualRenderers] = React.useState(0);\n\n const registerVirtualRenderer = React.useCallback(() => {\n setVirtualRenderers((count) => count + 1);\n return () => setVirtualRenderers((count) => Math.max(0, count - 1));\n }, []);\n\n const hasVirtualRenderer = virtualRenderers > 0;\n const wantsVirtual = virtualize ?? renderedItems.length >= virtualizeThreshold;\n\n // LATCHED per level: otherwise a query narrowing a 5,000 row level past the\n // threshold tears the virtualizer down and rebuilds it on backspace, losing\n // every measurement. State, not a ref, like `swap`.\n const [virtualLatch, setVirtualLatch] = React.useState({\n key: levelKey,\n on: false,\n });\n\n const virtualized =\n hasVirtualRenderer && (virtualLatch.key === levelKey ? virtualLatch.on || wantsVirtual : wantsVirtual);\n\n if (!hasVirtualRenderer) {\n // Nothing is windowing, so nothing may stay latched.\n if (virtualLatch.on || virtualLatch.key !== levelKey) {\n setVirtualLatch({ key: levelKey, on: false });\n }\n } else if (virtualLatch.key !== levelKey) {\n setVirtualLatch({ key: levelKey, on: virtualized });\n } else if (virtualized && !virtualLatch.on) {\n setVirtualLatch({ key: levelKey, on: true });\n }\n\n /**\n * One forced re-render, one commit AFTER windowing turns on. Base UI sizes\n * `listRef` from `filteredItems` in a layout effect keyed on that array's\n * identity, but `virtualized` reaches the list a commit later and the\n * `CompositeList` teardown REPLACES `listRef` with an empty array nothing\n * re-sizes, so ArrowDown stops at the last WINDOWED row. A passive effect is\n * late enough: the teardown is scheduled from a layout effect.\n */\n const [virtualSyncs, setVirtualSyncs] = React.useState(0);\n\n React.useEffect(() => {\n if (!virtualized) return;\n setVirtualSyncs((count) => count + 1);\n }, [virtualized]);\n\n React.useEffect(() => {\n if (process.env.NODE_ENV === 'production') return undefined;\n if (virtualize !== true || hasVirtualRenderer) return undefined;\n // Deferred a tick: the renderer registers from a layout effect, so a\n // synchronous check would report every correctly wired cascader.\n const timeout = setTimeout(() => {\n console.error(\n '[Cascader] `virtualize` is true but no windowing renderer is mounted. ' +\n 'Render <CascaderVirtualItems /> inside <CascaderList>, or ' +\n '<CascaderVirtualColumn /> through the <CascaderColumns> slot.',\n );\n }, 0);\n return () => clearTimeout(timeout);\n }, [virtualize, hasVirtualRenderer]);\n\n /* ------------------------------ navigation ------------------------------ */\n\n /** One signal per navigation, feeding the live region, bumped EXACTLY once\n * per action. `seq` alternates the invisible marker so two identical\n * announcements are still two mutations; `toggled` names the tree branch. */\n const [announceSignal, setAnnounceSignal] = React.useState<{\n seq: number;\n toggled: string | null;\n /** A one-off verbatim message: a `max` refusal, a cascade fan-out. STATE,\n * so an unrelated render cannot clear it mid-read. */\n notice: string | null;\n }>({ seq: 0, toggled: null, notice: null });\n\n const bumpAnnouncement = React.useCallback((toggled: string | null) => {\n setAnnounceSignal((prev) => ({ seq: prev.seq + 1, toggled, notice: null }));\n }, []);\n\n /** Speaks for interactions that change nothing on screen: a refusal returns\n * before any state moves, a cascade sweep is invisible from the row pressed.\n * The seq bump keeps two identical refusals two mutations. */\n const announceNotice = React.useCallback((notice: string) => {\n setAnnounceSignal((prev) => ({ seq: prev.seq + 1, toggled: null, notice }));\n }, []);\n\n /**\n * The navigation a press asked for and a fetch has not answered yet. Load\n * BEFORE you move: drilling in first threw away the list the user was\n * reading and, on failure, stranded them on an error screen for a level they\n * had never seen. Holding here keeps the old rows and puts the progress on\n * the pressed row, whose chevron `CascaderItem` swaps for a spinner.\n */\n const [pendingNavigation, setPendingNavigation] = React.useState<CascaderPendingNavigation | null>(null);\n\n /** Asks for a branch's children and parks the navigation until they land.\n * BOTH entry points are called unconditionally: `retryLevel` no-ops unless\n * the level errored, `ensureLevel` no-ops if it has state, so a repeat press\n * is free and the readiness decision stays inside the loader. */\n const requestChildren = React.useCallback(\n (node: CascaderNode<T>, pending: CascaderPendingNavigation) => {\n setPendingNavigation(pending);\n retryLoaderLevel(node.value);\n ensureLevel(node.value, 'level');\n // Otherwise the panel is silent from the press until the level swaps.\n bumpAnnouncement(null);\n },\n [retryLoaderLevel, ensureLevel, bumpAnnouncement],\n );\n\n const pushLevel = React.useCallback(\n (nodeValue: string) => {\n setPathWithReason((prev) => [...prev, nodeValue], 'drill');\n setQuery('');\n bumpAnnouncement(null);\n },\n [setPathWithReason, setQuery, bumpAnnouncement],\n );\n\n const popLevel = React.useCallback(() => {\n setPathWithReason((prev) => (prev.length ? prev.slice(0, -1) : prev), 'back');\n setQuery('');\n // Going BACK abandons a held navigation, or an in-flight branch drills in\n // the moment it lands, long after the user moved on.\n setPendingNavigation(null);\n bumpAnnouncement(null);\n }, [setPathWithReason, setQuery, bumpAnnouncement]);\n\n const goToDepth = React.useCallback(\n (depth: number) => {\n setPathWithReason((prev) => prev.slice(0, Math.max(0, depth)), 'breadcrumb');\n setQuery('');\n setPendingNavigation(null);\n bumpAnnouncement(null);\n },\n [setPathWithReason, setQuery, bumpAnnouncement],\n );\n\n const toggleExpanded = React.useCallback(\n (nodeValue: string) => {\n setExpandedList((prev) =>\n prev.includes(nodeValue) ? prev.filter((v) => v !== nodeValue) : [...prev, nodeValue],\n );\n bumpAnnouncement(nodeValue);\n },\n [setExpandedList, bumpAnnouncement],\n );\n\n const isBranch = React.useCallback((node: CascaderNode<T>) => isCascaderBranch(index, node), [index]);\n\n const isSelectable = React.useCallback(\n (node: CascaderNode<T>) => isCascaderSelectable(index, node, selectable),\n [index, selectable],\n );\n\n const isDisabled = React.useCallback((node: CascaderNode<T>) => isCascaderDisabled(index, node), [index]);\n\n // Whether a branch can be committed AT ALL here. `\"leaf\"` is the only\n // setting that answers no in advance; a predicate is opaque, so the check\n // gutter is reserved uniformly rather than per row.\n const branchesSelectable = selectable !== 'leaf';\n\n // Open flyouts, by key. A ref, not state: `handleOpenChange` needs the\n // answer as of the Escape being handled, and opening a footer menu must not\n // re-render the root.\n const openFlyoutsRef = React.useRef<Set<string>>(new Set());\n\n const setFlyoutOpen = React.useCallback((key: string, open: boolean) => {\n if (open) openFlyoutsRef.current.add(key);\n else openFlyoutsRef.current.delete(key);\n }, []);\n\n const hasOpenFlyout = React.useCallback(() => openFlyoutsRef.current.size > 0, []);\n\n // Shallow-stabilized like `labels`: an inline array republished the context.\n const stableActions = useShallowStable(actions, shallowEqualItemLists);\n\n const resolvedActions = React.useMemo<CascaderActionItem[]>(() => stableActions ?? EMPTY_ACTIONS, [stableActions]);\n\n // A Set, not an `includes` scan: `isSelected` runs once per rendered row.\n const selectedSet = React.useMemo(() => new Set(selectedValues), [selectedValues]);\n\n const isSelected = React.useCallback((node: CascaderNode<T>) => selectedSet.has(node.value), [selectedSet]);\n\n /** Selected-descendant counts, walked ONCE per selection change and never\n * stored, so the flat value array stays the only source of truth. The walk\n * is `selections x depth`, up from each selection rather than down from each\n * row, which keeps the count and `isIndeterminate` O(1). */\n const selectedDescendants = React.useMemo(\n () => getCascaderSelectedDescendants(index, selectedValues),\n [index, selectedValues],\n );\n\n const selectedDescendantCount = React.useCallback(\n (node: CascaderNode<T>) => selectedDescendants.get(node.value) ?? 0,\n [selectedDescendants],\n );\n\n // Partial selections read off the SAME map, so the dash and the number are\n // two readings of one traversal and cannot drift apart.\n const indeterminateSet = React.useMemo(() => {\n if (!cascade || !multiple) return null;\n return getCascaderIndeterminateFrom(selectedDescendants, selectedValues);\n }, [cascade, multiple, selectedDescendants, selectedValues]);\n\n const isIndeterminate = React.useCallback(\n (node: CascaderNode<T>) => indeterminateSet?.has(node.value) ?? false,\n [indeterminateSet],\n );\n\n // Base UI owns the highlight; mirrored so handlers can read it unsubscribed.\n const highlightedRef = React.useRef<CascaderNode<T> | null>(null);\n const getHighlighted = React.useCallback(() => highlightedRef.current, []);\n\n // The same highlight as an external store, for the consumer that must\n // RE-RENDER on it. `useState`, not `useMemo`: React may drop a memo, and a\n // second store would silently orphan every subscriber.\n const [highlightStore] = React.useState<CascaderHighlightStore>(createCascaderHighlightStore);\n\n /* ------------------------------ announcement ---------------------------- */\n\n const currentLoadState = React.useMemo<CascaderLoadState | null>(\n () => loadStates.get(currentLevelKey) ?? null,\n [loadStates, currentLevelKey],\n );\n const searchLoadState = loader.searchState;\n\n /** What the query announcement COUNTS: matches, not rows, since the list\n * also carries a tree query's ancestor context and the Load-more row. Server\n * hits count as-is; re-judging them locally would drop what it matched on\n * data the client cannot see. */\n const announcedMatches = React.useMemo(() => {\n if (deepResults) return deepResults.length;\n const normalized = normalizeCascaderQuery(query);\n if (!normalized) return 0;\n const matches = filter ?? matchesCascaderQuery;\n return renderedItems.filter((node) => !isCascaderMoreNode(node) && matches(node, normalized)).length;\n }, [deepResults, renderedItems, query, filter]);\n\n // The live-region text plus whether it may be DEFERRED; see\n // `ANNOUNCE_DEBOUNCE`. The committed string is state, set below.\n const announcementTarget = React.useMemo(() => {\n // An INLINE cascader is never \"open\", so `open` alone silenced its tree.\n if (!open && !inline) return { text: '', defer: false };\n\n const total = renderedItems.length;\n const marker = ANNOUNCE_MARKER.repeat(announceSignal.seq % 2);\n\n // A notice outranks everything below: it exists because nothing else on\n // screen changed. It rides the signal, so the next navigation replaces it.\n if (announceSignal.notice) {\n return { text: `${announceSignal.notice}${marker}`, defer: false };\n }\n\n // A tree toggle changes neither level nor query, so it rides the signal.\n const toggled =\n mode === 'tree' && announceSignal.toggled ? (index.byValue.get(announceSignal.toggled) ?? null) : null;\n\n // Async states outrank everything below, or a fetching level announces \"0\n // results\" and contradicts itself. A HELD navigation outranks even those:\n // nothing on screen has moved yet, so \"loading\" is the only truth.\n const pendingState = pendingNavigation ? (loadStates.get(pendingNavigation.value) ?? null) : null;\n const levelState = query.trim() ? searchLoadState : currentLoadState;\n let text: string;\n let defer = false;\n if (pendingState?.error) {\n text = labels.error;\n } else if (pendingNavigation) {\n // Always the FIRST-page string: the rows on screen belong to the level\n // being left behind, so their count says nothing about this request.\n text = labels.loading;\n } else if (levelState?.error) {\n text = labels.error;\n } else if (levelState?.loading) {\n // With a query set the in-flight load IS the server search, and calling\n // that \"Loading more\" misreads what is being waited on.\n text = query.trim() ? labels.searchingAnnouncement : total > 0 ? labels.loadingMore : labels.loading;\n } else if (query.trim()) {\n // An empty result set is the more useful thing to say than \"0 results\".\n text = announcedMatches === 0 ? labels.empty : labels.resultsAnnouncement(announcedMatches);\n // The ONE deferred branch: only a stream of keystrokes needs coalescing.\n defer = true;\n } else if (toggled) {\n text = expanded.has(toggled.value)\n ? labels.expandedAnnouncement(toggled.label, getCascaderCount(index, toggled))\n : labels.collapsedAnnouncement(toggled.label);\n } else if (currentParent) {\n // `path.length + 1` matches tree mode's `aria-level`: the rows are\n // `currentParent`'s CHILDREN, one level below it.\n text = labels.levelAnnouncement(currentParent.label, path.length + 1, total);\n } else {\n // Returning to the root would otherwise announce nothing at all.\n text = labels.rootAnnouncement(total);\n }\n\n return { text: `${text}${marker}`, defer };\n }, [\n open,\n inline,\n mode,\n index,\n expanded,\n announceSignal,\n query,\n labels,\n renderedItems.length,\n announcedMatches,\n currentParent,\n path.length,\n currentLoadState,\n searchLoadState,\n pendingNavigation,\n loadStates,\n ]);\n\n /** The COMMITTED announcement. Immediate texts commit during render (the\n * pattern `swap` uses), so an async settle announces in the very commit that\n * shows the rows. Only the deferred query count uses the timer below. */\n const [announced, setAnnounced] = React.useState(announcementTarget);\n\n if (!announcementTarget.defer && announced.text !== announcementTarget.text) {\n // Terminates: after the set the condition is false on the re-render.\n setAnnounced(announcementTarget);\n }\n\n React.useEffect(() => {\n if (!announcementTarget.defer) return undefined;\n const timer = setTimeout(() => setAnnounced(announcementTarget), ANNOUNCE_DEBOUNCE);\n return () => clearTimeout(timer);\n }, [announcementTarget]);\n\n const announcement = announced.text;\n\n /* --------------------------------- state -------------------------------- */\n\n // The volatile half: rebuilt by a keystroke, hence split from the actions.\n const stateValue = React.useMemo<CascaderStateContextValue<T>>(\n () => ({\n index,\n path,\n expanded,\n query,\n currentParent,\n levelItems,\n deepResults,\n renderedItems,\n columns,\n treeRows,\n selectedValues,\n selectedDescendants,\n loadStates,\n searchState: searchLoadState,\n announcement,\n }),\n [\n index,\n path,\n expanded,\n query,\n currentParent,\n levelItems,\n deepResults,\n renderedItems,\n columns,\n treeRows,\n selectedValues,\n selectedDescendants,\n loadStates,\n searchLoadState,\n announcement,\n ],\n );\n\n /* ------------------------------ latest props ---------------------------- */\n\n /**\n * Latest committed props and derived state, WRITTEN IN AN EFFECT. That is\n * what keeps the callbacks below `[]`-dep and stable for the life of the\n * cascader; writing during render is unsafe under concurrent rendering. The\n * cost: a read sees the PREVIOUS commit until the effect runs, so ONLY event\n * handlers may read it. Anything used during render is memoised instead.\n */\n const latest = React.useRef<CascaderLatest<T>>({\n index,\n state: stateValue,\n mode,\n multiple,\n cascade,\n max,\n labels,\n closeOnSelect,\n selectedValues,\n deepResults,\n onValueChange,\n resolveNode,\n isSelectable,\n needsChildren,\n expanded,\n });\n\n React.useEffect(() => {\n latest.current = {\n index,\n state: stateValue,\n mode,\n multiple,\n cascade,\n max,\n labels,\n closeOnSelect,\n selectedValues,\n deepResults,\n onValueChange,\n resolveNode,\n isSelectable,\n needsChildren,\n expanded,\n };\n });\n\n const getIndex = React.useCallback(() => latest.current.index, []);\n const getState = React.useCallback(() => latest.current.state, []);\n\n const goToLevelAt = React.useCallback(\n (nodeValue: string, depth: number) => {\n setPathWithReason((prev) => [...prev.slice(0, Math.max(0, depth)), nodeValue], 'drill');\n setQuery('');\n bumpAnnouncement(null);\n },\n [setPathWithReason, setQuery, bumpAnnouncement],\n );\n\n const goToTrail = React.useCallback(\n (trail: string[]) => {\n // A global hit can BE the level on screen. Then nothing moved, so no path\n // change is reported, and no level swap clears the highlight the hit\n // list left at its index, where Enter would commit some other row.\n const { path: current } = latest.current.state;\n const stays = trail.length === current.length && trail.every((entry, i) => entry === current[i]);\n if (stays) resetHighlight();\n else setPathWithReason(trail, 'drill');\n setQuery('');\n bumpAnnouncement(null);\n },\n [setPathWithReason, resetHighlight, setQuery, bumpAnnouncement],\n );\n\n const navigateAt = React.useCallback(\n (node: CascaderNode<T>, depth: number) => {\n if (isCascaderDisabled(latest.current.index, node)) return;\n if (latest.current.mode === 'tree') {\n toggleExpanded(node.value);\n return;\n }\n if (latest.current.needsChildren(node)) {\n requestChildren(node, { value: node.value, kind: 'at', depth });\n return;\n }\n goToLevelAt(node.value, depth);\n },\n [toggleExpanded, goToLevelAt, requestChildren],\n );\n\n const navigate = React.useCallback(\n (node: CascaderNode<T>) => {\n const {\n mode: currentMode,\n deepResults: currentDeepResults,\n index: currentIndex,\n expanded: currentExpanded,\n needsChildren: pending,\n } = latest.current;\n\n // Every drill and expand passes here, from a search hit, a key or a hover\n // timer alike, so this is where a disabled subtree stays shut.\n if (isCascaderDisabled(currentIndex, node)) return;\n\n if (currentMode === 'tree') {\n // Collapsing never needs data. Opening waits WITHOUT expanding, so\n // the branch stays shut with a spinner rather than opening onto no rows.\n if (!currentExpanded.has(node.value) && pending(node)) {\n requestChildren(node, {\n value: node.value,\n kind: 'expand',\n depth: 0,\n });\n return;\n }\n toggleExpanded(node.value);\n return;\n }\n\n // A search hit sits at any depth, and under a global search outside the\n // current path, so drilling in swaps in the hit's own trail. A held drill\n // carries it too: splicing the hit into the current path at its depth\n // kept the wrong ancestors for anything below a direct child.\n if (currentDeepResults) {\n const trail = getCascaderPath(currentIndex, node.value).map((entry) => entry.value);\n if (pending(node)) {\n requestChildren(node, { value: node.value, kind: 'trail', trail });\n return;\n }\n goToTrail(trail);\n return;\n }\n\n if (pending(node)) {\n requestChildren(node, { value: node.value, kind: 'push', depth: 0 });\n return;\n }\n pushLevel(node.value);\n },\n [toggleExpanded, goToTrail, pushLevel, requestChildren],\n );\n\n /**\n * The other half of `requestChildren`: the fetch settled, so the held\n * navigation happens or is dropped. Reads the load STATE, not a promise:\n * only the loader knows a request was superseded, aborted or retried, and no\n * entry at all means it has not reached the store yet. On failure nothing\n * moves and the intent is KEPT, which is what makes the row's retry\n * affordance mean something; only `popLevel`, `goToDepth` and a close drop it.\n */\n React.useEffect(() => {\n if (!pendingNavigation) return;\n const state = loadStates.get(pendingNavigation.value);\n if (!state || state.loading || state.error) return;\n\n setPendingNavigation(null);\n\n // Asked again against the index as it is NOW: a new `items` or a landed\n // page can disable the target while its fetch was in flight.\n const target = index.byValue.get(pendingNavigation.value);\n if (target && isDisabled(target)) return;\n\n if (pendingNavigation.kind === 'expand') {\n toggleExpanded(pendingNavigation.value);\n return;\n }\n if (pendingNavigation.kind === 'trail') {\n goToTrail(pendingNavigation.trail);\n return;\n }\n if (pendingNavigation.kind === 'at') {\n goToLevelAt(pendingNavigation.value, pendingNavigation.depth);\n return;\n }\n pushLevel(pendingNavigation.value);\n }, [pendingNavigation, loadStates, index, isDisabled, toggleExpanded, goToTrail, goToLevelAt, pushLevel]);\n\n // A popup that closes mid-flight must not drill in when the answer arrives;\n // the loader aborts the request, this drops the intent.\n React.useEffect(() => {\n if (!open && !inline) setPendingNavigation(null);\n }, [open, inline]);\n\n /* ------------------------------- selection ------------------------------ */\n\n // The one place the selection changes, so `onValueChange` reports the same\n // shape whatever caused it: a row press, drag-select, or the headless hooks.\n const emitSelection = React.useCallback(\n (nextValues: string[], node: CascaderNode<T> | null, reason: CascaderChangeReason) => {\n const {\n selectedValues: current,\n multiple: currentMultiple,\n onValueChange: emit,\n index: currentIndex,\n resolveNode: resolve,\n } = latest.current;\n\n // Nothing changed. The dedup lives here now, not in `useControllable`.\n const unchanged = nextValues.length === current.length && nextValues.every((entry, i) => entry === current[i]);\n if (unchanged) return;\n\n const next = currentMultiple ? nextValues : (nextValues[0] ?? '');\n setValue(next);\n\n if (!emit) return;\n\n const chain = node ? getCascaderPath(currentIndex, node.value) : [];\n emit(next, {\n node,\n // A node absent from `items` has no chain, so fall back to the node\n // rather than report an empty path for a change that had one.\n path: node ? (chain.length ? chain : [node]) : [],\n // `resolveNode`, not `index.byValue`: a selected value missing from\n // `items` must still come back rather than be dropped.\n nodes: nextValues.map(resolve),\n reason,\n });\n },\n [setValue],\n );\n\n const setSelection = React.useCallback(\n (values: string[], reason?: CascaderChangeReason) => {\n const { selectedValues: current, resolveNode: resolve } = latest.current;\n const before = new Set(current);\n const after = new Set(values);\n const added = values.find((entry) => !before.has(entry));\n const removed = current.find((entry) => !after.has(entry));\n\n if (reason === 'clear') {\n emitSelection(values, null, 'clear');\n return;\n }\n if (added) {\n emitSelection(values, resolve(added), reason ?? 'select');\n return;\n }\n if (removed) {\n emitSelection(values, resolve(removed), reason ?? 'deselect');\n return;\n }\n // Same set: a no-op, but routed so an explicit `reason` still applies.\n emitSelection(values, null, reason ?? 'select');\n },\n [emitSelection],\n );\n\n const commit = React.useCallback(\n (node: CascaderNode<T>) => {\n const {\n multiple: currentMultiple,\n cascade: currentCascade,\n selectedValues: current,\n max: currentMax,\n index: currentIndex,\n isSelectable: currentIsSelectable,\n labels: currentLabels,\n closeOnSelect: currentCloseOnSelect,\n } = latest.current;\n\n // Refuses a SELECT, never a removal: a disabled value set from outside\n // must stay removable, and a cascade chip's removal arrives here.\n const selecting = !currentMultiple || !current.includes(node.value);\n if (selecting && isCascaderDisabled(currentIndex, node)) return;\n\n if (!currentMultiple) {\n emitSelection([node.value], node, 'select');\n if (currentCloseOnSelect) {\n openReasonRef.current = 'item-press';\n setOpen(false);\n } else {\n // The popup stays up, so clear the query the way a multiple commit\n // does; the next pick then starts from the full level.\n setQuery('');\n }\n return;\n }\n\n if (currentCascade) {\n const next = applyCascadeSelection(currentIndex, current, node.value, selecting, currentIsSelectable);\n // `max` caps the whole gesture rather than truncating it: an arbitrary\n // prefix of a subtree is a selection nobody asked for. The refusal\n // changes nothing on screen, so the live region is its only witness.\n if (selecting && currentMax != null && next.length > currentMax && next.length > current.length) {\n announceNotice(currentLabels.maxReachedAnnouncement(currentMax));\n return;\n }\n emitSelection(next, node, selecting ? 'select' : 'deselect');\n // How many values the closure swept along is invisible from the one\n // row pressed, so the sweep says its number out loud, itself excluded.\n const before = new Set(current);\n const after = new Set(next);\n let swept = 0;\n for (const entry of selecting ? next : current) {\n if (entry === node.value) continue;\n if (selecting ? !before.has(entry) : !after.has(entry)) swept += 1;\n }\n if (swept > 0) {\n announceNotice(currentLabels.cascadeAnnouncement(node.label ?? node.value, swept, selecting));\n }\n setQuery('');\n return;\n }\n\n if (current.includes(node.value)) {\n emitSelection(\n current.filter((v) => v !== node.value),\n node,\n 'deselect',\n );\n } else if (currentMax == null || current.length < currentMax) {\n emitSelection([...current, node.value], node, 'select');\n } else {\n // The plain-multiple twin of the cascade refusal above: just as silent.\n announceNotice(currentLabels.maxReachedAnnouncement(currentMax));\n }\n setQuery('');\n },\n [emitSelection, setOpen, setQuery, announceNotice],\n );\n\n /** Safety net for paths that bypass the row-level veto (the drag-select\n * mouseup). `details.cancel()` suppresses the commit and the close together:\n * Base UI shares one event-details object between them. */\n const handleComboboxValueChange = React.useCallback(\n (next: CascaderNode<T> | CascaderNode<T>[] | null, details: ComboboxPrimitive.Root.ChangeEventDetails) => {\n if (!multiple) {\n const node = Array.isArray(next) ? (next[0] ?? null) : next;\n // The paging row is a real option, so Base UI reports it as a\n // selection. Same safety net branches get, for paths a row cannot veto.\n if (node && isCascaderMoreNode(node)) {\n details.cancel();\n return;\n }\n // The row is Base UI `disabled` already, so only a path around it gets\n // here, a custom row re-enabling it for one: refused, never navigated.\n if (node && isDisabled(node)) {\n details.cancel();\n return;\n }\n if (node && !isSelectable(node) && isBranch(node)) {\n details.cancel();\n navigate(node);\n return;\n }\n if (node) {\n // `closeOnSelect={false}` must also stop Base UI's OWN close; one\n // shared details object, so cancelling suppresses both, and our value\n // is controlled, so Base UI's half had nothing to keep.\n if (!closeOnSelect) details.cancel();\n commit(node);\n }\n return;\n }\n\n // Take Base UI's whole array as the answer and inspect only what was\n // ADDED. Deriving the toggle from the tail works for an add but on a\n // remove drops the wrong node, leaving the last selection unclearable.\n const nextNodes = Array.isArray(next) ? next : [];\n const before = new Set(selectedValues);\n const added = nextNodes.find((node) => !before.has(node.value));\n\n if (added && (isCascaderMoreNode(added) || isDisabled(added))) {\n details.cancel();\n return;\n }\n\n if (added && !isSelectable(added) && isBranch(added)) {\n details.cancel();\n navigate(added);\n return;\n }\n\n // Cascading reads Base UI's array only as the REPORT of which row was\n // pressed: it differs by exactly one value either way, and the real\n // commit covers a whole subtree.\n if (cascade) {\n const nextValues = new Set(nextNodes.map((node) => node.value));\n const removed = selectedValues.find((entry) => !nextValues.has(entry));\n const toggled = added ?? (removed != null ? resolveNode(removed) : null);\n if (toggled) commit(toggled);\n return;\n }\n\n if (max != null && nextNodes.length > selectedValues.length && nextNodes.length > max) {\n details.cancel();\n // The third silent refusal site: cancelling reverts the press with no\n // state change, so the live region is the only witness.\n announceNotice(labels.maxReachedAnnouncement(max));\n return;\n }\n\n setSelection(nextNodes.map((node) => node.value));\n setQuery('');\n },\n [\n multiple,\n selectedValues,\n max,\n cascade,\n closeOnSelect,\n labels,\n announceNotice,\n isSelectable,\n isDisabled,\n isBranch,\n navigate,\n commit,\n resolveNode,\n setSelection,\n setQuery,\n ],\n );\n\n const handleOpenChange = React.useCallback(\n (nextOpen: boolean, details: ComboboxPrimitive.Root.ChangeEventDetails) => {\n if (details.isCanceled) return;\n\n // Escape closes ONE popup at a time. `Combobox` builds no `FloatingTree`,\n // so one Escape reaches the flyout and the cascader; the flyout clears\n // its registration in an effect, so the set holds for exactly this event.\n if (!nextOpen && details.reason === 'escape-key' && hasOpenFlyout()) {\n details.cancel();\n return;\n }\n\n // Captured for the wrapped `onOpenChange`, which runs synchronously\n // inside `setOpen`, so a ref written just before the call is exact.\n openReasonRef.current = details.reason ?? 'none';\n setOpen(nextOpen);\n\n if (!nextOpen) {\n setQuery('');\n return;\n }\n\n // Opening onto the level holding the selection is the difference\n // between \"edit this\" and \"start over\".\n if (revealSelected) {\n setQuery('');\n const first = toArray(value)[0];\n setPathWithReason(\n first\n ? getCascaderPath(index, first)\n .slice(0, -1)\n .map((node) => node.value)\n : [],\n 'reveal',\n );\n }\n },\n [setOpen, setQuery, revealSelected, value, index, setPathWithReason, hasOpenFlyout],\n );\n\n /* -------------------------------- context ------------------------------- */\n\n // NOT memoised further: render props must be the current closure, and only\n // rows consume this. See `CascaderRenderContextValue`.\n const renderContext = React.useMemo(() => ({ renderItem, renderLabel }), [renderItem, renderLabel]);\n\n /** The stable half: nothing in these deps moves on a keystroke, a level\n * change or a highlight, which is what makes `React.memo` on `CascaderItem`\n * hold while the user types. Destructured off `loader` so the memo depends\n * on its `[]`-dep callbacks, not the object it republishes per load. */\n const { active: hasLoader, loadMore, retryLevel, prefetchNode } = loader;\n\n const actionsValue = React.useMemo<CascaderActionsContextValue<T>>(\n () => ({\n index,\n mode,\n multiple,\n cascade,\n branchesSelectable,\n indicator,\n expandTrigger,\n actions: resolvedActions,\n searchScope,\n maxHeight,\n inline: !!inline,\n invalid: !!invalid,\n baseId,\n labels,\n virtualized,\n registerVirtualRenderer,\n virtualize,\n virtualizeThreshold,\n estimateRowSize,\n overscan,\n hasLoader,\n loadMore,\n retryLevel,\n invalidateLevel,\n getIndex,\n getState,\n getHighlighted,\n setPath,\n pushLevel,\n popLevel,\n goToDepth,\n toggleExpanded,\n setFlyoutOpen,\n hasOpenFlyout,\n setQuery,\n setSelection,\n commit,\n navigate,\n navigateAt,\n resolveNode,\n isBranch,\n isSelectable,\n isDisabled,\n isSelected,\n isIndeterminate,\n selectedDescendantCount,\n }),\n [\n index,\n mode,\n multiple,\n cascade,\n branchesSelectable,\n indicator,\n expandTrigger,\n resolvedActions,\n searchScope,\n maxHeight,\n inline,\n invalid,\n baseId,\n labels,\n virtualized,\n registerVirtualRenderer,\n virtualize,\n virtualizeThreshold,\n estimateRowSize,\n overscan,\n hasLoader,\n loadMore,\n retryLevel,\n invalidateLevel,\n getIndex,\n getState,\n getHighlighted,\n setPath,\n pushLevel,\n popLevel,\n goToDepth,\n toggleExpanded,\n setFlyoutOpen,\n hasOpenFlyout,\n setQuery,\n setSelection,\n commit,\n navigate,\n navigateAt,\n resolveNode,\n isBranch,\n isSelectable,\n isDisabled,\n isSelected,\n isIndeterminate,\n selectedDescendantCount,\n ],\n );\n\n // A fresh array identity each time windowing turns on, and once more after:\n // that identity is the ONLY thing that re-runs Base UI's `listRef` sizing\n // effect. See `virtualSyncs`.\n const comboboxItems = React.useMemo(\n () => (virtualized ? renderedItems.slice() : renderedItems),\n\n [renderedItems, virtualized, virtualSyncs],\n );\n\n const comboboxValue = React.useMemo(() => {\n if (multiple) return selectedValues.map(resolveNode);\n return selectedValues.length ? resolveNode(selectedValues[0]) : null;\n }, [multiple, selectedValues, resolveNode]);\n\n return (\n // Providers store values with the item generic erased; the hooks re-apply\n // the caller's own `T` on the way back out.\n <CascaderActionsContext.Provider value={actionsValue as unknown as CascaderActionsContextValue}>\n <CascaderStateContext.Provider value={stateValue as unknown as CascaderStateContextValue}>\n <CascaderHighlightContext.Provider value={highlightStore}>\n <CascaderRenderContext.Provider value={renderContext as unknown as CascaderRenderContextValue}>\n <ComboboxPrimitive.Root\n items={renderedItems}\n /* The empty frame that resets the highlight. See the comment above. */\n filteredItems={swapping ? EMPTY : comboboxItems}\n /* Filtering is ours: the level, deep and global scopes cannot\n be expressed through Base UI's single matcher. */\n filter={null}\n value={comboboxValue}\n onValueChange={handleComboboxValueChange}\n open={open}\n onOpenChange={handleOpenChange}\n inputValue={query}\n onInputValueChange={(next: string) => setQuery(next)}\n multiple={multiple}\n disabled={disabled}\n /* Form wiring, straight to Base UI's hidden input. Conditional\n spreads: an explicit `undefined` on a controlled prop reads as\n \"deleted\" rather than \"not supplied\". */\n name={name}\n {...(form != null ? { form } : null)}\n {...(id != null ? { id } : null)}\n {...(required != null ? { required } : null)}\n {...(readOnly != null ? { readOnly } : null)}\n {...(inputRef ? { inputRef } : null)}\n inline={inline}\n /* Stops Base UI rendering its composite list, which is what makes\n an explicit row `index` legal. `items`/`filteredItems` stay full:\n they size `listRef`, or ArrowDown stops at the last RENDERED row. */\n virtualized={virtualized}\n itemToStringValue={(item: CascaderNode<T>) => item?.value ?? ''}\n itemToStringLabel={(item: CascaderNode<T>) => item?.label ?? ''}\n isItemEqualToValue={(a: CascaderNode<T>, b: CascaderNode<T>) => a?.value === b?.value}\n // Fires on every arrow key AND every pointer move, so it must\n // never call setState. The ref serves keyboard handlers, the\n // de-duping store anything that has to re-render.\n onItemHighlighted={(\n item: CascaderNode<T> | undefined,\n details: ComboboxPrimitive.Root.HighlightEventDetails,\n ) => {\n highlightedRef.current = item ?? null;\n highlightStore.set({\n index: details.index,\n value: item?.value ?? null,\n });\n // Schedules a TIMEOUT and returns: inside a layout effect, a\n // synchronous setState would cascade before paint.\n prefetchNode(item);\n }}\n >\n {children}\n </ComboboxPrimitive.Root>\n </CascaderRenderContext.Provider>\n </CascaderHighlightContext.Provider>\n </CascaderStateContext.Provider>\n </CascaderActionsContext.Provider>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Trigger */\n/* -------------------------------------------------------------------------- */\n\n/** `Trigger.Props` stops short of `ref`, so it is intersected in, as the\n * shadcn combobox wrapper also does: a form library needs a ref here, and\n * `onBlur`, the \"touched\" signal, lands here too. */\nexport interface CascaderTriggerProps\n extends ComboboxPrimitive.Trigger.Props, Pick<React.ComponentPropsWithRef<'button'>, 'ref'> {\n /** Hides the trailing chevron, for a trigger that supplies its own. */\n showIcon?: boolean;\n}\n\nfunction CascaderTrigger({ className, children, showIcon = true, ref, ...props }: CascaderTriggerProps) {\n const { invalid } = useCascaderActions();\n\n // `ref` is the one prop `mergeProps` does not merge, so chain it by hand.\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\n const setTrigger = React.useCallback(\n (node: HTMLButtonElement | null) => {\n triggerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as { current: unknown }).current = node;\n },\n [ref],\n );\n\n /** 18 of 19 audited examples shipped an unnamed combobox: the trigger's\n * contents are the field's VALUE, so a screen reader never hears its NAME.\n * Checked in the DOM, since the name may arrive as a `<label for>`. */\n React.useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n const element = triggerRef.current;\n if (!element) return;\n const named =\n element.hasAttribute('aria-label') ||\n element.hasAttribute('aria-labelledby') ||\n element.closest('label') !== null ||\n (element.id !== '' && element.ownerDocument.querySelector(`label[for=\"${CSS.escape(element.id)}\"]`) !== null);\n if (named) return;\n warnCascaderOnce(\n 'trigger-unnamed',\n \"`CascaderTrigger` has no accessible name. Its contents are the field's VALUE - they change with the selection - so a screen reader hears what is picked but never what the field is for. Pass `aria-label` or `aria-labelledby`, or reference the trigger's `id` from a `<label>`.\",\n );\n });\n\n return (\n <ComboboxPrimitive.Trigger\n ref={setTrigger}\n data-slot='cascader-trigger'\n /* Conditional spread: an explicit `undefined` would DELETE whatever a\n `Field` wrapper had already put here. */\n {...(invalid ? { 'aria-invalid': true, 'data-invalid': '' } : null)}\n className={cn(TRIGGER_ICON_FALLBACK_CLASS, className)}\n {...props}\n >\n {children}\n {showIcon ? (\n <IconPlaceholder\n lucide='ChevronDownIcon'\n tabler='IconChevronDown'\n hugeicons='ArrowDown01Icon'\n phosphor='CaretDownIcon'\n remixicon='RiArrowDownSLine'\n className={`${TRIGGER_ICON_CLASS} pointer-events-none shrink-0`}\n />\n ) : null}\n </ComboboxPrimitive.Trigger>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Resolved theme */\n/* -------------------------------------------------------------------------- */\n\n/* The eight registry styles each state a combobox surface differently, so the\n * classes below spell every one out with `style-<name>:` variants. Nothing\n * depends on ReUI's theme CSS; `build-registry` flattens one in on install. */\n\n/** Icon size for a combobox surface: 14px in mira and sera, 16px elsewhere. */\nconst TRIGGER_ICON_CLASS = 'text-muted-foreground size-4';\n\n/** The same ladder, applied only to trigger children that carry no size. */\nconst TRIGGER_ICON_FALLBACK_CLASS = \"[&_svg:not([class*='size-'])]:size-4\";\n\n/** The chips field: a form-control surface, so it carries the invalid states. */\nconst CHIPS_CLASS =\n 'flex flex-wrap items-center border bg-clip-padding dark:bg-input/30 border-input focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 bg-transparent px-2.5 text-sm focus-within:ring-3 has-aria-invalid:ring-3 min-h-8 gap-1 rounded-lg py-1 transition-colors has-data-[slot=combobox-chip]:px-1';\n\nconst CHIP_CLASS =\n 'text-foreground flex w-fit items-center justify-center gap-1 font-medium whitespace-nowrap bg-muted rounded-sm px-1.5 text-xs has-data-[slot=combobox-chip-remove]:pr-0 h-[calc(--spacing(5.25))]';\n\nconst CHIP_REMOVE_CLASS = 'opacity-50 hover:opacity-100 -ml-1';\n\n/** The floating panel's surface. The shared popup's `InputGroup` sizing is\n * left out (mirrored in `cascader-nav.tsx`), as are its `max-h-72` and\n * `min-w-*`: `CascaderContent` sets both from the positioner's variables. */\nconst CONTENT_SURFACE_CLASS =\n 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 overflow-hidden ring-1 duration-100 ring-foreground/10 shadow-md rounded-lg data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2';\n\nconst EMPTY_CLASS =\n 'text-muted-foreground hidden w-full justify-center py-2 text-center group-data-empty/combobox-content:flex text-sm';\n\n/* -------------------------------------------------------------------------- */\n/* Chips */\n/* -------------------------------------------------------------------------- */\n\n/** Ref for the chips container: they replace the trigger, so the popup has to\n * be anchored to them. Hand it to `CascaderContent`'s `anchor`. */\nexport function useCascaderAnchor() {\n return React.useRef<HTMLDivElement | null>(null);\n}\n\nexport interface CascaderChipsProps\n extends Omit<ComboboxPrimitive.Chips.Props, 'children'>, Pick<React.ComponentPropsWithRef<'div'>, 'ref'> {\n /** Shown in place of the chips when nothing is selected. */\n placeholder?: React.ReactNode;\n /**\n * How a `cascade` selection is condensed into chips. DISPLAY ONLY: the\n * stored value stays the full closure, which keeps a row's checked state an\n * O(1) lookup. `\"all\"` (default) is one chip per value, `\"parent\"` collapses\n * a fully selected branch, `\"child\"` chips only the deepest frontier.\n * Removing a condensed chip removes its whole closure and reconciles.\n */\n strategy?: CascaderCheckedStrategy;\n /** Replaces the chip list, receiving the resolved selection IN SELECTION\n * ORDER. Keep that order: Base UI removes a chip by sibling position. */\n children?: React.ReactNode | ((nodes: CascaderNode[]) => React.ReactNode);\n}\n\n/**\n * The multi-select trigger surface: one removable chip per selection, where\n * `CascaderValue` would collapse to \"3 selected\". A component rather than a\n * recipe because of three easy misses: the popup anchored to the chips, an\n * accessible name on every remove button, and labels that disambiguate when\n * two branches use the same one.\n *\n * ```tsx\n * const anchor = useCascaderAnchor()\n * <Cascader multiple items={items}>\n * <CascaderChips ref={anchor} placeholder=\"Select attributes\" />\n * <CascaderContent anchor={anchor}>...</CascaderContent>\n * </Cascader>\n * ```\n */\nfunction CascaderChips({ className, children, placeholder, strategy = 'all', ...props }: CascaderChipsProps) {\n const { labels, multiple, invalid, resolveNode, index, isSelectable, setSelection } = useCascaderActions();\n const { selectedValues } = useCascaderState();\n\n React.useEffect(() => {\n if (process.env.NODE_ENV === 'production') return;\n if (multiple) return;\n warnCascaderOnce(\n 'chips-without-multiple',\n '`CascaderChips` renders one chip per selection and there is only ever one without `multiple`. Use `CascaderValue` for a single-select trigger.',\n );\n }, [multiple]);\n\n // DERIVED display: the selection stays the full closure, the chips condense.\n const displayedValues =\n strategy === 'all' ? selectedValues : getCascaderCheckedValues(index, selectedValues, strategy);\n\n // Not memoised: one entry per SELECTION, not per row, so the pass is short.\n const nodes = displayedValues.map(resolveNode);\n const ambiguous = findAmbiguousCascaderLabels(nodes);\n\n // Removal for a CONDENSED chip: Base UI's `ChipRemove` maps a press onto the\n // STORED array, which is wrong once the chips are fewer, so this removes the\n // chip's whole subtree closure instead.\n const removeClosure = (node: CascaderNode) => {\n setSelection(applyCascadeSelection(index, selectedValues, node.value, false, isSelectable), 'deselect');\n };\n\n const content = typeof children === 'function' ? children(nodes) : children;\n\n return (\n <ComboboxPrimitive.Chips\n data-slot='cascader-chips'\n /* An unnamed `role=\"toolbar\"` announces as just \"toolbar\". */\n aria-label={labels.chipsLabel}\n /* Conditional spread: the error treatment is keyed on\n `has-aria-invalid:`, so the attribute must be absent, not empty. */\n {...(invalid ? { 'aria-invalid': true, 'data-invalid': '' } : null)}\n className={cn(CHIPS_CLASS, className)}\n {...props}\n >\n {content ??\n (nodes.length === 0 ? (\n <span data-slot='cascader-chips-placeholder' className='text-muted-foreground truncate'>\n {placeholder}\n </span>\n ) : (\n nodes.map((node) => (\n <CascaderChip\n key={node.value}\n node={node}\n showPath={ambiguous.has(node.value)}\n /* Only a condensed chip needs the remover; the default shape\n keeps Base UI's positional removal. */\n {...(strategy !== 'all' ? { onRemove: () => removeClosure(node) } : null)}\n />\n ))\n ))}\n </ComboboxPrimitive.Chips>\n );\n}\n\nexport interface CascaderChipProps extends Omit<ComboboxPrimitive.Chip.Props, 'children'> {\n node: CascaderNode;\n /** Prefix the label with its ancestor trail. */\n showPath?: boolean;\n /** Trail segments to show, the node itself included. */\n maxSegments?: number;\n /** Hides the remove button, for a read-only chip. */\n showRemove?: boolean;\n /** Replaces Base UI's positional removal for this chip (remove button and\n * Backspace/Delete). Supplied for a `strategy`-condensed chip, whose\n * position no longer maps onto the stored array. */\n onRemove?: () => void;\n /** Replaces the chip's label. The remove button is still rendered. */\n children?: React.ReactNode;\n}\n\n/** Base UI hands its chip handlers events carrying the veto hook. */\ntype CascaderChipKeyEvent = Parameters<NonNullable<ComboboxPrimitive.Chip.Props['onKeyDown']>>[0];\n\ntype CascaderChipRemoveClickEvent = Parameters<NonNullable<ComboboxPrimitive.ChipRemove.Props['onClick']>>[0];\n\n/** One chip. Removal goes through Base UI's `ChipRemove`, which reports the\n * shortened selection to the root, so it lands in the same `setSelection` as\n * every other deselection and `cascade` applies to it. */\nfunction CascaderChip({\n className,\n node,\n showPath = false,\n maxSegments = 2,\n showRemove = true,\n onRemove,\n children,\n ...props\n}: CascaderChipProps) {\n const { labels, index } = useCascaderActions();\n\n const chain = showPath ? getCascaderPath(index, node.value) : [];\n const segments = collapseCascaderPath(chain, {\n maxSegments,\n collapse: 'start',\n });\n\n const label = segments.length\n ? segments.map((segment) => (segment.type === 'node' ? segment.node.label : '…')).join(` ${labels.pathSeparator} `)\n : node.label;\n\n return (\n <ComboboxPrimitive.Chip\n data-slot='cascader-chip'\n /* Keyboard half of `onRemove`: Base UI's chip removes ITSELF by position\n on Backspace/Delete, the arithmetic a condensed chip must not use. The\n veto runs first, so the closure removal replaces it. */\n {...(onRemove\n ? {\n onKeyDown: (event: CascaderChipKeyEvent) => {\n if (event.key !== 'Backspace' && event.key !== 'Delete') return;\n event.preventBaseUIHandler();\n onRemove();\n },\n }\n : null)}\n className={cn(\n CHIP_CLASS,\n 'has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children ?? <span className='truncate'>{label}</span>}\n {showRemove ? (\n <ComboboxPrimitive.ChipRemove\n data-slot='cascader-chip-remove'\n /* Named after what the chip DISPLAYS, not the bare node label, or\n two disambiguated chips both announce \"Remove Created at\". */\n aria-label={labels.removeChip(label)}\n /* The pointer half of `onRemove`, same veto, same reason. */\n {...(onRemove\n ? {\n onClick: (event: CascaderChipRemoveClickEvent) => {\n event.preventBaseUIHandler();\n onRemove();\n },\n }\n : null)}\n className={CHIP_REMOVE_CLASS}\n >\n <IconPlaceholder\n lucide='XIcon'\n tabler='IconX'\n hugeicons='Cancel01Icon'\n phosphor='XIcon'\n remixicon='RiCloseLine'\n className='pointer-events-none'\n />\n </ComboboxPrimitive.ChipRemove>\n ) : null}\n </ComboboxPrimitive.Chip>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Content */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderContentProps\n extends\n ComboboxPrimitive.Popup.Props,\n /** Positioner surface forwarded as-is, so an unusual anchor does not force\n * a rebuild of the content stack. No `trackAnchor`: Base UI 1.5.0 has\n * none. */\n Pick<\n ComboboxPrimitive.Positioner.Props,\n | 'side'\n | 'align'\n | 'sideOffset'\n | 'alignOffset'\n | 'anchor'\n | 'collisionBoundary'\n | 'collisionPadding'\n | 'sticky'\n | 'positionMethod'\n >,\n /** Where the portal mounts, for a shadow root or a scoped stacking context. */\n Pick<ComboboxPrimitive.Portal.Props, 'container'> {}\n\n/** Portal + Positioner + floating panel. Unlike shadcn's `ComboboxContent` it\n * does NOT clamp the popup to the anchor width (a cascader panel is routinely\n * wider), but it keeps `group/combobox-content`, which `CascaderEmpty` needs. */\nfunction CascaderContent({\n className,\n side = 'bottom',\n sideOffset = 6,\n align = 'start',\n alignOffset = 0,\n anchor,\n collisionBoundary,\n collisionPadding,\n sticky,\n positionMethod,\n container,\n ref,\n ...props\n}: CascaderContentProps) {\n const { labels } = useCascaderActions();\n const popupRef = React.useRef<HTMLDivElement | null>(null);\n\n // `initialFocus` needs the popup element, and `ref` is the one prop\n // `mergeProps` does NOT merge, so it is chained by hand rather than spread.\n const setPopup = React.useCallback(\n (node: HTMLDivElement | null) => {\n popupRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as { current: unknown }).current = node;\n },\n [ref],\n );\n\n /**\n * Focus goes to the search field, where the level keys and\n * `aria-activedescendant` live. Base UI's own default agrees but is COMPUTED\n * FROM THE FIRST RENDER, when the field has not mounted, and collapses to\n * \"do not move focus\": measured, a KEYBOARD open left focus on the trigger\n * and cost two Tabs to reach the footer where a pointer open cost one.\n *\n * `initialFocus` rather than an effect, because anything scheduled alongside\n * Base UI's focus manager is a race; the field is resolved INSIDE the\n * callback, which runs after the layout effects. Touch is handed back to\n * Base UI on purpose - focusing the popup keeps the Android keyboard shut.\n */\n const initialFocus = React.useCallback((openType: string) => {\n const popup = popupRef.current;\n if (!popup) return true;\n if (openType === 'touch') return popup;\n return popup.querySelector<HTMLElement>('[data-slot=\"cascader-input\"]') ?? true;\n }, []);\n\n return (\n // Conditional spreads throughout: `mergeProps` iterates own keys, so an\n // explicit `undefined` reads as \"deleted\" rather than \"not supplied\".\n <ComboboxPrimitive.Portal {...(container !== undefined ? { container } : null)}>\n <ComboboxPrimitive.Positioner\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n anchor={anchor}\n {...(collisionBoundary !== undefined ? { collisionBoundary } : null)}\n {...(collisionPadding !== undefined ? { collisionPadding } : null)}\n {...(sticky !== undefined ? { sticky } : null)}\n {...(positionMethod !== undefined ? { positionMethod } : null)}\n className='isolate z-50'\n >\n <ComboboxPrimitive.Popup\n ref={setPopup}\n data-slot='cascader-content'\n /* Marks a menu surface for the docs design-system picker. An\n attribute, not a class, so the panel's look stays self-contained. */\n data-menu-target=''\n /* The input inside makes this a `role=\"dialog\"`, unnamed by default. */\n aria-label={labels.panelLabel}\n initialFocus={initialFocus}\n className={cn(\n CONTENT_SURFACE_CLASS,\n 'group/combobox-content relative flex max-h-(--available-height) max-w-(--available-width) min-w-(--anchor-width) origin-(--transform-origin) flex-col',\n className,\n )}\n {...props}\n />\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Panel */\n/* -------------------------------------------------------------------------- */\n\nexport type CascaderPanelProps = useRender.ComponentProps<'div'>;\n\n/**\n * The nav + list(s) + footer container, with no positioning of its own: inside\n * `CascaderContent` for the popup case, alone for the embedded one.\n *\n * `min-h-0` and `max-h-full` are load-bearing. A flex child without `min-h-0`\n * refuses to shrink below its content, which is the usual reason a scroll area\n * never scrolls - worst embedded, where no positioner publishes\n * `--available-height`. It also owns the panel's TAB ORDER: the scroll area\n * makes itself a tab stop whenever the level overflows, stranding the footer,\n * and the panel is the only ancestor of both ends of that move in BOTH shapes.\n */\nfunction CascaderPanel({ className, ...props }: CascaderPanelProps) {\n const { mode } = useCascaderActions();\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Tab' || event.defaultPrevented) return;\n // A browser-level move (Ctrl+Tab switches tabs) is never ours.\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n\n const panel = event.currentTarget;\n const target = event.target as HTMLElement | null;\n if (!target || !panel.contains(target)) return;\n\n const next = getCascaderTabTarget(panel, target, event.shiftKey);\n // Off either end: left to the browser, since focus is never trapped.\n if (!next) return;\n\n event.preventDefault();\n next.focus();\n }, []);\n\n const defaultProps = {\n 'data-slot': 'cascader-panel',\n 'data-mode': mode,\n // In `defaultProps`, not around `props.onKeyDown`: `mergeProps` chains\n // right to left, so a consumer's handler runs FIRST and can drop this one.\n 'onKeyDown': handleKeyDown,\n 'className': cn('flex max-h-full min-h-0 w-full flex-col', className),\n };\n\n return useRender({\n defaultTagName: 'div',\n render: props.render,\n props: mergeProps<'div'>(defaultProps, props),\n });\n}\n\n/* -------------------------------------------------------------------------- */\n/* List */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderListProps extends Omit<ComboboxPrimitive.List.Props, 'style'> {\n /** Applied to the OUTER shell, which owns the height, so an inline\n * `--cascader-max-height` lands where the bound can read it. Narrowed from\n * Base UI's `style`: the shell is a plain `<div>` with no list state. */\n style?: React.CSSProperties;\n /** Caps this level's height; the panel still shrinks to fit. Default 24rem. */\n maxHeight?: number | string;\n}\n\n/**\n * Scroll container for one level: pattern 3 of the house scroll reference,\n * viewport-bounded popup scroll. The height is `min()` of `--available-height`\n * (the positioner's space between anchor and viewport edge) and `maxHeight`,\n * so neither can be ignored; a fixed pixel cap alone still reserved 288px for\n * a panel opened 200px above the fold and spilled off screen, and wasted room\n * in a tall window. The four classes are shared with `CascaderColumns` and\n * live in `cascader-lib.tsx`.\n */\nfunction CascaderList({ className, style, maxHeight: maxHeightProp, ...props }: CascaderListProps) {\n const { maxHeight, mode, labels, baseId, virtualized, searchScope } = useCascaderActions();\n const { currentParent, deepResults } = useCascaderState();\n const resolved = maxHeightProp ?? maxHeight;\n // Global hits come from the whole tree, so the parent would understate them.\n const listName =\n searchScope === 'global' && deepResults ? labels.rootLevel : (currentParent?.label ?? labels.rootLevel);\n\n return (\n <div\n data-slot='cascader-list-shell'\n style={\n resolved != null\n ? ({\n ...style,\n '--cascader-max-height': typeof resolved === 'number' ? `${resolved}px` : resolved,\n } as React.CSSProperties)\n : style\n }\n className={cn('relative flex max-h-full min-h-0', CASCADER_LIST_PAD_CLASS)}\n >\n <div\n data-slot='cascader-list-bounds'\n className={cn('flex w-full min-w-0 flex-col overscroll-contain', CASCADER_LIST_HEIGHT_CLASS)}\n >\n <ScrollArea className={CASCADER_SCROLL_CLASS}>\n <ComboboxPrimitive.List\n data-slot='cascader-list'\n /* Base UI names the list nothing, so every mode shipped an unnamed\n listbox. The level's parent is the name; the root borrows one. */\n aria-label={listName}\n /* Replaces Base UI's floating id. `aria-controls` reads the live\n id, so the columns trail gets a predictable target. */\n id={`${baseId}-column-0`}\n /* NEVER a ternary ending in `undefined`: `mergeProps` iterates own\n keys, so that DELETES Base UI's `role=\"listbox\"`. */\n {...(mode === 'tree' ? { role: 'tree' as const } : null)}\n {...(virtualized ? { 'data-virtualized': true } : null)}\n className={cn(\n CASCADER_ROWS_CLASS,\n /* A windowed row is absolutely positioned, so the ROWS' box is\n the containing block, not the scrollport: it carries the\n padding the geometry is measured against. */\n virtualized && 'relative',\n className,\n )}\n {...props}\n />\n </ScrollArea>\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Empty / Loading */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderEmptyProps extends ComboboxPrimitive.Empty.Props {\n /** @deprecated Ignored: the loading surface no longer draws skeletons. They\n * promised a shape the level might not have and cost a second layout; the\n * progress lives on the branch row instead. Kept so call sites compile. */\n skeletonRows?: number;\n}\n\n/** The empty, loading and error surface, in ONE element that never unmounts.\n * `Combobox.Empty` renders whenever `filteredItems.length === 0`, as true of a\n * fetching level as of an empty one, so swapping siblings would announce \"No\n * results found.\" over every async level. Swap the CHILDREN. */\nfunction CascaderEmpty({\n className,\n children,\n // Accepted and ignored; destructured so it is never spread onto the DOM.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n skeletonRows,\n ...props\n}: CascaderEmptyProps) {\n const { labels, retryLevel } = useCascaderActions();\n const { query, path, searchState } = useCascaderState();\n // The level whose emptiness is on screen; tree always shows the root.\n const levelKey = path.length ? path[path.length - 1] : CASCADER_ROOT_KEY;\n const loadState = useCascaderLoadState(levelKey);\n const state = query.trim() ? (searchState ?? loadState) : loadState;\n\n let body: React.ReactNode = children ?? labels.empty;\n\n if (state?.error) {\n body = (\n <span data-slot='cascader-error' className='flex flex-col items-center gap-1.5'>\n <span>{labels.error}</span>\n <button\n type='button'\n data-slot='cascader-retry'\n /* A real button because this lives OUTSIDE the listbox; a focusable\n element inside a `role=\"option\"` is `nested-interactive`. */\n onClick={() => retryLevel(levelKey)}\n className='text-foreground hover:bg-accent focus-visible:ring-ring/50 rounded-md px-2 py-0.5 font-medium outline-hidden transition-colors focus-visible:ring-2'\n >\n {labels.retry}\n </button>\n </span>\n );\n } else if (state?.loading) {\n body = (\n <span data-slot='cascader-loading' className='flex w-full items-center justify-center'>\n {labels.loading}\n </span>\n );\n }\n\n return (\n <ComboboxPrimitive.Empty\n data-slot='cascader-empty'\n data-state={state?.error ? 'error' : state?.loading ? 'loading' : 'empty'}\n className={cn(EMPTY_CLASS, className)}\n /* The ONE place an explicit `undefined` is right: it DELETES Base UI's\n live region, which is wanted. `CascaderStatus` is the single one, and\n leaving this one spoke \"No results found.\" on every level swap, which\n renders one deliberately empty frame to reset the highlight. */\n role={undefined}\n aria-live={undefined}\n aria-atomic={undefined}\n {...props}\n >\n {body}\n </ComboboxPrimitive.Empty>\n );\n}\n\nexport type CascaderStatusProps = ComboboxPrimitive.Status.Props;\n\n/**\n * Polite live region for the current level and result count, which drill-down\n * otherwise hides in a visual breadcrumb. Built on `Combobox.Status` for its\n * initial-mutation marker: Safari and VoiceOver need a text change ~200ms\n * after mount before reading a polite region at all.\n */\nfunction CascaderStatus({ className, children, ...props }: CascaderStatusProps) {\n const { announcement } = useCascaderState();\n\n return (\n <ComboboxPrimitive.Status data-slot='cascader-status' className={cn('sr-only', className)} {...props}>\n {children ?? announcement}\n </ComboboxPrimitive.Status>\n );\n}\n\nexport {\n Cascader,\n CascaderTrigger,\n CascaderChip,\n CascaderChips,\n CascaderContent,\n CascaderPanel,\n CascaderList,\n CascaderEmpty,\n CascaderStatus,\n};\n\n/** Re-exported from `cascader-context.tsx`: existing import paths keep\n * working, and the row component avoids an import cycle through this file. */\nexport { createCascaderHighlightStore, useCascaderActions, useCascaderHighlight, useCascaderRender, useCascaderState };\n\nexport type {\n CascaderActionsContextValue,\n CascaderColumn,\n CascaderHighlight,\n CascaderHighlightStore,\n CascaderItemState,\n CascaderRenderContextValue,\n CascaderStateContextValue,\n};\n","import { cn } from '#lib/utils';\nimport { LoaderCircleIcon } from 'lucide-react';\n\n/** 加载指示(reui/spinner API 面:size 经 className 传);async 钻取态用。 */\nfunction Spinner({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span data-slot='spinner' className={cn('inline-flex shrink-0 items-center justify-center', className)} {...props}>\n <LoaderCircleIcon className='size-full animate-spin' />\n </span>\n );\n}\n\nexport { Spinner };\n","import { cn } from '#lib/utils';\nimport { Spinner } from '#reui/spinner';\nimport { Combobox as ComboboxPrimitive } from '@base-ui/react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport * as React from 'react';\n\nimport { useCascaderActions, useCascaderRender, useCascaderState } from './cascader-context';\nimport { getCascaderCount, getCascaderMoreParent, getCascaderPath, isCascaderMoreNode } from './cascader-lib';\nimport type { CascaderLoadState, CascaderNode } from './cascader-types';\nimport { IconPlaceholder } from './icon-placeholder';\n\n// Base UI extends its synthetic events with a handler-veto escape hatch.\ntype VetoableEvent = { preventBaseUIHandler?: () => void };\n\n/** A row press. The veto hook is optional: an `as=\"button\"` row is outside Base\n * UI's listbox and gets a plain React event. */\nexport type CascaderRowEvent = React.MouseEvent<HTMLElement> & VetoableEvent;\n\n// Each style's inline inset, as a variable: a row and its absolutely positioned\n// check have to land on the same number, in LOGICAL properties. These eight\n// numbers MIRROR the shared style sheets; keep them in step with\n// `registry/styles/style-*.css`.\nconst ROW_INSET_CLASS = '[--cascader-row-inset:6px]';\n\n// Both insets equal, for a row with no check. `!` because a consumer may not\n// import the sheets into `layer(base)`, where the class would win on order.\nconst ROW_FLUSH_CLASS = 'ps-[var(--cascader-row-inset,8px)]! pe-[var(--cascader-row-inset,8px)]!';\n\n// The same start inset plus room for the check. A flat `pr-8` is wrong in five\n// of the eight styles: 4px of slack in nova, 8px short in maia, luma and sera,\n// and no gutter at all in mira, whose check then overlaps its own label.\nconst ROW_GUTTER_CLASS = 'ps-[var(--cascader-row-inset,8px)]! pe-[calc(var(--cascader-row-inset,8px)*2_+_16px)]!';\n\n// The check's box, inset to match the row's. A physical `right-2` neither\n// mirrors under RTL nor tracks the style's inset; `right-auto` comes with the\n// logical `end-*`, because width + `left` + `right` is over-constrained.\nconst INDICATOR_CLASS =\n 'pointer-events-none absolute flex items-center justify-center size-4 end-[var(--cascader-row-inset,8px)]! rtl:right-auto!';\n\n// The row's type, gap, radius and icon size per style. No horizontal padding:\n// every row pairs this with `ROW_FLUSH_CLASS` or `ROW_GUTTER_CLASS`.\nconst ROW_THEME_CLASS =\n \"data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground [&_svg:not([class*='size-'])]:size-4 rounded-md py-1\";\n\n/**\n * The row's gap and type, per style, held apart from the rest of the theme.\n *\n * A row that pins its own gap or text size takes `ROW_SHELL_CLASS` and leaves\n * these out, because a `style-<name>:` utility is emitted AFTER the plain one\n * it would have to lose to. Not receiving the token beats overriding it with\n * `!`, which a consumer then has to fight in turn.\n */\nconst ROW_GAP_CLASS = 'gap-2';\n\nconst ROW_TEXT_CLASS = 'text-sm';\n\nconst ROW_SHELL_CLASS = `${ROW_THEME_CLASS} relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 ${ROW_INSET_CLASS}`;\n\nconst ROW_CLASS = `${ROW_SHELL_CLASS} ${ROW_GAP_CLASS} ${ROW_TEXT_CLASS}`;\n\nconst CASCADER_ACTION_INSET_CLASS = `${ROW_INSET_CLASS} ${ROW_FLUSH_CLASS}`;\n\n/** A footer COMMAND: the row theme, so it cannot drift from the list, plus the\n * hover and `focus-visible` fills a plain button never gets. Fills, never a\n * ring: a ring under rows that all paint with a fill read as a different\n * widget bolted on. `focus-visible`, not `focus`, so a pointer press does not\n * leave a command painted as if it were still hovered. Disabled keys off\n * `aria-disabled`, not `:disabled`, to keep it FOCUSABLE: a footer whose only\n * row is disabled has no tab stop. */\nexport const CASCADER_ACTION_CLASS = `${ROW_SHELL_CLASS} ${ROW_TEXT_CLASS} ${ROW_FLUSH_CLASS} hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground cursor-pointer gap-2 transition-colors aria-disabled:pointer-events-none aria-disabled:opacity-50`;\n\n// The box around the affordances that are not the row. 20px around a 16px icon,\n// the outer 2px cancelled at the call site; 24px would set the row height.\nconst AFFORDANCE_BOX_CLASS = 'flex size-5 shrink-0 items-center justify-center rounded-sm';\n\n// What makes an affordance read as pressable on an already highlighted row. Not\n// `hover:bg-accent`: the row is `bg-accent` under the pointer, so the chip would\n// be invisible. `!` and `**:` for the `CHECKBOX_MARK_CLASS` reason.\nconst AFFORDANCE_HOVER_CLASS =\n 'transition-[background-color,box-shadow,color] hover:bg-background hover:text-foreground! hover:**:text-foreground! hover:shadow-xs';\n\n// The selection MARK's colour, pinned so nothing can repaint it: every row\n// carries a DESCENDANT highlight rule, and a mark is STATE. Pinned TWICE\n// because icon sets draw with `fill`/`stroke=\"currentColor\"`, which the\n// `<path>` inherits and resolves against the PATH's own `color`. Both halves\n// are asserted in `cascader-behavior.test.tsx`.\nconst CHECKBOX_MARK_CLASS = 'text-primary-foreground! **:text-primary-foreground!';\nconst INDICATOR_MARK_CLASS = 'text-foreground! **:text-foreground!';\n\n// Milliseconds the pointer must rest on a branch row before\n// `expandTrigger=\"hover\"` drills in: long enough that a pointer crossing the\n// column on its way elsewhere opens nothing, short enough to read as immediate.\nconst CASCADER_HOVER_EXPAND_DELAY = 150;\n\nexport interface CascaderItemProps extends Omit<\n ComboboxPrimitive.Item.Props,\n 'value' | 'children' | 'className' | 'style' | 'onClick' | 'onMouseUp'\n> {\n /** No state callback: the row merges `className` and `style` itself. */\n className?: string;\n style?: React.CSSProperties;\n onClick?: (event: CascaderRowEvent) => void;\n onMouseUp?: (event: CascaderRowEvent) => void;\n node: CascaderNode;\n /** Explicit render index. Required while virtualized and DELIBERATELY IGNORED\n * otherwise: it self-registers the row and breaks `aria-activedescendant`. */\n index?: number;\n /** Indentation depth. Drives `--cascader-indent` in tree mode. */\n depth?: number;\n /** Renders the ancestor chain under the label, for deep and global search. */\n showPath?: boolean;\n /** `option` renders a real `Combobox.Item`; `button` renders identical markup\n * outside the listbox, for the ancestor columns in columns mode. */\n as?: 'option' | 'button';\n /** Tree mode: this row is an expanded branch. */\n expanded?: boolean;\n /** Indent each depth by this many pixels. Tree mode only. */\n indent?: number;\n /** Whether the node has children. Defaults to the cascader's own answer, as do\n * the three below: callers pass them because they already hold the level,\n * which keeps a memoised row off the volatile context. */\n branch?: boolean;\n /** Whether the node may be committed. Defaults to the cascader's own answer. */\n selectable?: boolean;\n /** Whether the node is currently selected. Defaults to the cascader's answer. */\n selected?: boolean;\n /** Some but not all of the loaded subtree selected. `cascade` only. */\n indeterminate?: boolean;\n /** Selected nodes below this one, at any depth. Drives the trailing count. */\n selectedCount?: number;\n /** Paging row only: a request for this level is in flight. */\n loading?: boolean;\n /** Paging row only: this level's last request failed. */\n error?: boolean;\n /** Branch row only: this node's OWN children are being fetched. The chevron\n * (or, in tree mode, the expander) becomes a spinner IN PLACE, in the same\n * 16px box: no skeleton row appears below, nothing reflows. */\n childrenLoading?: boolean;\n /** Branch row only: the last fetch of this node's children failed. The same\n * box becomes the retry. The press path is unchanged: it goes through\n * `navigate`, which refires the failed level rather than moving. */\n childrenError?: boolean;\n children?: React.ReactNode;\n}\n\n/** One row. Branch presses navigate instead of selecting, vetoed here with\n * `preventBaseUIHandler()` on `onClick` (Enter too) and on `onMouseUp`. */\nconst CascaderItem = React.memo(function CascaderItem({\n node,\n index,\n depth,\n showPath = false,\n as = 'option',\n expanded,\n indent = 16,\n branch: branchProp,\n selectable: selectableProp,\n selected: selectedProp,\n indeterminate: indeterminateProp,\n selectedCount: selectedCountProp,\n loading,\n error,\n childrenLoading = false,\n childrenError = false,\n className,\n children,\n onClick,\n onMouseUp,\n style,\n ...props\n}: CascaderItemProps) {\n // The ACTIONS context only: the state context republishes on every keystroke.\n const {\n index: treeIndex,\n mode,\n labels,\n isBranch,\n isSelectable,\n isDisabled,\n isSelected,\n isIndeterminate,\n selectedDescendantCount,\n multiple,\n branchesSelectable,\n indicator: indicatorEnabled,\n expandTrigger = 'click',\n navigate,\n navigateAt,\n toggleExpanded,\n commit,\n getState,\n virtualized,\n loadMore,\n retryLevel,\n } = useCascaderActions();\n // Render props come from an always-current context, or a closure goes stale.\n const { renderItem, renderLabel } = useCascaderRender();\n\n const branch = branchProp ?? isBranch(node);\n const selectable = selectableProp ?? isSelectable(node);\n // An ancestor's flag counts: a search hit or a revealed path can list a row\n // inside a branch nobody may open. Asked here, off the near-stable context,\n // so no new prop and only a row that re-renders pays the ancestor walk.\n const disabled = isDisabled(node);\n const selected = selectedProp ?? isSelected(node);\n // A selected node is never also partially selected (a dash in a filled box).\n const indeterminate = !selected && (indeterminateProp ?? isIndeterminate(node));\n const count = branch ? getCascaderCount(treeIndex, node) : 0;\n const nodeDepth = depth ?? treeIndex.depthOf.get(node.value) ?? 0;\n\n // O(1): the cascader publishes a map of selected-descendant counts, because a\n // row walking its own subtree is `rows x descendants`, paid every keystroke.\n const selectedDescendants = branch ? (selectedCountProp ?? selectedDescendantCount(node)) : 0;\n // `multiple` only: with a single selection the trigger, the breadcrumb and\n // the leaf's own check already say where it is, so swapping a branch's real\n // child total (\"24\") for a permanent \"1\" would trade a useful number away.\n const showsSelectedCount = multiple && selectedDescendants > 0;\n const trailingCount = showsSelectedCount ? selectedDescendants : count;\n // Shown selected or not: suppressing it under a checked branch read as data\n // loss, and the row's TWO trailing columns mean the count never has to share\n // a slot with the check.\n const showCount = trailingCount > 0;\n\n // Where a multi-select tree puts its checkbox: at the HEAD of the row, since a\n // trailing box does not follow the label stagger. Per-LIST, never per-row, or\n // the labels below an unselectable row step back out.\n const leadingCheckbox = mode === 'tree' && multiple;\n\n // Whether this row draws a MARK, and so whether it reserves the gutter one\n // needs. `|| multiple` is the scope of the opt-out: a checkbox is the\n // selection CONTROL, so `indicator={false}` is a no-op in multi-select.\n const showsIndicator = indicatorEnabled || multiple;\n\n const veto = React.useCallback((event: VetoableEvent) => {\n event.preventBaseUIHandler?.();\n }, []);\n\n const handleClick = React.useCallback(\n (event: CascaderRowEvent) => {\n onClick?.(event);\n if (disabled) return;\n if (branch && !selectable) {\n veto(event);\n navigate(node);\n }\n },\n [onClick, node, disabled, branch, selectable, veto, navigate],\n );\n\n const handleMouseUp = React.useCallback(\n (event: CascaderRowEvent) => {\n onMouseUp?.(event);\n if (disabled) return;\n if (branch && !selectable) veto(event);\n },\n [onMouseUp, disabled, branch, selectable, veto],\n );\n\n // The tree expander's own press. With `selectable=\"any\"` the row press\n // commits, and under `cascade` that selected a whole subtree while the row\n // stayed collapsed, so expanding needs its own target. `stopPropagation`\n // before the veto, so Base UI's handler never runs, and no role: nesting\n // one in `role=\"option\"` fails axe. `navigate` fetches BEFORE it opens.\n // A disabled row may still CLOSE what `expanded` opened, never open: a row\n // only a query holds open is not in `expanded`, and the toggle would add it.\n const handleExpanderClick = React.useCallback(\n (event: CascaderRowEvent) => {\n event.stopPropagation();\n veto(event);\n if (expanded) {\n if (!disabled || getState().expanded.has(node.value)) {\n toggleExpanded(node.value);\n }\n } else if (!disabled) navigate(node);\n },\n [veto, node, disabled, expanded, getState, toggleExpanded, navigate],\n );\n\n const handleExpanderMouseUp = React.useCallback(\n (event: CascaderRowEvent) => {\n // Base UI treats a drag-select mouseup as a commit; this is not one.\n event.stopPropagation();\n veto(event);\n },\n [veto],\n );\n\n const handleChevronClick = React.useCallback(\n (event: CascaderRowEvent) => {\n event.stopPropagation();\n veto(event);\n if (disabled) return;\n // `navigate` falls through to `pushLevel`, which APPENDS: right in the\n // deepest column, but from an ancestor column it duplicated the level and\n // corrupted the path. `navigateAt` rebuilds the trail from this depth.\n if (as === 'button') navigateAt(node, depth ?? 0);\n else navigate(node);\n },\n [veto, node, disabled, as, navigateAt, depth, navigate],\n );\n\n const handleChevronMouseUp = React.useCallback((event: CascaderRowEvent) => veto(event), [veto]);\n\n // Keeps focus in the search field: Base UI prevents the mousedown default for\n // option rows, and focusing a `tabindex=\"-1\"` trail row kills every key.\n const handleButtonMouseDown = React.useCallback((event: React.MouseEvent<HTMLElement>) => {\n event.preventDefault();\n }, []);\n\n const handleButtonClick = React.useCallback(\n (event: CascaderRowEvent) => {\n onClick?.(event);\n if (disabled) return;\n if (branch && !selectable) {\n // Button rows only exist in the columns trail, where `depth` is the\n // column's own depth, so navigating replaces the trail from here.\n navigateAt(node, depth ?? 0);\n return;\n }\n if (selectable) commit(node);\n },\n [onClick, node, disabled, branch, selectable, navigateAt, depth, commit],\n );\n\n // The paging row's press, never a selection, whatever `selectable` says.\n const handleMoreClick = React.useCallback(\n (event: CascaderRowEvent) => {\n onClick?.(event);\n veto(event);\n const parent = getCascaderMoreParent(node);\n if (parent == null) return;\n if (error) retryLevel(parent);\n else if (!loading) loadMore(parent);\n },\n [onClick, veto, node, error, loading, retryLevel, loadMore],\n );\n\n // `expandTrigger=\"hover\"`: resting on a BRANCH row in the ACTIVE column drills\n // in after a delay. The deepest column of columns mode only, and it never\n // commits, so a pointer crossing the panel cannot change the value.\n const hoverNavigates = expandTrigger === 'hover' && mode === 'columns' && as === 'option' && branch && !disabled;\n const hoverTimerRef = React.useRef<number | null>(null);\n\n const cancelHoverNavigate = React.useCallback(() => {\n if (hoverTimerRef.current == null) return;\n window.clearTimeout(hoverTimerRef.current);\n hoverTimerRef.current = null;\n }, []);\n\n const handleHoverPointerEnter = React.useCallback(() => {\n cancelHoverNavigate();\n hoverTimerRef.current = window.setTimeout(() => {\n hoverTimerRef.current = null;\n navigate(node);\n }, CASCADER_HOVER_EXPAND_DELAY);\n }, [cancelHoverNavigate, navigate, node]);\n\n // Drilling in demotes this column to the trail WITHOUT unmounting the row, so\n // a pending timer has to die or it fires `navigate` from an inactive column.\n React.useEffect(() => {\n if (!hoverNavigates) cancelHoverNavigate();\n }, [hoverNavigates, cancelHoverNavigate]);\n React.useEffect(() => cancelHoverNavigate, [cancelHoverNavigate]);\n\n /* ------------------------------- paging row ------------------------------ */\n\n if (isCascaderMoreNode(node)) {\n const text = error ? labels.error : loading ? (node.count ? labels.loadingMore : labels.loading) : labels.loadMore;\n\n const moreStyle =\n mode === 'tree' && nodeDepth > 0\n ? ({\n ...style,\n '--cascader-indent': `${nodeDepth * indent}px`,\n } as React.CSSProperties)\n : style;\n\n const moreShared = {\n 'data-slot': 'cascader-item',\n 'data-more': '',\n 'data-state': error ? 'error' : loading ? 'loading' : 'idle',\n 'data-depth': nodeDepth,\n 'style': moreStyle,\n 'className': cn(\n ROW_SHELL_CLASS,\n ROW_FLUSH_CLASS,\n 'text-muted-foreground justify-center gap-1.5 text-xs',\n !error && !loading && 'hover:text-foreground',\n mode === 'tree' && 'ps-[calc(var(--cascader-row-inset,8px)_+_var(--cascader-indent,0px))]!',\n className,\n ),\n };\n\n const moreBody = children ?? (\n <>\n {loading ? (\n <IconPlaceholder\n lucide='LoaderCircleIcon'\n tabler='IconLoader2'\n hugeicons='Loading02Icon'\n phosphor='CircleNotchIcon'\n remixicon='RiLoader4Line'\n className='size-3.5 animate-spin'\n aria-hidden\n />\n ) : null}\n <span>{text}</span>\n {/* TEXT, not a button: a focusable element inside a `role=\"option\"`\n row is a `nested-interactive` violation. */}\n {error ? <span className='text-foreground font-medium'>{labels.retry}</span> : null}\n </>\n );\n\n if (as === 'button') {\n const buttonProps = { ...(props as React.ComponentProps<'button'>) };\n delete buttonProps['aria-setsize'];\n delete buttonProps['aria-posinset'];\n delete buttonProps['aria-level'];\n\n return (\n <button type='button' {...moreShared} tabIndex={-1} onClick={handleMoreClick} {...buttonProps}>\n {moreBody}\n </button>\n );\n }\n\n return (\n <ComboboxPrimitive.Item\n {...moreShared}\n value={node}\n {...(virtualized && index != null ? { index } : null)}\n {...(mode === 'tree' ? { 'role': 'treeitem' as const, 'aria-level': nodeDepth + 1 } : null)}\n onClick={handleMoreClick}\n onMouseUp={veto}\n {...props}\n >\n {moreBody}\n </ComboboxPrimitive.Item>\n );\n }\n\n const itemState = {\n branch,\n selected,\n disabled,\n depth: nodeDepth,\n count,\n path: showPath ? getCascaderPath(treeIndex, node.value).slice(0, -1) : [],\n };\n\n const custom = renderItem?.(node, itemState);\n const customLabel = renderLabel?.(node, itemState);\n\n // What the markup cannot say: a branch would announce \"Person 24\", a naked\n // number. Trail rows are outside the listbox, so they need words for state.\n const srDetails = [\n branch ? labels.itemCount(count) : null,\n showsSelectedCount ? labels.selectedCount(selectedDescendants) : null,\n branch && mode !== 'tree' ? labels.branchAffordance : null,\n as === 'button' && selected ? labels.selectedState : null,\n // Option rows say this with `aria-checked=\"mixed\"`; `role=\"button\"` allows\n // neither that nor `aria-selected`, so a trail row says it in words.\n as === 'button' && indeterminate ? labels.partiallySelectedState : null,\n ]\n .filter(Boolean)\n .map((detail) => `, ${detail}`)\n .join('');\n\n // Extracted because tree mode renders it INLINE at the head of the row. It\n // reads `data-selected` off the ROW, so it also works on the trail rows.\n const checkbox = (\n <span\n data-slot='cascader-item-checkbox'\n className='border-input in-data-[selected]:bg-primary in-data-[selected]:border-primary in-data-[selected]:text-primary-foreground in-data-[indeterminate]:bg-primary in-data-[indeterminate]:border-primary in-data-[indeterminate]:text-primary-foreground flex size-4 shrink-0 items-center justify-center rounded-[4px] border transition-colors'\n >\n {/* Colour declared ON THE ICON with `!`; see `CHECKBOX_MARK_CLASS`. */}\n {indeterminate ? (\n <IconPlaceholder\n lucide='MinusIcon'\n tabler='IconMinus'\n hugeicons='MinusSignIcon'\n phosphor='MinusIcon'\n remixicon='RiSubtractLine'\n data-slot='cascader-item-dash'\n className={cn(CHECKBOX_MARK_CLASS, 'size-3')}\n />\n ) : (\n <IconPlaceholder\n lucide='CheckIcon'\n tabler='IconCheck'\n hugeicons='Tick02Icon'\n phosphor='CheckIcon'\n remixicon='RiCheckLine'\n data-slot='cascader-item-tick'\n className={cn(CHECKBOX_MARK_CLASS, 'size-3 opacity-0 in-data-[selected]:opacity-100')}\n />\n )}\n </span>\n );\n\n const indicator = (\n <>\n {multiple ? (\n checkbox\n ) : (\n <IconPlaceholder\n lucide='CheckIcon'\n tabler='IconCheck'\n hugeicons='Tick02Icon'\n phosphor='CheckIcon'\n remixicon='RiCheckLine'\n data-slot='cascader-item-check'\n className={cn('pointer-events-none', INDICATOR_MARK_CLASS)}\n />\n )}\n </>\n );\n\n const body = custom ?? children ?? (\n <>\n {/* Tree mode expands in place, so the branch marker leads the row. */}\n {mode === 'tree' && branch ? (\n <span\n data-slot='cascader-item-expander'\n /* Pure affordance: the row itself carries `aria-expanded`. */\n aria-hidden='true'\n data-state={childrenError ? 'error' : childrenLoading ? 'loading' : 'idle'}\n onClick={handleExpanderClick}\n onMouseUp={handleExpanderMouseUp}\n className={cn(\n '-ms-0.5',\n childrenError ? 'text-destructive' : 'text-muted-foreground',\n AFFORDANCE_BOX_CLASS,\n AFFORDANCE_HOVER_CLASS,\n /* A disabled row is `pointer-events-none`; only while open does its\n expander take the pointer back, to close what `expanded` opened. */\n disabled && expanded && 'pointer-events-auto',\n childrenLoading && 'pointer-events-none',\n )}\n >\n {childrenLoading ? (\n <Spinner aria-hidden='true' className='size-4' />\n ) : childrenError ? (\n <IconPlaceholder\n lucide='RotateCwIcon'\n tabler='IconRefresh'\n hugeicons='RefreshIcon'\n phosphor='ArrowClockwiseIcon'\n remixicon='RiRefreshLine'\n className='size-4'\n />\n ) : (\n <IconPlaceholder\n lucide='ChevronRightIcon'\n tabler='IconChevronRight'\n hugeicons='ArrowRight01Icon'\n phosphor='CaretRightIcon'\n remixicon='RiArrowRightSLine'\n className={cn(\n 'size-4 transition-transform',\n /* Collapsed it points INTO the level, so it mirrors; expanded\n it points DOWN, the same in both writing modes, so the mirror\n has to come off or `scaleX(-1)` composed with `rotate(90deg)`\n lands it pointing up. `rtl:rotate-90` beside `rotate-90` was\n a no-op that only looked like it handled this. */\n expanded ? 'rotate-90' : 'rtl:-scale-x-100',\n )}\n />\n )}\n </span>\n ) : mode === 'tree' ? (\n // A LEAF's expander slot, reserved and empty: without it a leaf's label\n // started 28px off its sibling branches' and read as one level up.\n <span\n data-slot='cascader-item-expander-spacer'\n aria-hidden='true'\n className={cn('-ms-0.5', AFFORDANCE_BOX_CLASS)}\n />\n ) : null}\n\n {/* Tree + multi-select: the box leads the row, and an unselectable row\n still reserves its width. */}\n {leadingCheckbox ? (\n selectable ? (\n checkbox\n ) : (\n <span data-slot='cascader-item-checkbox-spacer' aria-hidden='true' className='size-4 shrink-0' />\n )\n ) : null}\n\n {node.icon ? (\n <span\n data-slot='cascader-item-icon'\n className='text-muted-foreground flex shrink-0 items-center justify-center'\n >\n {node.icon}\n </span>\n ) : null}\n\n {/* The row box is sized for pieces side by side; this one stacks, so it\n restates the gap: 8px reads as a paragraph break, not a subtitle. */}\n <span className='flex min-w-0 flex-1 flex-col items-start gap-0.5'>\n {customLabel ?? (\n <>\n <span className='w-full truncate text-start'>{node.label}</span>\n {node.description ? (\n <span\n data-slot='cascader-item-description'\n className='text-muted-foreground w-full truncate text-start text-xs'\n >\n {node.description}\n </span>\n ) : null}\n </>\n )}\n {showPath ? <CascaderItemPath node={node} /> : null}\n </span>\n\n {/* The count is a bare number, and nothing else says a branch opens. */}\n {srDetails ? (\n <span data-slot='cascader-item-details' className='sr-only'>\n {srDetails}\n </span>\n ) : null}\n\n {/* Tree mode expands in place, so it has no drill-in chevron. */}\n {branch && mode !== 'tree' ? (\n <span\n data-slot='cascader-item-trailing'\n aria-hidden='true'\n className='text-muted-foreground ms-auto flex shrink-0 items-center gap-1 text-xs tabular-nums'\n >\n {showCount ? (\n <span\n data-slot='cascader-item-count'\n /* The marker a consumer (and a test) reads to tell the two\n numbers apart without matching on a colour class. */\n {...(showsSelectedCount ? { 'data-selected-count': '' } : null)}\n className={cn(showsSelectedCount && 'text-primary!')}\n >\n {trailingCount}\n </span>\n ) : null}\n {/* ONLY the chevron is the drill target: sharing a hit area with\n the count made a number pressable. */}\n <span\n data-slot='cascader-item-chevron'\n data-state={childrenError ? 'error' : childrenLoading ? 'loading' : 'idle'}\n onClick={selectable ? handleChevronClick : undefined}\n onMouseUp={selectable ? handleChevronMouseUp : undefined}\n onMouseDown={as === 'button' ? handleButtonMouseDown : undefined}\n className={cn(\n /* Cancels the box's outer slack, so the icon keeps its column. */\n '-me-0.5',\n AFFORDANCE_BOX_CLASS,\n selectable && AFFORDANCE_HOVER_CLASS,\n childrenError && 'text-destructive',\n childrenLoading && 'pointer-events-none',\n )}\n >\n {childrenLoading ? (\n <Spinner aria-hidden='true' className='size-4' />\n ) : childrenError ? (\n <IconPlaceholder\n lucide='RotateCwIcon'\n tabler='IconRefresh'\n hugeicons='RefreshIcon'\n phosphor='ArrowClockwiseIcon'\n remixicon='RiRefreshLine'\n className='size-4'\n />\n ) : (\n <IconPlaceholder\n lucide='ChevronRightIcon'\n tabler='IconChevronRight'\n hugeicons='ArrowRight01Icon'\n phosphor='CaretRightIcon'\n remixicon='RiArrowRightSLine'\n className='size-4 rtl:-scale-x-100'\n />\n )}\n </span>\n </span>\n ) : null}\n\n {branch && mode === 'tree' && showCount ? (\n <span\n data-slot='cascader-item-count'\n {...(showsSelectedCount ? { 'data-selected-count': '' } : null)}\n /* The count is spoken by the sr-only details span instead. */\n aria-hidden='true'\n className={cn(\n 'text-muted-foreground ms-auto shrink-0 text-xs tabular-nums',\n showsSelectedCount && 'text-primary!',\n )}\n >\n {trailingCount}\n </span>\n ) : null}\n\n {/* No trailing indicator when a tree's box led the row, or when\n `indicator={false}` opted out. See `showsIndicator`. */}\n {selectable && !leadingCheckbox && showsIndicator ? (\n as === 'button' ? (\n // No ItemIndicator outside Base UI: `data-selected` drives it.\n (multiple || selected) && (\n <span data-slot='cascader-item-indicator' className={INDICATOR_CLASS}>\n {indicator}\n </span>\n )\n ) : (\n <ComboboxPrimitive.ItemIndicator\n /* Kept mounted for a partial selection too: the row is not\n selected, so Base UI would unmount the box the dash lives in. */\n keepMounted={multiple || indeterminate}\n render={<span data-slot='cascader-item-indicator' className={INDICATOR_CLASS} />}\n >\n {indicator}\n </ComboboxPrimitive.ItemIndicator>\n )\n ) : null}\n </>\n );\n\n const rowStyle =\n mode === 'tree' && nodeDepth > 0\n ? ({\n ...style,\n '--cascader-indent': `${nodeDepth * indent}px`,\n } as React.CSSProperties)\n : style;\n\n const shared = {\n 'data-slot': 'cascader-item',\n 'data-branch': branch || undefined,\n 'data-selected': selected || undefined,\n 'data-indeterminate': indeterminate || undefined,\n 'data-depth': nodeDepth,\n 'data-expanded': expanded || undefined,\n // No `aria-level`: `role=\"option\"` allows only `aria-selected`,\n // `aria-checked`, `aria-posinset` and `aria-setsize`, and a `role=\"button\"`\n // trail row allows none of the four. Only tree mode has a role that takes a\n // level, and it adds one below.\n 'style': rowStyle,\n 'className': cn(\n ROW_CLASS,\n /* Three separate reasons to hand the check gutter back. A multi-select\n tree's box leads the row, so the gutter would be 24px of dead space;\n `indicator={false}` drops the check, and keeping the gutter would park\n the count and the chevron one gutter in from an edge nothing sits on;\n and for branches the question is per-LIST, not per-row, because the old\n `branch && !selectable` put neighbouring chevrons on 24px and 6px in\n nova. One `pe-*` is emitted either way, so nothing here depends on\n class-merge order. */\n leadingCheckbox || !showsIndicator || (branch && !branchesSelectable) ? ROW_FLUSH_CLASS : ROW_GUTTER_CLASS,\n /* ADDED to the style's own inset, never substituted: replacing it put\n depth 0 at 12px and depth 1 at 16px in maia, luma and sera, a 4px step.\n `_+_` because Tailwind's parser splits on whitespace. */\n mode === 'tree' && 'ps-[calc(var(--cascader-row-inset,8px)_+_var(--cascader-indent,0px))]!',\n className,\n ),\n };\n\n if (as === 'button') {\n const buttonProps = { ...(props as React.ComponentProps<'button'>) };\n // `role=\"button\"` allows none of these, so they are dropped, not passed.\n delete buttonProps['aria-setsize'];\n delete buttonProps['aria-posinset'];\n delete buttonProps['aria-level'];\n\n return (\n <button\n type='button'\n {...shared}\n /* Focus stays in the search input; the trail uses ArrowLeft. */\n tabIndex={-1}\n disabled={disabled}\n aria-disabled={disabled || undefined}\n onClick={handleButtonClick}\n onMouseDown={handleButtonMouseDown}\n {...buttonProps}\n >\n {body}\n </button>\n );\n }\n\n return (\n <ComboboxPrimitive.Item\n {...shared}\n value={node}\n /* THE one gate for the explicit index: supply one outside virtualized mode\n and the first arrow key leaves `aria-activedescendant` pointing at\n nothing. */\n {...(virtualized && index != null ? { index } : null)}\n disabled={disabled}\n /* Conditional spread, never `role={... : undefined}`: `mergeProps`\n iterates own keys, so `undefined` would delete `role=\"option\"`. */\n {...(mode === 'tree'\n ? {\n 'role': 'treeitem' as const,\n 'aria-level': nodeDepth + 1,\n ...(branch ? { 'aria-expanded': !!expanded } : null),\n }\n : branch\n ? { 'aria-haspopup': 'listbox' as const }\n : null)}\n /* Only ever `mixed`: a selected row already says so with `aria-selected`,\n and two selection attributes on one row is noise. */\n {...(indeterminate ? { 'aria-checked': 'mixed' as const } : null)}\n {...(hoverNavigates\n ? {\n onPointerEnter: handleHoverPointerEnter,\n onPointerLeave: cancelHoverNavigate,\n }\n : null)}\n onClick={handleClick}\n onMouseUp={handleMouseUp}\n {...props}\n >\n {body}\n </ComboboxPrimitive.Item>\n );\n});\n\n/** Ancestor chain under a deep or global hit: \"Name\" alone is ambiguous. */\nfunction CascaderItemPath({ node }: { node: CascaderNode }) {\n const { index, labels } = useCascaderActions();\n const ancestors = getCascaderPath(index, node.value).slice(0, -1);\n if (!ancestors.length) return null;\n\n return (\n <span\n data-slot='cascader-item-path'\n className='text-muted-foreground flex w-full items-center gap-0.5 truncate text-start text-xs'\n >\n {ancestors.map((ancestor, i) => (\n <React.Fragment key={ancestor.value}>\n {i > 0 ? <span aria-hidden='true'>{labels.pathSeparator}</span> : null}\n <span className='truncate'>{ancestor.label}</span>\n </React.Fragment>\n ))}\n </span>\n );\n}\n\n/** Every load-derived prop a row needs. A PAGING row reports the level it\n * belongs to, a BRANCH row the level it OWNS; mutually exclusive, so one call\n * answers both. Exported because a memoised row cannot read them itself. */\nexport function getCascaderMoreProps(\n node: CascaderNode,\n loadStates: ReadonlyMap<string, CascaderLoadState>,\n): {\n loading: boolean;\n error: boolean;\n childrenLoading: boolean;\n childrenError: boolean;\n} {\n const parent = getCascaderMoreParent(node);\n if (parent == null) {\n const own = loadStates.get(node.value);\n return {\n loading: false,\n error: false,\n childrenLoading: !!own?.loading,\n childrenError: !!own?.error,\n };\n }\n const state = loadStates.get(parent);\n return {\n loading: !!state?.loading,\n error: !!state?.error,\n childrenLoading: false,\n childrenError: false,\n };\n}\n\nexport interface CascaderItemsProps {\n /** Replaces the default row for every item. */\n children?: (node: CascaderNode, index: number) => React.ReactNode;\n}\n\n/** Whatever the active view is: the current level, the deepest column, or the\n * flattened tree rows. Lives here so `cascader.tsx` never imports a row\n * component, which would cycle with the context. `index` is deliberately not\n * passed; see `CascaderItemProps`. */\nfunction CascaderItems({ children }: CascaderItemsProps) {\n const { mode, isBranch, isSelectable, isSelected, isIndeterminate } = useCascaderActions();\n const { renderedItems, deepResults, treeRows, loadStates } = useCascaderState();\n const showPath = deepResults !== null;\n\n // Answered once here, as plain booleans, so `React.memo` can skip a row.\n if (mode === 'tree') {\n return (\n <>\n {treeRows.map((row, i) =>\n children ? (\n <React.Fragment key={row.node.value}>{children(row.node, i)}</React.Fragment>\n ) : (\n <CascaderItem\n key={row.node.value}\n node={row.node}\n depth={row.depth}\n expanded={row.expanded}\n branch={row.branch}\n selectable={isSelectable(row.node)}\n selected={isSelected(row.node)}\n indeterminate={isIndeterminate(row.node)}\n {...getCascaderMoreProps(row.node, loadStates)}\n aria-setsize={row.setSize}\n aria-posinset={row.posInSet}\n />\n ),\n )}\n </>\n );\n }\n\n return (\n <>\n {renderedItems.map((node, i) =>\n children ? (\n <React.Fragment key={node.value}>{children(node, i)}</React.Fragment>\n ) : (\n <CascaderItem\n key={node.value}\n node={node}\n showPath={showPath}\n branch={isBranch(node)}\n selectable={isSelectable(node)}\n selected={isSelected(node)}\n indeterminate={isIndeterminate(node)}\n {...getCascaderMoreProps(node, loadStates)}\n aria-setsize={renderedItems.length}\n aria-posinset={i + 1}\n />\n ),\n )}\n </>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Group / Label / Separator */\n/* -------------------------------------------------------------------------- */\n\n// Whether a `CascaderLabel` has a group to name: Base UI's `Combobox.GroupLabel`\n// THROWS when there is none, and a heading is useful outside a group.\nconst CascaderGroupContext = React.createContext(false);\n\n// A heading over a run of rows. All eight styles are spelled out because the\n// type is not uniform (sera is uppercase), and the inset is the row's own.\nconst CASCADER_LABEL_CLASS = `text-muted-foreground text-xs py-1.5 ${CASCADER_ACTION_INSET_CLASS} block truncate`;\n\n// A rule between two runs. The inline margin is not the combobox separator's:\n// that cancels the container's padding with a per-style number, wrong in a\n// footer and 4px too much in lyra. `--cascader-list-pad` reaches the edge.\nconst CASCADER_SEPARATOR_CLASS = 'h-px bg-border my-1 mx-[calc(var(--cascader-list-pad,4px)*-1)]! shrink-0';\n\nexport interface CascaderGroupProps extends Omit<ComboboxPrimitive.Group.Props, 'className'> {\n /** Base UI also accepts a state callback here; the group has no state. */\n className?: string;\n}\n\n/** A run of related rows, named by the `CascaderLabel` inside it: the group is\n * `role=\"group\"` and Base UI points its `aria-labelledby` at the label, where a\n * heading alone inside a listbox is dropped from the accessibility tree.\n * Grouping is composition, not data: `CascaderItems` renders one flat run per\n * level, so its indices line up with `listRef`. */\nfunction CascaderGroup({ className, ...props }: CascaderGroupProps) {\n return (\n <CascaderGroupContext.Provider value={true}>\n <ComboboxPrimitive.Group data-slot='cascader-group' className={cn('flex flex-col', className)} {...props} />\n </CascaderGroupContext.Provider>\n );\n}\n\nexport interface CascaderLabelProps extends Omit<ComboboxPrimitive.GroupLabel.Props, 'className' | 'style'> {\n /** No state callback; outside a group this is not a Base UI part at all. */\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Inside a group: the real thing, with the id association Base UI wires up. */\nfunction CascaderGroupLabel({ className, ...props }: CascaderLabelProps) {\n return (\n <ComboboxPrimitive.GroupLabel\n data-slot='cascader-label'\n className={cn(CASCADER_LABEL_CLASS, className)}\n {...props}\n />\n );\n}\n\n// Outside a group: the same heading as a plain element. A separate component\n// rather than a branch, so the hook count cannot change when a label moves in.\nfunction CascaderPlainLabel({ className, ...props }: CascaderLabelProps) {\n const defaultProps = {\n 'data-slot': 'cascader-label',\n 'className': cn(CASCADER_LABEL_CLASS, className),\n };\n\n return useRender({\n defaultTagName: 'div',\n render: props.render,\n props: mergeProps<'div'>(defaultProps, props),\n });\n}\n\n/** A heading. Inside `CascaderGroup` it is the group's accessible name; outside\n * one (the footer flyout is a menu, not a listbox) it is decoration only. */\nfunction CascaderLabel(props: CascaderLabelProps) {\n const grouped = React.useContext(CascaderGroupContext);\n return grouped ? <CascaderGroupLabel {...props} /> : <CascaderPlainLabel {...props} />;\n}\n\nexport interface CascaderSeparatorProps extends Omit<ComboboxPrimitive.Separator.Props, 'className'> {\n /** Base UI also accepts a state callback here; only the orientation varies. */\n className?: string;\n}\n\n/** Decorative on purpose: Base UI's separator is `role=\"separator\"`, which a\n * `listbox` may not own, and a run that needs separating for a screen reader\n * needs a `CascaderGroup`, not a line. A consumer can pass the role back. */\nfunction CascaderSeparator({ className, ...props }: CascaderSeparatorProps) {\n return (\n <ComboboxPrimitive.Separator\n data-slot='cascader-separator'\n role='presentation'\n aria-hidden='true'\n className={cn(CASCADER_SEPARATOR_CLASS, className)}\n {...props}\n />\n );\n}\n\nexport { CascaderGroup, CascaderItem, CascaderItems, CascaderLabel, CascaderSeparator };\n","import { cn } from '#lib/utils';\nimport { Combobox as ComboboxPrimitive } from '@base-ui/react';\nimport { useDirection } from '@base-ui/react/direction-provider';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport * as React from 'react';\n\nimport { useCascaderActions, useCascaderState } from './cascader-context';\nimport { resolveCascaderSearchLabel } from './cascader-i18n';\nimport { collapseCascaderPath, getCascaderFooterStops, getCascaderPath, isCascaderRtl } from './cascader-lib';\nimport type { CascaderCollapse, CascaderNode, CascaderValueDisplay } from './cascader-types';\nimport { IconPlaceholder } from './icon-placeholder';\n\n/* -------------------------------------------------------------------------- */\n/* Separator */\n/* -------------------------------------------------------------------------- */\n\nfunction PathChevron() {\n return (\n <IconPlaceholder\n lucide='ChevronRightIcon'\n tabler='IconChevronRight'\n hugeicons='ArrowRight01Icon'\n phosphor='CaretRightIcon'\n remixicon='RiArrowRightSLine'\n className='size-3 shrink-0 opacity-50 rtl:-scale-x-100'\n />\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Nav */\n/* -------------------------------------------------------------------------- */\n\nexport type CascaderNavProps = useRender.ComponentProps<'div'>;\n\n/**\n * Header: back control, search input, and the separator under them. The\n * breadcrumb belongs with the list below: it describes the rows, not the field.\n */\nfunction CascaderNav({ className, ...props }: CascaderNavProps) {\n const defaultProps = {\n 'data-slot': 'cascader-nav',\n 'className': cn(\n // `py-1`, not `py-1.5`: the row inside sets its own per-style height, so\n // even padding read too tall. 6px beside the field, 4px above and below.\n 'border-border/60 flex shrink-0 flex-col gap-1 border-b px-1.5 py-1',\n className,\n ),\n };\n\n return useRender({\n defaultTagName: 'div',\n render: props.render,\n props: mergeProps<'div'>(defaultProps, props),\n });\n}\n\n/* -------------------------------------------------------------------------- */\n/* Back */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderBackProps extends Omit<useRender.ComponentProps<'button'>, 'children'> {\n children?: React.ReactNode;\n}\n\n/** Pops one level. Renders nothing at the root, so no dead header space. */\nfunction CascaderBack({ className, children, ...props }: CascaderBackProps) {\n const { popLevel, labels, mode } = useCascaderActions();\n const { path } = useCascaderState();\n\n // Checked after `useRender`, never before it: an early return would change\n // the hook count between the root level and any deeper one.\n const hidden = mode !== 'drill' || path.length === 0;\n\n const defaultProps = {\n 'data-slot': 'cascader-back',\n 'type': 'button' as const,\n 'aria-label': labels.back,\n 'onClick': () => popLevel(),\n 'className': cn(\n 'text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/50 flex shrink-0 items-center justify-center rounded-md outline-hidden transition-colors focus-visible:ring-2',\n // A notch under the row height: an affordance, not a second field.\n 'size-6',\n className,\n ),\n 'children': children ?? (\n <IconPlaceholder\n lucide='ChevronLeftIcon'\n tabler='IconChevronLeft'\n hugeicons='ArrowLeft01Icon'\n phosphor='CaretLeftIcon'\n remixicon='RiArrowLeftSLine'\n className='size-4 rtl:-scale-x-100'\n />\n ),\n };\n\n const element = useRender({\n defaultTagName: 'button',\n render: props.render,\n props: mergeProps<'button'>(defaultProps, props),\n });\n\n return hidden ? null : element;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Breadcrumb */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderBreadcrumbProps extends Omit<useRender.ComponentProps<'nav'>, 'children'> {\n /** Maximum visible node segments before the middle collapses. */\n maxSegments?: number;\n collapse?: CascaderCollapse;\n /** Clicking a segment navigates back to that level. Defaults to true. */\n interactive?: boolean;\n}\n\n/**\n * Compact trail of the current level AND its ancestors, collapsed by the same\n * helper as `CascaderValue` so panel and trigger cannot disagree. The current\n * level IS the last crumb: dropping it read as a rendering bug, a trail naming\n * only the places you are not.\n */\nfunction CascaderBreadcrumb({\n className,\n maxSegments = 3,\n collapse = 'middle',\n interactive = true,\n ...props\n}: CascaderBreadcrumbProps) {\n const { goToDepth, mode, labels } = useCascaderActions();\n const { path, index } = useCascaderState();\n\n // The WHOLE path, current level included; unresolvable entries drop out.\n const nodes = path.map((value) => index.byValue.get(value)).filter(Boolean) as CascaderNode[];\n const segments = collapseCascaderPath(nodes, { maxSegments, collapse });\n // `collapseCascaderPath` never collapses the last node away, so this is\n // always the final segment - derived rather than assumed, so a `collapse`\n // mode that ever changes that cannot mark an ancestor as the current page.\n const currentValue = nodes.length ? nodes[nodes.length - 1].value : null;\n\n // See `CascaderBack`: the hide check must not short-circuit past `useRender`.\n const hidden = mode !== 'drill' || nodes.length === 0;\n\n const goTo = (node: CascaderNode) => {\n const depth = path.indexOf(node.value);\n if (depth < 0) return;\n // `goToDepth`, not a bare `setPath`: it reports `reason: \"breadcrumb\"`,\n // clears the query and drops any pending navigation.\n goToDepth(depth + 1);\n };\n\n const defaultProps = {\n 'data-slot': 'cascader-breadcrumb',\n 'aria-label': labels.breadcrumbLabel,\n 'className': cn(\n 'text-muted-foreground flex min-w-0 shrink-0 items-center gap-0.5 pt-1.5 pb-0.5 text-xs',\n // Lines up with the ROWS, not the header: each style's list padding plus\n // its row inset. vega/mira/rhea `p-1`+`pl-2`, nova `p-1`+`pl-1.5`, maia\n // `p-1`+`pl-3`, lyra `pl-2`, luma/sera `p-1.5`+`pl-3`, per style-*.css.\n 'px-2.5',\n className,\n ),\n 'children': segments.map((segment, i) => (\n <React.Fragment key={segment.type === 'node' ? segment.node.value : `gap-${i}`}>\n {i > 0 ? <PathChevron /> : null}\n {segment.type === 'ellipsis' ? (\n <span\n data-slot='cascader-breadcrumb-ellipsis'\n title={segment.hidden.map((n) => n.label).join(` ${labels.pathSeparator} `)}\n className='shrink-0'\n >\n …\n </span>\n ) : interactive && segment.node.value !== currentValue ? (\n <button\n type='button'\n data-slot='cascader-breadcrumb-item'\n onClick={() => goTo(segment.node)}\n className='hover:text-foreground focus-visible:ring-ring/50 max-w-32 truncate rounded-sm outline-hidden transition-colors focus-visible:ring-2'\n >\n {segment.node.label}\n </button>\n ) : (\n <span\n data-slot='cascader-breadcrumb-item'\n /* The level on screen: a span because it goes nowhere, plus\n `aria-current=\"page\"` so it is not read as one of a flat list. */\n {...(segment.node.value === currentValue ? { 'aria-current': 'page' as const } : null)}\n className={cn('max-w-32 truncate', segment.node.value === currentValue && 'text-foreground font-medium')}\n >\n {segment.node.label}\n </span>\n )}\n </React.Fragment>\n )),\n };\n\n const element = useRender({\n defaultTagName: 'nav',\n render: props.render,\n props: mergeProps<'nav'>(defaultProps, props),\n });\n\n return hidden ? null : element;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Input */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderInputProps extends ComboboxPrimitive.Input.Props {\n /** Renders the back control inline, before the field. Defaults to true. */\n showBack?: boolean;\n}\n\n/** Base UI hands its input handlers an event carrying the veto hook. */\ntype CascaderInputKeyEvent = Parameters<NonNullable<ComboboxPrimitive.Input.Props['onKeyDown']>>[0];\n\n/**\n * Search field. MUST render inside the positioner: only there does Base UI skip\n * the refill from the committed selection that would fight every level swap.\n */\nfunction CascaderInput({\n className,\n showBack = true,\n placeholder,\n onKeyDown,\n 'aria-describedby': ariaDescribedBy,\n ...props\n}: CascaderInputProps) {\n const {\n labels,\n popLevel,\n mode,\n getHighlighted,\n isBranch,\n isDisabled,\n navigate,\n index,\n toggleExpanded,\n inline,\n invalid,\n baseId,\n searchScope,\n } = useCascaderActions();\n const direction = useDirection();\n const { currentParent, query, path, expanded, renderedItems, treeRows } = useCascaderState();\n\n // Root wording under a global search: naming the level on screen would\n // promise a narrower search than the one that runs.\n const resolvedPlaceholder =\n placeholder ?? resolveCascaderSearchLabel(labels, searchScope === 'global' ? undefined : currentParent?.label);\n\n // Not `showBack`: `CascaderBack` renders nothing at the root or outside\n // drill mode, where the field's own leading `px-1.5` is wanted. Beside the\n // button it stacks with the row's `gap-1` into a 10px hole, hence `ps-0`.\n const backVisible = showBack && mode === 'drill' && path.length > 0;\n\n const hintId = `${baseId}-hint`;\n // Base UI names no list while inline; columns mode moves the real listbox to\n // the deepest panel, which is the `path.length` one.\n const listId = `${baseId}-column-${mode === 'columns' ? path.length : 0}`;\n\n // The direction the HINT is worded for. `handleKeyDown` re-reads\n // `isCascaderRtl` per keystroke; this is text on screen before any key, so\n // the same check runs once against the mounted DOM (on the hint span, so no\n // second ref into Base UI's input). SSR renders the \"ltr\" default and\n // corrects on hydration. `direction` is the only dep: a `dir` attribute and\n // the stylesheet are declarations, not state, so nothing to resubscribe to.\n const hintRef = React.useRef<HTMLSpanElement>(null);\n const [hintDir, setHintDir] = React.useState<'ltr' | 'rtl'>('ltr');\n React.useLayoutEffect(() => {\n const hint = hintRef.current;\n if (!hint) return;\n setHintDir(isCascaderRtl(hint, direction) ? 'rtl' : 'ltr');\n }, [direction]);\n\n /**\n * Moves the highlight to `targetIndex` in `treeRows`. Base UI has no\n * imperative setter (`actionsRef` is `{ unmount }`), so the move is arrow\n * presses, sound only because `useListNavigation` fires `onItemHighlighted`\n * SYNCHRONOUSLY per keydown. A press that fails to close the gap ends it.\n */\n const moveHighlightTo = (field: HTMLInputElement, targetIndex: number) => {\n const rowIndex = () => {\n const highlighted = getHighlighted();\n if (!highlighted) return -1;\n return treeRows.findIndex((row) => row.node.value === highlighted.value);\n };\n\n let current = rowIndex();\n for (let step = 0; step < treeRows.length; step += 1) {\n if (current === -1 || current === targetIndex) return;\n const key = current > targetIndex ? 'ArrowUp' : 'ArrowDown';\n field.dispatchEvent(new KeyboardEvent('keydown', { key, bubbles: true, cancelable: true }));\n const next = rowIndex();\n const progressed =\n key === 'ArrowUp' ? next < current && next >= targetIndex : next > current && next <= targetIndex;\n if (next === -1 || !progressed) return;\n current = next;\n }\n };\n\n /**\n * The tree pattern's two level keys; Base UI leaves both alone (list\n * navigation is vertical-only, the chip handler no-ops without\n * `Combobox.Chips`). Passed in rather than hardcoded because RTL swaps them:\n * APG defines them as \"toward the children\", not as a physical arrow.\n */\n const handleTreeKeyDown = (\n event: CascaderInputKeyEvent,\n field: HTMLInputElement,\n caretAtStart: boolean,\n caretAtEnd: boolean,\n forwardKey: 'ArrowLeft' | 'ArrowRight',\n backKey: 'ArrowLeft' | 'ArrowRight',\n ) => {\n const forward = event.key === forwardKey;\n if (!forward && event.key !== backKey) return;\n if (forward ? !caretAtEnd : !caretAtStart) return;\n\n const highlighted = getHighlighted();\n if (!highlighted) return;\n const rowIndex = treeRows.findIndex((row) => row.node.value === highlighted.value);\n if (rowIndex < 0) return;\n const row = treeRows[rowIndex];\n\n if (forward) {\n if (!row.branch) return;\n event.preventDefault();\n if (!row.expanded) {\n // `navigate`, not `toggleExpanded`: it waits for an unloaded branch's\n // children, so the keyboard path in matches the expander.\n navigate(row.node);\n return;\n }\n // `flattenCascaderTree` emits children right after their parent, so the\n // first child is the next row. The depth check covers an empty branch.\n const child = treeRows[rowIndex + 1];\n if (child && child.depth === row.depth + 1) {\n moveHighlightTo(field, rowIndex + 1);\n }\n return;\n }\n\n // A query holds every hit's ancestors open without adding them to\n // `expanded`, so the toggle would ADD such a row: it would open a disabled\n // one for good. That row moves to its parent instead, as a closed one does.\n const heldByQuery = isDisabled(row.node) && !expanded.has(row.node.value);\n if (row.branch && row.expanded && !heldByQuery) {\n event.preventDefault();\n toggleExpanded(row.node.value);\n return;\n }\n\n const parentValue = index.parentOf.get(row.node.value);\n if (!parentValue) return;\n const parentIndex = treeRows.findIndex((entry) => entry.node.value === parentValue);\n if (parentIndex < 0) return;\n event.preventDefault();\n moveHighlightTo(field, parentIndex);\n };\n\n const handleKeyDown = (event: CascaderInputKeyEvent) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n\n const field = event.currentTarget;\n const caretAtStart = field.selectionStart === 0 && field.selectionEnd === 0;\n const caretAtEnd = field.selectionStart === query.length && field.selectionEnd === query.length;\n\n // ArrowDown at the END of the list hands real focus to the pinned footer,\n // the key a combobox is actually navigated with; Tab still works and still\n // skips the scroll area. An EMPTY list hands off at once, and the footer\n // owns the way back. Counted from state, so a windowed list still answers.\n if (event.key === 'ArrowDown' && !event.altKey) {\n const rowCount = mode === 'tree' ? treeRows.length : renderedItems.length;\n const lastValue = mode === 'tree' ? treeRows[rowCount - 1]?.node.value : renderedItems[rowCount - 1]?.value;\n const highlighted = getHighlighted();\n const atEnd = rowCount === 0 || (highlighted != null && highlighted.value === lastValue);\n if (atEnd) {\n const panel = field.closest<HTMLElement>('[data-slot=\"cascader-panel\"]');\n const stop = panel ? getCascaderFooterStops(panel)[0] : undefined;\n if (stop) {\n event.preventDefault();\n // Base UI's handler is deliberately NOT vetoed: its wrap's first\n // press CLEARS the highlight, so no stale row stays active behind the\n // focused command, and the emptied highlight completes the ring.\n stop.focus();\n return;\n }\n }\n }\n\n // The level keys are LOGICAL, not physical: in RTL, ArrowLeft opens a\n // branch and ArrowRight goes back. They act only at the caret edge, and\n // those guards do NOT mirror: `selectionStart === 0` is the logical start.\n const rtl = isCascaderRtl(field, direction);\n const forwardKey = rtl ? 'ArrowLeft' : 'ArrowRight';\n const backKey = rtl ? 'ArrowRight' : 'ArrowLeft';\n\n if (mode === 'tree') {\n handleTreeKeyDown(event, field, caretAtStart, caretAtEnd, forwardKey, backKey);\n return;\n }\n\n if (event.key === forwardKey && caretAtEnd) {\n const highlighted = getHighlighted();\n if (highlighted && isBranch(highlighted)) {\n event.preventDefault();\n navigate(highlighted);\n return;\n }\n }\n\n // Backspace on an empty query pops a level too, so the keyboard way out of\n // a level is symmetric with typing into it.\n if ((event.key === backKey && caretAtStart) || (event.key === 'Backspace' && query.length === 0)) {\n if (path.length > 0) {\n event.preventDefault();\n popLevel();\n }\n }\n };\n\n return (\n <div\n data-slot='cascader-input-row'\n className={cn(\n 'flex shrink-0 items-center gap-1',\n /* Each style sizes a combobox search field only as a DIRECT child of\n the popup; this row is nested, so the ladder is mirrored here rather\n than hardcoding one height for all eight styles. */\n 'h-8',\n )}\n >\n {showBack ? <CascaderBack /> : null}\n <ComboboxPrimitive.Input\n data-slot='cascader-input'\n placeholder={resolvedPlaceholder}\n onKeyDown={handleKeyDown}\n /* Nothing on screen says the level keys exist. */\n aria-describedby={[ariaDescribedBy, hintId].filter(Boolean).join(' ')}\n /* Conditional: an explicit `undefined` deletes Base UI's own value. */\n {...(mode === 'tree' ? { 'aria-haspopup': 'tree' as const } : null)}\n /* Base UI omits BOTH `aria-expanded` and `aria-controls` while inline,\n and an embedded panel is permanently expanded, so supply both. */\n {...(inline ? { 'aria-expanded': true, 'aria-controls': listId } : null)}\n /* No trigger to carry the invalid state in the `inline` case. */\n {...(invalid ? { 'aria-invalid': true, 'data-invalid': '' } : null)}\n className={cn(\n 'placeholder:text-muted-foreground h-full w-full min-w-0 flex-1 bg-transparent px-1.5 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n backVisible && 'ps-0',\n className,\n )}\n {...props}\n />\n <span id={hintId} ref={hintRef} className='sr-only'>\n {/* `hintDir`, not `direction`: the context alone misses an RTL app that\n uses a `dir` attribute instead of `DirectionProvider`. */}\n {labels.keyboardHint(mode, hintDir)}\n </span>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Value */\n/* -------------------------------------------------------------------------- */\n\nexport interface CascaderValueProps extends Omit<useRender.ComponentProps<'span'>, 'children'> {\n /** `path` shows the full trail, `leaf` only the node, `count` only a total. */\n display?: CascaderValueDisplay;\n maxSegments?: number;\n collapse?: CascaderCollapse;\n separator?: React.ReactNode;\n /** Renders the selected node's icon before the trail. */\n showIcon?: boolean;\n placeholder?: React.ReactNode;\n /** Replaces the whole rendering. Receives the resolved selection and path. */\n children?: (selected: CascaderNode[], path: CascaderNode[]) => React.ReactNode;\n}\n\n/**\n * Trigger display. Defaults to the collapsed selection path rather than a bare\n * leaf label, which in a nested picker is frequently ambiguous.\n */\nfunction CascaderValue({\n className,\n display = 'path',\n maxSegments = 3,\n collapse = 'middle',\n separator,\n showIcon = true,\n placeholder,\n children,\n ...props\n}: CascaderValueProps) {\n const { labels, multiple, resolveNode } = useCascaderActions();\n const { index, selectedValues } = useCascaderState();\n\n // `resolveNode`, not `index.byValue`: a selection missing from `items` (async\n // children, a removed item) must still render a label, not an empty trigger.\n const selected = selectedValues.map(resolveNode);\n\n const resolvedPath = selectedValues.length === 1 ? getCascaderPath(index, selectedValues[0]) : [];\n // No ancestor chain: fall back to the node so `display=\"path\"` shows a leaf.\n const path = resolvedPath.length > 0 ? resolvedPath : selected.length === 1 ? selected : [];\n\n let content: React.ReactNode;\n\n if (children) {\n content = children(selected, path);\n } else if (selectedValues.length === 0) {\n content = <span className='text-muted-foreground truncate'>{placeholder}</span>;\n } else if (display === 'count' || (multiple && selectedValues.length > 1)) {\n content = labels.selectedCount(selectedValues.length);\n } else {\n const leaf = path[path.length - 1] ?? selected[0];\n const segments =\n display === 'leaf'\n ? [{ type: 'node' as const, node: leaf }]\n : collapseCascaderPath(path, { maxSegments, collapse });\n\n content = (\n <>\n {showIcon && leaf?.icon ? (\n <span data-slot='cascader-value-icon' className='text-muted-foreground flex shrink-0 items-center'>\n {leaf.icon}\n </span>\n ) : null}\n {segments.map((segment, i) => (\n <React.Fragment key={segment.type === 'node' ? segment.node.value : `gap-${i}`}>\n {i > 0 ? (separator ?? <PathChevron />) : null}\n {segment.type === 'ellipsis' ? (\n <span\n data-slot='cascader-value-ellipsis'\n title={segment.hidden.map((n) => n.label).join(` ${labels.pathSeparator} `)}\n className='text-muted-foreground shrink-0'\n >\n …\n </span>\n ) : (\n <span className={cn('truncate', i < segments.length - 1 && 'text-muted-foreground')}>\n {segment.node?.label}\n </span>\n )}\n </React.Fragment>\n ))}\n </>\n );\n }\n\n const defaultProps = {\n 'data-slot': 'cascader-value',\n 'className': cn('flex min-w-0 items-center gap-1 truncate', className),\n 'children': content,\n };\n\n return useRender({\n defaultTagName: 'span',\n render: props.render,\n props: mergeProps<'span'>(defaultProps, props),\n });\n}\n\nexport { CascaderNav, CascaderBack, CascaderBreadcrumb, CascaderInput, CascaderValue };\n","import { ChevronDownIcon } from 'lucide-react';\n\nimport {\n Cascader,\n CascaderContent,\n CascaderEmpty,\n CascaderList,\n CascaderPanel,\n CascaderStatus,\n CascaderTrigger,\n} from './cascader';\nimport { CascaderItems } from './cascader-item';\nimport { CascaderBreadcrumb, CascaderInput, CascaderNav, CascaderValue } from './cascader-nav';\nimport type { CascaderNode } from './cascader-types';\n\nexport type FieldPickerPopupProps = {\n nodes: CascaderNode[];\n /** 受控触发态由外壳持有;这里只负责选中后回传整条路径 */\n onPick: (path: string) => void;\n /** 弹层关闭(item-press / 外点)→ 外壳卸载,下次点击重挂新生 */\n onClose: () => void;\n disabled?: boolean;\n triggerClassName: string;\n triggerLabel: string;\n placeholder: string;\n};\n\n/**\n * TypedInput 字段选择弹层(c-cascader-21 形态):tree 模式整棵展开 +\n * 全树搜索(searchScope=global,命中带路径轨迹),分支/叶子均可选中\n * (selectable=\"any\"——`customer` 本身即合法 reference)。\n * 懒加载模块:Base UI 组合件走宿主 external,本 chunk 仅在首开弹层时下载。\n * 挂载即开(defaultOpen)——外壳点击的意图就是打开。\n */\nexport default function FieldPickerPopup({\n nodes,\n onPick,\n onClose,\n disabled,\n triggerClassName,\n triggerLabel,\n placeholder,\n}: FieldPickerPopupProps) {\n return (\n <Cascader\n items={nodes}\n mode='tree'\n searchScope='global'\n selectable='any'\n defaultOpen\n onOpenChange={(next) => {\n if (!next) {\n onClose();\n }\n }}\n onValueChange={(value) => {\n if (value != null) {\n onPick(String(value));\n }\n }}\n >\n <CascaderTrigger\n render={\n <button type='button' className={triggerClassName} disabled={disabled}>\n <span className='min-w-0 flex-1 truncate text-left'>{triggerLabel}</span>\n <ChevronDownIcon className='size-3.5 shrink-0 opacity-60' />\n </button>\n }\n >\n <CascaderValue placeholder={placeholder} />\n </CascaderTrigger>\n <CascaderContent className='w-72'>\n <CascaderPanel>\n <CascaderNav>\n <CascaderInput placeholder={placeholder} />\n </CascaderNav>\n <CascaderBreadcrumb />\n <CascaderEmpty />\n <CascaderList>\n <CascaderItems />\n </CascaderList>\n <CascaderStatus />\n </CascaderPanel>\n </CascaderContent>\n </Cascader>\n );\n}\n"],"mappings":"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"}
|