@sproutsocial/seeds-react-tree 0.4.1 → 0.4.3

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Tree.tsx","../src/Common/treeContext.ts","../src/Common/useTreeState.ts","../src/TreeStyles.tsx","../src/TreeItem.tsx","../src/Common/useTreeKeyboard.ts","../src/Common/treeNavigation.ts","../src/TreeCombobox.tsx","../src/Common/filterTree.ts","../src/SingleTreeSearchableSelect.tsx","../src/Common/TreeSearchableSelectBase.tsx","../src/Common/flattenTree.ts","../src/MultiTreeSearchableSelect.tsx"],"sourcesContent":["export { Tree, type TreeProps } from \"./Tree\";\nexport { TreeItem, type TreeItemProps } from \"./TreeItem\";\nexport { TreeCombobox, type TreeComboboxProps } from \"./TreeCombobox\";\nexport {\n SingleTreeSearchableSelect,\n type SingleTreeSearchableSelectProps,\n} from \"./SingleTreeSearchableSelect\";\nexport {\n MultiTreeSearchableSelect,\n type MultiTreeSearchableSelectProps,\n} from \"./MultiTreeSearchableSelect\";\nexport type {\n TreeItemData,\n TreeSelectionMode,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionIndicatorState,\n} from \"./Common/types\";\n","import * as React from \"react\";\nimport {\n TreeContext,\n TreeItemContext,\n type TreeContextValue,\n} from \"./Common/treeContext\";\nimport { useTreeState } from \"./Common/useTreeState\";\nimport type {\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionMode,\n} from \"./Common/types\";\nimport { TreeRoot } from \"./TreeStyles\";\n\nexport type TreeProps = {\n children: React.ReactNode;\n /** Accessible name for the tree. One of `aria-label` / `aria-labelledby` is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n\n selectionMode?: TreeSelectionMode;\n selectableNodes?: TreeSelectableNodes;\n\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n defaultSelected?: ReadonlyArray<string>;\n selected?: ReadonlyArray<string>;\n onSelectionChange?: (selected: string[]) => void;\n\n /**\n * Optional render function for a per-item selection indicator (e.g. radio or\n * checkbox). Returns null/undefined for no indicator.\n */\n renderSelectionIndicator?: TreeSelectionIndicator;\n\n /** Item id to receive focus first; defaults to the first treeitem in DOM order. */\n defaultFocusedId?: string;\n /**\n * Controlled focused id. When set, the host owns which item is \"active\" —\n * the roving tabindex target in DOM-focus mode, or the `aria-activedescendant`\n * target in `manageDomFocus={false}` mode.\n */\n focusedId?: string | null;\n onFocusedIdChange?: (id: string | null) => void;\n\n /**\n * When `false`, Tree does not put treeitems in the tab order and does not\n * call `.focus()` on them. Used by `TreeCombobox` so DOM focus can stay on\n * its input while `focusedId` drives `aria-activedescendant`. Defaults to\n * `true`.\n */\n manageDomFocus?: boolean;\n\n className?: string;\n id?: string;\n};\n\nexport const Tree = React.forwardRef<HTMLUListElement, TreeProps>(function Tree(\n props,\n forwardedRef\n) {\n const {\n children,\n selectionMode = \"none\",\n selectableNodes = \"all\",\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n renderSelectionIndicator,\n defaultFocusedId,\n focusedId: focusedIdProp,\n onFocusedIdChange,\n manageDomFocus = true,\n className,\n id,\n } = props;\n\n const ariaLabel = props[\"aria-label\"];\n const ariaLabelledBy = props[\"aria-labelledby\"];\n\n const innerRef = React.useRef<HTMLUListElement>(null);\n React.useImperativeHandle(forwardedRef, () => innerRef.current!, []);\n\n const { expanded, toggleExpanded, selected, toggleSelected } = useTreeState({\n selectionMode,\n selectableNodes,\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n });\n\n const isFocusedControlled = focusedIdProp !== undefined;\n const [internalFocusedId, setInternalFocusedId] = React.useState<\n string | null\n >(defaultFocusedId ?? null);\n const focusedId = isFocusedControlled\n ? focusedIdProp ?? null\n : internalFocusedId;\n\n const setFocusedId = React.useCallback(\n (nextId: string | null) => {\n if (!isFocusedControlled) setInternalFocusedId(nextId);\n onFocusedIdChange?.(nextId);\n },\n [isFocusedControlled, onFocusedIdChange]\n );\n\n const [hasFocused, setHasFocused] = React.useState(false);\n\n // If the focused id points at an item that no longer exists in the DOM\n // (e.g. it was filtered out by a wrapper), reset it to the first visible\n // item so the tree always has a tabbable target. Without this, Tab into\n // the tree lands nowhere and the user has to click to recover.\n React.useLayoutEffect(() => {\n const root = innerRef.current;\n if (!root || focusedId === null) return;\n const stillExists = root.querySelector(\n `[role=\"treeitem\"][data-treeitem-id=\"${CSS.escape(focusedId)}\"]`\n );\n if (stillExists) return;\n const firstVisible = root.querySelector<HTMLElement>('[role=\"treeitem\"]');\n setFocusedId(firstVisible?.dataset.treeitemId ?? null);\n });\n\n const ctxValue = React.useMemo<TreeContextValue>(\n () => ({\n focusedId,\n setFocusedId,\n expanded,\n toggleExpanded,\n selected,\n toggleSelected,\n selectionMode,\n selectableNodes,\n renderSelectionIndicator,\n rootRef: innerRef,\n hasFocused,\n setHasFocused,\n manageDomFocus,\n }),\n [\n focusedId,\n setFocusedId,\n expanded,\n toggleExpanded,\n selected,\n toggleSelected,\n selectionMode,\n selectableNodes,\n renderSelectionIndicator,\n hasFocused,\n manageDomFocus,\n ]\n );\n\n return (\n <TreeContext.Provider value={ctxValue}>\n <TreeItemContext.Provider value={{ level: 1 }}>\n <TreeRoot\n ref={innerRef}\n role=\"tree\"\n id={id}\n className={className}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-multiselectable={selectionMode === \"multiple\" ? true : undefined}\n >\n {children}\n </TreeRoot>\n </TreeItemContext.Provider>\n </TreeContext.Provider>\n );\n});\n","import { createContext, useContext } from \"react\";\nimport type {\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionMode,\n} from \"./types\";\n\nexport type TreeContextValue = {\n /** Roving tabindex / active descendant target. */\n focusedId: string | null;\n setFocusedId: (id: string | null) => void;\n /** Set of expanded branch ids. */\n expanded: ReadonlySet<string>;\n toggleExpanded: (id: string, next?: boolean) => void;\n /** Set of selected ids. */\n selected: ReadonlySet<string>;\n toggleSelected: (id: string, hasChildren: boolean) => void;\n selectionMode: TreeSelectionMode;\n selectableNodes: TreeSelectableNodes;\n renderSelectionIndicator?: TreeSelectionIndicator;\n /** DOM node of the <ul role=\"tree\"> root. Used for DOM-order navigation. */\n rootRef: React.RefObject<HTMLUListElement>;\n /** Whether the tree has received focus yet (controls initial roving tabindex). */\n hasFocused: boolean;\n setHasFocused: (v: boolean) => void;\n /**\n * When true (default), Tree manages DOM focus: items participate in the\n * tab order and `.focus()` is called as the focused id changes. When false,\n * the host (e.g. a combobox input) owns DOM focus and just consumes\n * `focusedId` to drive `aria-activedescendant`.\n */\n manageDomFocus: boolean;\n};\n\nexport const TreeContext = createContext<TreeContextValue | null>(null);\n\nexport function useTreeContext(): TreeContextValue {\n const ctx = useContext(TreeContext);\n if (!ctx) {\n throw new Error(\"TreeItem must be rendered inside a <Tree>.\");\n }\n return ctx;\n}\n\nexport type TreeItemContextValue = {\n /** 1-based depth used for aria-level. */\n level: number;\n};\n\nexport const TreeItemContext = createContext<TreeItemContextValue>({\n level: 1,\n});\n","import { useCallback, useMemo, useState } from \"react\";\nimport type { TreeSelectableNodes, TreeSelectionMode } from \"./types\";\n\ntype UseTreeStateOptions = {\n selectionMode: TreeSelectionMode;\n selectableNodes: TreeSelectableNodes;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n defaultSelected?: ReadonlyArray<string>;\n selected?: ReadonlyArray<string>;\n onSelectionChange?: (selected: string[]) => void;\n};\n\nexport function useTreeState(opts: UseTreeStateOptions) {\n const {\n selectionMode,\n selectableNodes,\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n } = opts;\n\n const [uncontrolledExpanded, setUncontrolledExpanded] = useState<Set<string>>(\n () => new Set(defaultExpanded ?? [])\n );\n const [uncontrolledSelected, setUncontrolledSelected] = useState<Set<string>>(\n () => new Set(defaultSelected ?? [])\n );\n\n const expanded = useMemo(\n () => (expandedProp ? new Set(expandedProp) : uncontrolledExpanded),\n [expandedProp, uncontrolledExpanded]\n );\n\n const selected = useMemo(\n () => (selectedProp ? new Set(selectedProp) : uncontrolledSelected),\n [selectedProp, uncontrolledSelected]\n );\n\n const toggleExpanded = useCallback(\n (id: string, next?: boolean) => {\n const current = expandedProp\n ? new Set(expandedProp)\n : uncontrolledExpanded;\n const willOpen = next ?? !current.has(id);\n const updated = new Set(current);\n if (willOpen) {\n updated.add(id);\n } else {\n updated.delete(id);\n }\n if (!expandedProp) {\n setUncontrolledExpanded(updated);\n }\n onExpandedChange?.(Array.from(updated));\n },\n [expandedProp, uncontrolledExpanded, onExpandedChange]\n );\n\n const toggleSelected = useCallback(\n (id: string, hasChildren: boolean) => {\n if (selectionMode === \"none\") return;\n if (selectableNodes === \"leaves\" && hasChildren) return;\n\n const current = selectedProp\n ? new Set(selectedProp)\n : uncontrolledSelected;\n const updated = new Set<string>();\n\n if (selectionMode === \"single\") {\n if (!current.has(id)) {\n updated.add(id);\n }\n } else {\n current.forEach((v) => updated.add(v));\n if (updated.has(id)) {\n updated.delete(id);\n } else {\n updated.add(id);\n }\n }\n\n if (!selectedProp) {\n setUncontrolledSelected(updated);\n }\n onSelectionChange?.(Array.from(updated));\n },\n [\n selectionMode,\n selectableNodes,\n selectedProp,\n uncontrolledSelected,\n onSelectionChange,\n ]\n );\n\n return {\n expanded,\n toggleExpanded,\n selected,\n toggleSelected,\n };\n}\n","import styled, { css } from \"styled-components\";\n\nexport const TreeRoot = styled.ul`\n list-style: none;\n margin: 0;\n padding: 0;\n font-family: ${({ theme }) => theme.fontFamily};\n font-size: ${({ theme }) => theme.typography[200].fontSize};\n line-height: ${({ theme }) => theme.typography[200].lineHeight};\n color: ${({ theme }) => theme.colors.text.body};\n`;\n\nexport const TreeItemRow = styled.div<{\n $level: number;\n $selected: boolean;\n $disabled: boolean;\n}>`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[300]};\n padding: ${({ theme }) => theme.space[300]};\n padding-left: ${({ theme, $level }) =>\n `calc(${theme.space[300]} + ${$level - 1} * ${theme.space[400]})`};\n border-radius: ${({ theme }) => theme.radii[400]};\n cursor: pointer;\n user-select: none;\n background: transparent;\n transition: background-color ${({ theme }) => theme.duration.fast}\n ${({ theme }) => theme.easing.ease_in};\n\n &:hover {\n background: ${({ theme }) => theme.colors.listItem.background.hover};\n }\n\n ${({ $selected, theme }) =>\n $selected &&\n css`\n background: ${theme.colors.listItem.background.hover};\n font-weight: ${theme.fontWeights.semibold};\n `}\n\n ${({ $disabled }) =>\n $disabled &&\n css`\n opacity: 0.4;\n cursor: not-allowed;\n pointer-events: none;\n `}\n`;\n\nexport const TreeItemEl = styled.li`\n list-style: none;\n outline: none;\n\n /*\n * Tree rows stack tightly, so the standard outset Seeds focusRing bleeds\n * into adjacent rows. Use an inset outline so the ring is drawn just inside\n * the row's edge and never overlaps siblings or children.\n *\n * The same ring is drawn when [data-treeitem-active] is set so combobox\n * hosts that drive the tree via aria-activedescendant (no real DOM focus)\n * still get a visible \"active\" indicator on the row.\n */\n &:focus-visible > ${TreeItemRow}, &[data-treeitem-active] > ${TreeItemRow} {\n outline: 2px solid\n ${({ theme }) => theme.colors.button.primary.background.base};\n outline-offset: -2px;\n }\n`;\n\nexport const TreeItemGroup = styled.ul`\n list-style: none;\n margin: 0;\n padding: 0;\n`;\n\nexport const TreeItemLabel = styled.span`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nexport const TreeItemIcon = styled.span`\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n`;\n\nexport const TreeItemChevron = styled.button.attrs({\n type: \"button\",\n tabIndex: -1,\n})<{ $expanded: boolean }>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: ${({ theme }) => theme.space[500]};\n height: ${({ theme }) => theme.space[500]};\n padding: 0;\n border: none;\n background: transparent;\n color: ${({ theme }) => theme.colors.icon.base};\n cursor: pointer;\n border-radius: ${({ theme }) => theme.radii[300]};\n transition: transform ${({ theme }) => theme.duration.fast}\n ${({ theme }) => theme.easing.ease_in};\n transform: ${({ $expanded }) =>\n $expanded ? \"rotate(0deg)\" : \"rotate(-90deg)\"};\n\n &:hover {\n background: ${({ theme }) => theme.colors.listItem.background.hover};\n }\n`;\n","import * as React from \"react\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { TreeItemContext, useTreeContext } from \"./Common/treeContext\";\nimport { useTreeKeyboard } from \"./Common/useTreeKeyboard\";\nimport { treeItemDomId } from \"./Common/treeNavigation\";\nimport {\n TreeItemChevron,\n TreeItemEl,\n TreeItemGroup,\n TreeItemIcon,\n TreeItemLabel,\n TreeItemRow,\n} from \"./TreeStyles\";\n\nexport type TreeItemProps = {\n id: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n disabled?: boolean;\n children?: React.ReactNode;\n /**\n * Optional override for the row click target. When provided, this is used\n * as the accessible name for the row (otherwise the rendered `label` is).\n */\n \"aria-label\"?: string;\n};\n\nfunction hasTreeItemChildren(children: React.ReactNode): boolean {\n let found = false;\n React.Children.forEach(children, (child) => {\n if (found) return;\n if (!React.isValidElement(child)) return;\n const childType = child.type;\n if (childType === React.Fragment) {\n found = hasTreeItemChildren(\n (child as React.ReactElement<{ children?: React.ReactNode }>).props\n .children\n );\n return;\n }\n // Any other element child counts as a tree item. Consumers should only\n // place TreeItems (or components that render one) inside a TreeItem.\n found = true;\n });\n return found;\n}\n\nexport function TreeItem(props: TreeItemProps) {\n const { id, label, icon, disabled = false, children } = props;\n const ctx = useTreeContext();\n const { level } = React.useContext(TreeItemContext);\n\n const hasChildren = React.useMemo(\n () => hasTreeItemChildren(children),\n [children]\n );\n\n const isExpanded = ctx.expanded.has(id);\n const isSelected = ctx.selected.has(id);\n const selectionMode = ctx.selectionMode;\n\n // Roving tabindex: this item is tabbable when it's the focused id. When the\n // host (e.g. a combobox) drives focus externally, no treeitem is tabbable.\n const itemRef = React.useRef<HTMLLIElement>(null);\n const isTabbable = ctx.manageDomFocus && ctx.focusedId === id;\n\n // On first mount of the very first item, register ourselves as the initial\n // roving target if nothing else has claimed it. Skipped when the host owns\n // focus — the host decides when (if ever) to set an initial active id.\n React.useEffect(() => {\n if (!ctx.manageDomFocus) return;\n if (ctx.focusedId !== null) return;\n const root = ctx.rootRef.current;\n if (!root) return;\n const first = root.querySelector<HTMLElement>('[role=\"treeitem\"]');\n if (first === itemRef.current) {\n ctx.setFocusedId(id);\n }\n // We only want this on mount; deps intentionally minimal.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleKeyDown = useTreeKeyboard(ctx);\n\n const handleRowClick = (e: React.MouseEvent) => {\n if (disabled) return;\n // Ignore clicks that originated on the chevron — it owns its own handler.\n const target = e.target as HTMLElement;\n if (target.closest(\"[data-tree-chevron]\")) return;\n\n ctx.setFocusedId(id);\n if (ctx.manageDomFocus) itemRef.current?.focus();\n\n if (hasChildren && selectionMode === \"none\") {\n ctx.toggleExpanded(id);\n return;\n }\n if (hasChildren && ctx.selectableNodes === \"leaves\") {\n ctx.toggleExpanded(id);\n return;\n }\n if (selectionMode !== \"none\") {\n ctx.toggleSelected(id, hasChildren);\n }\n };\n\n const handleChevronClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (disabled) return;\n ctx.setFocusedId(id);\n if (ctx.manageDomFocus) itemRef.current?.focus();\n ctx.toggleExpanded(id);\n };\n\n const ariaSelected =\n selectionMode === \"single\" && ctx.selectableNodes !== \"leaves\"\n ? isSelected\n : undefined;\n const ariaChecked =\n selectionMode === \"multiple\"\n ? isSelected\n : selectionMode === \"single\" && ctx.selectableNodes === \"leaves\"\n ? isSelected\n : undefined;\n\n const groupId = `${id}__group`;\n const labelId = `${id}__label`;\n\n return (\n <TreeItemEl\n ref={itemRef}\n id={treeItemDomId(id)}\n role=\"treeitem\"\n data-treeitem-id={id}\n data-treeitem-active={\n !ctx.manageDomFocus && ctx.focusedId === id ? true : undefined\n }\n aria-level={level}\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={ariaSelected}\n aria-checked={ariaChecked}\n aria-disabled={disabled || undefined}\n aria-labelledby={labelId}\n aria-owns={hasChildren && isExpanded ? groupId : undefined}\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => {\n if (!ctx.manageDomFocus) return;\n handleKeyDown(e, {\n id,\n hasChildren,\n isExpanded,\n isDisabled: disabled,\n level,\n });\n }}\n onClick={(e) => {\n // Branch treeitems contain descendant LIs whose row clicks bubble up.\n // Only handle the click if it originated within this LI's own row —\n // not within a descendant treeitem.\n const target = e.target as HTMLElement;\n const nearestTreeitem = target.closest('[role=\"treeitem\"]');\n if (nearestTreeitem !== e.currentTarget) return;\n handleRowClick(e);\n }}\n onMouseDown={(e) => {\n // In external-focus (combobox) mode, mousedown on a tabindex=-1\n // treeitem would still steal DOM focus from the host input. Prevent\n // it so focus stays where the host put it; onClick still fires.\n if (!ctx.manageDomFocus) e.preventDefault();\n }}\n onFocus={() => {\n if (!ctx.manageDomFocus) return;\n if (!ctx.hasFocused) ctx.setHasFocused(true);\n if (ctx.focusedId !== id) ctx.setFocusedId(id);\n }}\n >\n <TreeItemRow\n data-treeitem-row\n $level={level}\n $selected={isSelected}\n $disabled={disabled}\n >\n {ctx.renderSelectionIndicator &&\n !(ctx.selectableNodes === \"leaves\" && hasChildren)\n ? ctx.renderSelectionIndicator({\n selected: isSelected,\n disabled,\n selectionMode,\n })\n : null}\n\n {icon != null ? <TreeItemIcon aria-hidden>{icon}</TreeItemIcon> : null}\n <TreeItemLabel id={labelId}>{label}</TreeItemLabel>\n\n {hasChildren ? (\n <TreeItemChevron\n data-tree-chevron\n aria-hidden\n $expanded={isExpanded}\n onClick={handleChevronClick}\n >\n <Icon name=\"chevron-down-outline\" size=\"small\" />\n </TreeItemChevron>\n ) : null}\n </TreeItemRow>\n\n {hasChildren ? (\n <TreeItemGroup role=\"group\" id={groupId} hidden={!isExpanded}>\n <TreeItemContext.Provider value={{ level: level + 1 }}>\n {children}\n </TreeItemContext.Provider>\n </TreeItemGroup>\n ) : null}\n </TreeItemEl>\n );\n}\n\nTreeItem.displayName = \"TreeItem\";\n","import { useCallback, useRef } from \"react\";\nimport type { TreeContextValue } from \"./treeContext\";\nimport {\n computeTreeNavigation,\n getTreeItemId,\n getVisibleTreeItems,\n} from \"./treeNavigation\";\n\nconst TYPEAHEAD_TIMEOUT_MS = 500;\n\nfunction focusItem(el: HTMLElement | undefined) {\n if (!el) return;\n el.focus();\n}\n\n/**\n * Keyboard handler for the WAI-ARIA treeview pattern, bound to each TreeItem\n * via `onKeyDown` when DOM focus lives on treeitems (roving tabindex). The\n * heavy lifting — what to focus next, what to expand/select — is delegated to\n * `computeTreeNavigation` so a combobox host that drives the tree externally\n * can share the exact same navigation rules.\n */\nexport function useTreeKeyboard(ctx: TreeContextValue) {\n const typeaheadBufferRef = useRef(\"\");\n const typeaheadTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleTypeahead = useCallback(\n (char: string, current: HTMLElement, visible: HTMLElement[]) => {\n if (typeaheadTimerRef.current) clearTimeout(typeaheadTimerRef.current);\n typeaheadBufferRef.current = (\n typeaheadBufferRef.current + char\n ).toLowerCase();\n typeaheadTimerRef.current = setTimeout(() => {\n typeaheadBufferRef.current = \"\";\n }, TYPEAHEAD_TIMEOUT_MS);\n\n const buffer = typeaheadBufferRef.current;\n const currentIndex = visible.indexOf(current);\n const ordered = [\n ...visible.slice(currentIndex + 1),\n ...visible.slice(0, currentIndex + 1),\n ];\n const match = ordered.find((el) =>\n (el.textContent ?? \"\").trim().toLowerCase().startsWith(buffer)\n );\n if (match) {\n const id = getTreeItemId(match);\n if (id) ctx.setFocusedId(id);\n focusItem(match);\n }\n },\n [ctx]\n );\n\n return useCallback(\n (\n e: React.KeyboardEvent<HTMLLIElement>,\n itemMeta: {\n id: string;\n hasChildren: boolean;\n isExpanded: boolean;\n isDisabled: boolean;\n level: number;\n }\n ) => {\n if (itemMeta.isDisabled) return;\n // Branch treeitems contain their descendants' LIs, so keydowns bubble up\n // through every ancestor TreeItem. Only handle the keydown on the LI\n // that actually has focus, otherwise ancestor handlers fight the\n // descendant for control of the roving tabindex.\n if (e.target !== e.currentTarget) return;\n\n const root = ctx.rootRef.current;\n const current = e.currentTarget;\n\n const result = computeTreeNavigation(root, current, e.key, {\n id: itemMeta.id,\n hasChildren: itemMeta.hasChildren,\n isExpanded: itemMeta.isExpanded,\n level: itemMeta.level,\n });\n\n if (result.preventDefault) e.preventDefault();\n\n if (result.expandToggle) {\n ctx.toggleExpanded(result.expandToggle.id, result.expandToggle.next);\n }\n if (result.selectToggle) {\n ctx.toggleSelected(\n result.selectToggle.id,\n result.selectToggle.hasChildren\n );\n }\n if (result.expandSiblings) {\n result.expandSiblings.forEach((id) => ctx.toggleExpanded(id, true));\n }\n if (result.nextFocusedId) {\n ctx.setFocusedId(result.nextFocusedId);\n if (ctx.manageDomFocus) {\n const next = root?.querySelector<HTMLElement>(\n `[data-treeitem-id=\"${CSS.escape(result.nextFocusedId)}\"]`\n );\n focusItem(next ?? undefined);\n }\n }\n\n // Printable-char typeahead fires only when the navigation table didn't\n // claim the key. Skip it when DOM focus is external (combobox mode) —\n // there the host input is the type target, not the tree.\n if (\n !result.preventDefault &&\n ctx.manageDomFocus &&\n e.key.length === 1 &&\n /\\S/.test(e.key) &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.altKey\n ) {\n handleTypeahead(e.key, current, getVisibleTreeItems(root));\n }\n },\n [ctx, handleTypeahead]\n );\n}\n","/**\n * Pure navigation logic for the WAI-ARIA treeview pattern.\n *\n * `useTreeKeyboard` uses this when DOM focus lives on the focused treeitem\n * (roving tabindex). A combobox-style host that keeps DOM focus on an input\n * and reflects the active item via `aria-activedescendant` uses the same\n * function — it just skips the `.focus()` step.\n */\n\nexport type TreeNavigationResult = {\n /** True when the caller should call `event.preventDefault()`. */\n preventDefault: boolean;\n /** Item the host should make active next (roving focus / active descendant). */\n nextFocusedId?: string;\n /** Branch to expand or collapse. */\n expandToggle?: { id: string; next?: boolean };\n /** Item whose selection should be toggled (Enter / Space). */\n selectToggle?: { id: string; hasChildren: boolean };\n /** Sibling branch ids to expand (the `*` key). */\n expandSiblings?: string[];\n};\n\nexport function getVisibleTreeItems(root: HTMLElement | null): HTMLElement[] {\n if (!root) return [];\n const all = Array.from(\n root.querySelectorAll<HTMLElement>('[role=\"treeitem\"]')\n );\n return all.filter((el) => {\n if (el.getAttribute(\"aria-disabled\") === \"true\") return false;\n let parent = el.parentElement;\n while (parent && parent !== root) {\n if (\n parent.getAttribute(\"role\") === \"group\" &&\n parent.hasAttribute(\"hidden\")\n ) {\n return false;\n }\n parent = parent.parentElement;\n }\n return true;\n });\n}\n\nexport function getTreeItemId(el: HTMLElement): string | null {\n return el.dataset.treeitemId ?? null;\n}\n\n/** DOM `id` we apply to each treeitem so a combobox host can target it via `aria-activedescendant`. */\nexport function treeItemDomId(itemId: string): string {\n return `${itemId}__item`;\n}\n\nexport type TreeNavigationMeta = {\n id: string;\n hasChildren: boolean;\n isExpanded: boolean;\n level: number;\n};\n\nexport function computeTreeNavigation(\n root: HTMLElement | null,\n currentEl: HTMLElement | null,\n key: string,\n meta: TreeNavigationMeta | null\n): TreeNavigationResult {\n const visible = getVisibleTreeItems(root);\n if (visible.length === 0) return { preventDefault: false };\n\n const idOf = (el: HTMLElement | undefined): string | undefined => {\n if (!el) return undefined;\n return getTreeItemId(el) ?? undefined;\n };\n\n // No current item — ArrowDown/Home land on the first visible item;\n // ArrowUp/End land on the last. (Used by the combobox when the user\n // first presses an arrow with no item highlighted.)\n if (!currentEl || !meta) {\n if (key === \"ArrowDown\" || key === \"Home\") {\n return { preventDefault: true, nextFocusedId: idOf(visible[0]) };\n }\n if (key === \"ArrowUp\" || key === \"End\") {\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[visible.length - 1]),\n };\n }\n return { preventDefault: false };\n }\n\n const currentIndex = visible.indexOf(currentEl);\n if (currentIndex === -1) return { preventDefault: false };\n\n const clamp = (i: number) => Math.max(0, Math.min(visible.length - 1, i));\n\n switch (key) {\n case \"ArrowDown\":\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[clamp(currentIndex + 1)]),\n };\n case \"ArrowUp\":\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[clamp(currentIndex - 1)]),\n };\n case \"ArrowRight\": {\n if (meta.hasChildren && !meta.isExpanded) {\n return {\n preventDefault: true,\n expandToggle: { id: meta.id, next: true },\n };\n }\n if (meta.hasChildren && meta.isExpanded) {\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[clamp(currentIndex + 1)]),\n };\n }\n return { preventDefault: true };\n }\n case \"ArrowLeft\": {\n if (meta.hasChildren && meta.isExpanded) {\n return {\n preventDefault: true,\n expandToggle: { id: meta.id, next: false },\n };\n }\n let parent: HTMLElement | null = currentEl.parentElement;\n while (parent && parent !== root) {\n if (parent.getAttribute(\"role\") === \"group\") {\n const parentItem = parent.parentElement;\n if (parentItem?.getAttribute(\"role\") === \"treeitem\") {\n return {\n preventDefault: true,\n nextFocusedId: idOf(parentItem),\n };\n }\n }\n parent = parent.parentElement;\n }\n return { preventDefault: true };\n }\n case \"Home\":\n return { preventDefault: true, nextFocusedId: idOf(visible[0]) };\n case \"End\":\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[visible.length - 1]),\n };\n case \"Enter\":\n case \" \":\n return {\n preventDefault: true,\n selectToggle: { id: meta.id, hasChildren: meta.hasChildren },\n };\n case \"*\": {\n const siblings = Array.from(\n currentEl.parentElement?.children ?? []\n ).filter(\n (el): el is HTMLElement =>\n el instanceof HTMLElement && el.getAttribute(\"role\") === \"treeitem\"\n );\n const toExpand = siblings\n .filter((s) => s.getAttribute(\"aria-expanded\") === \"false\")\n .map((s) => getTreeItemId(s))\n .filter((id): id is string => id !== null);\n return { preventDefault: true, expandSiblings: toExpand };\n }\n }\n return { preventDefault: false };\n}\n","import * as React from \"react\";\nimport styled from \"styled-components\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport { Tree, type TreeProps } from \"./Tree\";\nimport { TreeItem } from \"./TreeItem\";\nimport { filterTree } from \"./Common/filterTree\";\nimport { computeTreeNavigation, treeItemDomId } from \"./Common/treeNavigation\";\nimport type { TreeItemData } from \"./Common/types\";\n\nconst Root = styled.div`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n`;\n\nconst SearchSection = styled.div`\n padding: ${({ theme }) => theme.space[300]};\n border-bottom: 1px solid ${({ theme }) => theme.colors.container.border.base};\n flex-shrink: 0;\n`;\n\nconst InputGroup = styled.div`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.space[200]};\n padding: ${({ theme }) => theme.space[200]} ${({ theme }) => theme.space[300]};\n border-radius: ${({ theme }) => theme.radii[500]};\n border: 1px solid ${({ theme }) => theme.colors.container.border.base};\n background: ${({ theme }) => theme.colors.container.background.base};\n color: ${({ theme }) => theme.colors.icon.base};\n\n &:focus-within {\n ${focusRing}\n }\n`;\n\nconst ComboboxInput = styled.input`\n flex: 1;\n border: none;\n background: transparent;\n outline: none;\n font-family: ${({ theme }) => theme.fontFamily};\n font-size: ${({ theme }) => theme.typography[200].fontSize};\n line-height: ${({ theme }) => theme.typography[200].lineHeight};\n color: ${({ theme }) => theme.colors.text.body};\n\n &::placeholder {\n color: ${({ theme }) => theme.colors.text.subtext};\n }\n`;\n\nconst ListSection = styled.div`\n padding: ${({ theme }) => theme.space[200]};\n overflow: auto;\n flex: 1;\n min-height: 0;\n`;\n\nconst EmptyState = styled.div`\n padding: ${({ theme }) => `${theme.space[300]} ${theme.space[350]}`};\n text-align: center;\n color: ${({ theme }) => theme.colors.text.subtext};\n font-size: ${({ theme }) => theme.typography[200].fontSize};\n line-height: ${({ theme }) => theme.typography[200].lineHeight};\n`;\n\nconst NAV_KEYS = new Set([\n \"ArrowDown\",\n \"ArrowUp\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Home\",\n \"End\",\n \"Enter\",\n]);\n\nexport type TreeComboboxProps = Omit<\n TreeProps,\n | \"children\"\n | \"focusedId\"\n | \"onFocusedIdChange\"\n | \"defaultFocusedId\"\n | \"manageDomFocus\"\n | \"aria-label\"\n | \"aria-labelledby\"\n> & {\n items: ReadonlyArray<TreeItemData>;\n /** Placeholder for the combobox input. */\n placeholder?: string;\n /** Text shown when the query has no matches. */\n emptyText?: string;\n /** Accessible name for the combobox. One of `aria-label` / `aria-labelledby` is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n /** Controlled query value. */\n query?: string;\n /** Uncontrolled initial query. */\n defaultQuery?: string;\n onQueryChange?: (query: string) => void;\n};\n\n/**\n * Combobox + tree pattern. Implements the WAI-ARIA combobox pattern with a\n * tree as the popup (`aria-haspopup=\"tree\"`). DOM focus stays on the input;\n * `aria-activedescendant` points at the active treeitem, which the input's\n * arrow-key handler moves through the visible tree. Selection and expansion\n * reuse the underlying Tree's logic — Enter on the input synthesizes a click\n * on the active row, ArrowRight/Left compute the new expanded set and pass\n * it through Tree's controlled `expanded` prop.\n */\nexport function TreeCombobox(props: TreeComboboxProps) {\n const {\n items,\n placeholder = \"Search...\",\n emptyText = \"No results found.\",\n query: queryProp,\n defaultQuery = \"\",\n onQueryChange,\n selectionMode = \"none\",\n selectableNodes = \"all\",\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n renderSelectionIndicator,\n id,\n className,\n } = props;\n const ariaLabel = props[\"aria-label\"];\n const ariaLabelledBy = props[\"aria-labelledby\"];\n\n const [uncontrolledQuery, setUncontrolledQuery] =\n React.useState(defaultQuery);\n const query = queryProp ?? uncontrolledQuery;\n const setQuery = (next: string) => {\n if (queryProp === undefined) setUncontrolledQuery(next);\n onQueryChange?.(next);\n };\n\n // Track the user's last \"real\" expansion state so it can be restored when\n // the query clears, matching the prior SearchableTree behavior.\n const [userExpanded, setUserExpanded] = React.useState<string[]>(() => [\n ...(defaultExpanded ?? expandedProp ?? []),\n ]);\n\n const { items: visibleItems, forceExpanded } = React.useMemo(\n () => filterTree([...items], query),\n [items, query]\n );\n\n const isFiltering = query.trim().length > 0;\n const effectiveExpanded = isFiltering\n ? Array.from(new Set([...userExpanded, ...forceExpanded]))\n : expandedProp ?? userExpanded;\n\n const handleExpandedChange = (next: string[]) => {\n if (!isFiltering) {\n setUserExpanded(next);\n }\n onExpandedChange?.(next);\n };\n\n const [focusedId, setFocusedId] = React.useState<string | null>(null);\n\n const treeRef = React.useRef<HTMLUListElement>(null);\n const reactId = React.useId();\n const treeDomId = id ? `${id}-tree` : `${reactId}-tree`;\n\n const findTreeItemEl = (itemId: string): HTMLElement | null =>\n treeRef.current?.querySelector<HTMLElement>(\n `[role=\"treeitem\"][data-treeitem-id=\"${CSS.escape(itemId)}\"]`\n ) ?? null;\n\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n if (query.length > 0) {\n e.preventDefault();\n setQuery(\"\");\n setFocusedId(null);\n }\n return;\n }\n if (!NAV_KEYS.has(e.key)) return;\n\n const currentEl = focusedId ? findTreeItemEl(focusedId) : null;\n const meta =\n currentEl && focusedId\n ? {\n id: focusedId,\n hasChildren: currentEl.getAttribute(\"aria-expanded\") !== null,\n isExpanded: currentEl.getAttribute(\"aria-expanded\") === \"true\",\n level: parseInt(currentEl.getAttribute(\"aria-level\") ?? \"1\", 10),\n }\n : null;\n\n // Enter: replay a row click on the active treeitem so we get TreeItem's\n // exact selection/expansion semantics (single vs multi, leaves-only,\n // branch-vs-leaf) for free.\n if (e.key === \"Enter\") {\n if (!currentEl) return;\n e.preventDefault();\n const row = currentEl.querySelector<HTMLElement>(\"[data-treeitem-row]\");\n row?.click();\n return;\n }\n\n const result = computeTreeNavigation(\n treeRef.current,\n currentEl,\n e.key,\n meta\n );\n if (result.preventDefault) e.preventDefault();\n\n if (result.expandToggle) {\n const current = new Set(effectiveExpanded);\n const willOpen =\n result.expandToggle.next ?? !current.has(result.expandToggle.id);\n if (willOpen) current.add(result.expandToggle.id);\n else current.delete(result.expandToggle.id);\n handleExpandedChange(Array.from(current));\n }\n if (result.nextFocusedId) {\n setFocusedId(result.nextFocusedId);\n }\n };\n\n // If a filter change drops the active item out of the visible set, the\n // Tree's recovery layout-effect rebases focusedId via onFocusedIdChange.\n // We accept that and don't reset focusedId on filter ourselves — clearing\n // happens explicitly on Escape.\n\n // Keep the active treeitem visible as the user navigates with the\n // keyboard. In DOM-focus mode the browser auto-scrolls on `.focus()`, but\n // combobox mode skips that call (focus stays on the input), so we have to\n // scroll explicitly to meet the WAI-ARIA combobox/treeview expectation\n // that the active option stays in view. `block: \"nearest\"` only scrolls\n // when the row is actually off-screen.\n React.useLayoutEffect(() => {\n if (!focusedId) return;\n const itemEl = findTreeItemEl(focusedId);\n const row =\n itemEl?.querySelector<HTMLElement>(\"[data-treeitem-row]\") ?? itemEl;\n // jsdom doesn't implement scrollIntoView; bail there.\n if (row && typeof row.scrollIntoView === \"function\") {\n row.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n }\n // findTreeItemEl is read from a ref so it doesn't need to be a dep.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [focusedId]);\n\n const showEmpty = visibleItems.length === 0;\n\n return (\n <Root className={className}>\n <SearchSection>\n <InputGroup>\n <Icon name=\"magnifying-glass-outline\" size=\"small\" aria-hidden />\n <ComboboxInput\n type=\"text\"\n role=\"combobox\"\n id={id}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-expanded={!showEmpty}\n aria-controls={treeDomId}\n aria-haspopup=\"tree\"\n aria-autocomplete=\"list\"\n aria-activedescendant={\n focusedId ? treeItemDomId(focusedId) : undefined\n }\n placeholder={placeholder}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={handleInputKeyDown}\n />\n </InputGroup>\n </SearchSection>\n\n <ListSection>\n <Tree\n ref={treeRef}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n id={treeDomId}\n manageDomFocus={false}\n selectionMode={selectionMode}\n selectableNodes={selectableNodes}\n expanded={effectiveExpanded}\n onExpandedChange={handleExpandedChange}\n selected={selectedProp}\n defaultSelected={defaultSelected}\n onSelectionChange={onSelectionChange}\n renderSelectionIndicator={renderSelectionIndicator}\n focusedId={focusedId}\n onFocusedIdChange={setFocusedId}\n >\n {visibleItems.map((item) => (\n <TreeNode key={item.id} item={item} />\n ))}\n </Tree>\n\n {showEmpty ? (\n <EmptyState role=\"status\" aria-live=\"polite\">\n {emptyText}\n </EmptyState>\n ) : null}\n </ListSection>\n </Root>\n );\n}\n\nfunction TreeNode({ item }: { item: TreeItemData }) {\n return (\n <TreeItem\n id={item.id}\n label={item.label}\n icon={item.icon}\n disabled={item.disabled}\n >\n {item.children?.map((child) => (\n <TreeNode key={child.id} item={child} />\n ))}\n </TreeItem>\n );\n}\n","import type { TreeItemData } from \"./types\";\n\nexport type FilterResult = {\n /** Items to render (parents with no matching descendants are removed). */\n items: TreeItemData[];\n /** Ids of branches that should be force-expanded so matches are visible. */\n forceExpanded: string[];\n};\n\n/**\n * Returns the subtree of items where `label` (or any descendant label) matches\n * `query`, plus the set of branch ids that should be opened to reveal matches.\n *\n * Why: TreeCombobox needs both a filtered list and the ancestor ids of every\n * match so users can see what their search hit.\n * How to apply: pass the result to <Tree expanded={...}>.\n */\nexport function filterTree(\n items: ReadonlyArray<TreeItemData>,\n query: string\n): FilterResult {\n const normalized = query.trim().toLowerCase();\n if (!normalized) {\n return { items: [...items], forceExpanded: [] };\n }\n\n const forceExpanded = new Set<string>();\n\n const walk = (node: TreeItemData): TreeItemData | null => {\n const matches = node.label.toLowerCase().includes(normalized);\n const filteredChildren = (node.children ?? [])\n .map(walk)\n .filter((c): c is TreeItemData => c !== null);\n\n if (filteredChildren.length > 0 && node.children) {\n forceExpanded.add(node.id);\n }\n\n if (matches || filteredChildren.length > 0) {\n return {\n ...node,\n children: node.children ? filteredChildren : undefined,\n };\n }\n return null;\n };\n\n const filtered = items.map(walk).filter((n): n is TreeItemData => n !== null);\n\n return { items: filtered, forceExpanded: Array.from(forceExpanded) };\n}\n","import * as React from \"react\";\nimport {\n TreeSearchableSelectBase,\n type RenderTrigger,\n} from \"./Common/TreeSearchableSelectBase\";\nimport type {\n TreeItemData,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n} from \"./Common/types\";\n\nexport type SingleTreeSearchableSelectProps = {\n items: ReadonlyArray<TreeItemData>;\n selectableNodes?: TreeSelectableNodes;\n\n selectedItemId?: string | null;\n defaultSelectedItemId?: string | null;\n onSelectedItemIdChange?: (id: string | null) => void;\n\n /** Accessible name for the trigger. One of label / labelledby is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n\n /** Render override for the trigger label area. */\n renderTrigger?: RenderTrigger;\n\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n disabled?: boolean;\n isInvalid?: boolean;\n required?: boolean;\n readOnly?: boolean;\n /** Name for the hidden form input, enabling participation in native form submission. */\n name?: string;\n fullWidth?: boolean;\n contentWidth?: number | string;\n\n renderSelectionIndicator?: TreeSelectionIndicator;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n id?: string;\n className?: string;\n};\n\n/**\n * Single-select tree inside a popout, following the same shape as\n * `SingleSearchableSelect`. Picks close the popout and return focus to the\n * trigger.\n */\nexport function SingleTreeSearchableSelect(\n props: SingleTreeSearchableSelectProps\n) {\n const {\n selectedItemId: selectedItemIdProp,\n defaultSelectedItemId = null,\n onSelectedItemIdChange,\n ...rest\n } = props;\n\n const isControlled = selectedItemIdProp !== undefined;\n const [internalId, setInternalId] = React.useState<string | null>(\n defaultSelectedItemId\n );\n const selectedItemId = isControlled ? selectedItemIdProp ?? null : internalId;\n\n const selectedIds = React.useMemo(\n () => (selectedItemId ? [selectedItemId] : []),\n [selectedItemId]\n );\n\n const handleSelectedIdsChange = (ids: string[]) => {\n const next = ids[0] ?? null;\n if (!isControlled) setInternalId(next);\n onSelectedItemIdChange?.(next);\n };\n\n return (\n <TreeSearchableSelectBase\n {...rest}\n selectionMode=\"single\"\n selectedIds={selectedIds}\n onSelectedIdsChange={handleSelectedIdsChange}\n closeOnSelect\n />\n );\n}\n","import * as React from \"react\";\nimport styled, { css } from \"styled-components\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { focusRing } from \"@sproutsocial/seeds-react-mixins\";\nimport { Popout } from \"@sproutsocial/seeds-react-popout/v2\";\nimport { TreeCombobox } from \"../TreeCombobox\";\nimport { flattenTreeItems } from \"./flattenTree\";\nimport type {\n TreeItemData,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionMode,\n} from \"./types\";\n\nconst invalidStyles = css`\n border-color: ${({ theme }) => theme.colors.form.border.error};\n`;\n\nconst Trigger = styled.button<{ $isInvalid?: boolean; $fullWidth: boolean }>`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ${({ theme }) => theme.space[300]};\n padding: ${({ theme }) => theme.space[200]} ${({ theme }) => theme.space[350]};\n min-width: 160px;\n width: ${({ $fullWidth }) => ($fullWidth ? \"100%\" : \"auto\")};\n border-radius: ${({ theme }) => theme.radii[500]};\n border: 1px solid ${({ theme }) => theme.colors.form.border.base};\n background: ${({ theme }) => theme.colors.form.background.base};\n font-family: ${({ theme }) => theme.fontFamily};\n font-size: ${({ theme }) => theme.typography[200].fontSize};\n line-height: ${({ theme }) => theme.typography[200].lineHeight};\n color: ${({ theme }) => theme.colors.text.body};\n text-align: left;\n cursor: default;\n outline: none;\n user-select: none;\n transition: border-color ${({ theme }) => theme.duration.fast}\n ${({ theme }) => theme.easing.ease_in},\n box-shadow ${({ theme }) => theme.duration.fast}\n ${({ theme }) => theme.easing.ease_in};\n\n &:focus-visible {\n ${focusRing}\n }\n\n &[aria-disabled=\"true\"],\n &:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n ${({ $isInvalid }) => $isInvalid && invalidStyles}\n`;\n\nconst TriggerLabel = styled.span`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst PlaceholderText = styled.span`\n color: ${({ theme }) => theme.colors.text.subtext};\n`;\n\nconst Chevron = styled.span<{ $open: boolean }>`\n display: inline-flex;\n align-items: center;\n color: ${({ theme }) => theme.colors.icon.base};\n transition: transform ${({ theme }) => theme.duration.fast}\n ${({ theme }) => theme.easing.ease_in};\n ${({ $open }) =>\n $open &&\n css`\n transform: rotate(-180deg);\n `}\n`;\n\n/*\n * Visually-hidden input that mirrors the combobox's selected value into a\n * form-submittable element. Matches Base UI's pattern (used by v3\n * SearchableSelect): the input stays in the DOM so HTML forms pick up the\n * value, but it's removed from view and from the accessibility tree.\n */\nconst HiddenInput = styled.input`\n clip-path: inset(50%);\n overflow: hidden;\n white-space: nowrap;\n border: 0;\n padding: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n position: fixed;\n top: 0;\n left: 0;\n`;\n\nconst PopoutContent = styled.div<{ $width?: number | string }>`\n display: flex;\n flex-direction: column;\n /* Width sizes to content within bounds: at least the trigger width, never */\n /* wider than the available viewport space. Shallow popups stay flush with */\n /* the trigger; deeply nested trees expand horizontally as needed. */\n min-width: var(--radix-popover-trigger-width);\n max-width: var(--radix-popper-available-width);\n /* Height caps at 400px (or available viewport) so a popup with many */\n /* expanded branches scrolls vertically instead of growing off-screen. */\n max-height: min(var(--radix-popper-available-height), 400px);\n width: ${({ $width }) =>\n $width === undefined\n ? \"max-content\"\n : typeof $width === \"number\"\n ? `${$width}px`\n : $width};\n`;\n\nconst MAX_INLINE_LABELS = 3;\n\nexport type RenderTrigger = (selected: TreeItemData[]) => React.ReactNode;\n\ntype TreeSearchableSelectBaseProps = {\n items: ReadonlyArray<TreeItemData>;\n\n selectionMode: Exclude<TreeSelectionMode, \"none\">;\n selectableNodes?: TreeSelectableNodes;\n /** Selected ids in the underlying Tree's array form. */\n selectedIds: ReadonlyArray<string>;\n /** Fires with the next selected ids whenever Tree's onSelectionChange fires. */\n onSelectedIdsChange: (ids: string[]) => void;\n\n /** Accessible name for the trigger. Required (label or labelledby). */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n\n /** Trigger placeholder when nothing is selected. */\n placeholder?: string;\n /** Search input placeholder inside the popout. */\n searchPlaceholder?: string;\n /** Empty-state text shown inside the popout when the query has no matches. */\n emptyText?: string;\n\n /** Render override for the trigger label area. Receives resolved selected items. */\n renderTrigger?: RenderTrigger;\n\n /** Open state — controllable. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n /** Close the popout immediately after a selection change. Single-select uses this. */\n closeOnSelect: boolean;\n\n disabled?: boolean;\n isInvalid?: boolean;\n required?: boolean;\n readOnly?: boolean;\n /**\n * Name for the hidden form input. When set, the component participates in\n * native HTML form submission. For multi-select, one `<input type=\"hidden\">`\n * is rendered per selected id under this name (so `formData.getAll(name)`\n * returns every selection).\n */\n name?: string;\n fullWidth?: boolean;\n\n /**\n * Popout content width. Defaults to the trigger's width (via Radix's\n * `--radix-popover-trigger-width`). Pass a number (px) or any valid CSS\n * width string to override.\n */\n contentWidth?: number | string;\n\n /** Tree props passed through. */\n renderSelectionIndicator?: TreeSelectionIndicator;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n id?: string;\n className?: string;\n};\n\nfunction defaultRenderTrigger(\n selected: TreeItemData[],\n placeholder: string\n): React.ReactNode {\n if (selected.length === 0) {\n return <PlaceholderText>{placeholder}</PlaceholderText>;\n }\n if (selected.length <= MAX_INLINE_LABELS) {\n return selected.map((s) => s.label).join(\", \");\n }\n return `${selected.length} selected`;\n}\n\nexport function TreeSearchableSelectBase(props: TreeSearchableSelectBaseProps) {\n const {\n items,\n selectionMode,\n selectableNodes,\n selectedIds,\n onSelectedIdsChange,\n placeholder = \"Select...\",\n searchPlaceholder = \"Search...\",\n emptyText = \"No results found.\",\n renderTrigger,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n closeOnSelect,\n disabled,\n isInvalid,\n required,\n readOnly,\n name,\n fullWidth = true,\n contentWidth,\n renderSelectionIndicator,\n defaultExpanded,\n expanded,\n onExpandedChange,\n id,\n className,\n } = props;\n const ariaLabel = props[\"aria-label\"];\n const ariaLabelledBy = props[\"aria-labelledby\"];\n const ariaDescribedBy = props[\"aria-describedby\"];\n\n const isOpenControlled = openProp !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n const open = isOpenControlled ? !!openProp : uncontrolledOpen;\n const setOpen = (next: boolean) => {\n if (!isOpenControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n };\n\n // Persist the search query across open/close so users don't lose their\n // place after picking a multi-select item.\n const [query, setQuery] = React.useState(\"\");\n\n // Stable id for the popup so the trigger's `aria-controls` resolves to a\n // real DOM element when open. Colons from React.useId() get stripped — axe\n // rejects them inside aria-* attribute values.\n const reactId = React.useId();\n const popupId = `tree-select-popup-${reactId.replace(/:/g, \"\")}`;\n\n // Resolve selected ids to data once per change.\n const flat = React.useMemo(() => flattenTreeItems(items), [items]);\n const selectedItems = React.useMemo(() => {\n const order = new Map(flat.map((it, i) => [it.id, i] as const));\n return selectedIds\n .map((id) => flat.find((it) => it.id === id))\n .filter((it): it is TreeItemData => it != null)\n .sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0));\n }, [flat, selectedIds]);\n\n const handleSelectionChange = (next: string[]) => {\n onSelectedIdsChange(next);\n if (closeOnSelect) {\n setOpen(false);\n }\n };\n\n const triggerContent = renderTrigger\n ? renderTrigger(selectedItems)\n : defaultRenderTrigger(selectedItems, placeholder);\n\n // Hidden input mirrors Base UI's pattern (see v3 SearchableSelect):\n // - Single-select: the primary input carries the value + name, so the\n // form picks it up like any text input.\n // - Multi-select: the primary input has no name (doesn't submit) and a\n // `<input type=\"hidden\">` is rendered per selected id so\n // `formData.getAll(name)` returns every selection.\n // When no `name` is provided, only an id-based primary input is rendered\n // so the `FormField → input` association keeps working.\n const isMulti = selectionMode === \"multiple\";\n const primaryInputName = isMulti ? undefined : name;\n const primaryInputId =\n id && primaryInputName == null ? `${id}-hidden-input` : undefined;\n\n return (\n <>\n <HiddenInput\n type=\"text\"\n id={primaryInputId}\n name={primaryInputName}\n value={isMulti ? \"\" : selectedIds[0] ?? \"\"}\n onChange={() => {\n // Controlled value with no user-driven mutation — value updates come\n // from the combobox's onSelectedIdsChange path, not from the input.\n }}\n disabled={disabled}\n required={required && !isMulti}\n readOnly={readOnly}\n tabIndex={-1}\n aria-hidden=\"true\"\n />\n {isMulti && name\n ? selectedIds.map((selectedId) => (\n <input\n key={selectedId}\n type=\"hidden\"\n name={name}\n value={selectedId}\n />\n ))\n : null}\n <Popout\n open={open}\n onOpenChange={setOpen}\n side=\"bottom\"\n align=\"start\"\n // Popout v2's default has padding: space[400] around its content. Our\n // inner sections (search header + tree list) own their padding, so we\n // strip the outer padding here to match the v3 SearchableSelect popup.\n style={{ padding: 0 }}\n onEscapeKeyDown={(event) => {\n // When the user has a query typed, the first Escape should clear the\n // query (handled inside TreeCombobox) and leave the popout open.\n // The second Escape (with empty query) closes it.\n if (query.length > 0) {\n event.preventDefault();\n }\n }}\n content={\n <PopoutContent id={popupId} $width={contentWidth}>\n <TreeCombobox\n /*\n * The wrapper's `aria-label` / `aria-labelledby` already names the\n * outer trigger combobox. Giving the inner search input the same\n * name produces two `role=\"combobox\"` elements with identical\n * accessible names — confusing for AT and ambiguous for tests.\n * The inner input is the \"search-within-the-popup\" control, so\n * give it a distinct, generic label.\n */\n aria-label=\"Search\"\n items={items}\n placeholder={searchPlaceholder}\n emptyText={emptyText}\n query={query}\n onQueryChange={setQuery}\n selectionMode={selectionMode}\n selectableNodes={selectableNodes}\n selected={selectedIds}\n onSelectionChange={handleSelectionChange}\n renderSelectionIndicator={renderSelectionIndicator}\n defaultExpanded={defaultExpanded}\n expanded={expanded}\n onExpandedChange={onExpandedChange}\n />\n </PopoutContent>\n }\n >\n <Trigger\n type=\"button\"\n id={id}\n className={className}\n $isInvalid={isInvalid}\n $fullWidth={fullWidth}\n disabled={disabled}\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-controls={open ? popupId : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={isInvalid || undefined}\n aria-required={required || undefined}\n >\n <TriggerLabel>{triggerContent}</TriggerLabel>\n <Chevron $open={open} aria-hidden>\n <Icon name=\"chevron-down-outline\" size=\"small\" />\n </Chevron>\n </Trigger>\n </Popout>\n </>\n );\n}\n","import type { TreeItemData } from \"./types\";\n\n/**\n * Walk a tree depth-first and return every item in a flat array, preserving\n * the original visit order.\n *\n * Used by `TreeSearchableSelect` wrappers to resolve selected ids back to\n * their `TreeItemData` for rendering trigger labels.\n */\nexport function flattenTreeItems(\n items: ReadonlyArray<TreeItemData>\n): TreeItemData[] {\n const out: TreeItemData[] = [];\n const walk = (nodes: ReadonlyArray<TreeItemData>) => {\n for (const node of nodes) {\n out.push(node);\n if (node.children) walk(node.children);\n }\n };\n walk(items);\n return out;\n}\n","import * as React from \"react\";\nimport {\n TreeSearchableSelectBase,\n type RenderTrigger,\n} from \"./Common/TreeSearchableSelectBase\";\nimport type {\n TreeItemData,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n} from \"./Common/types\";\n\nexport type MultiTreeSearchableSelectProps = {\n items: ReadonlyArray<TreeItemData>;\n selectableNodes?: TreeSelectableNodes;\n\n selectedItemIds?: ReadonlyArray<string>;\n defaultSelectedItemIds?: ReadonlyArray<string>;\n onSelectedItemIdsChange?: (ids: string[]) => void;\n\n /** Accessible name for the trigger. One of label / labelledby is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n\n /** Render override for the trigger label area. */\n renderTrigger?: RenderTrigger;\n\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n disabled?: boolean;\n isInvalid?: boolean;\n required?: boolean;\n readOnly?: boolean;\n /**\n * Name for the form inputs. Renders one `<input type=\"hidden\">` per selected\n * id under this name so `formData.getAll(name)` returns every selection.\n */\n name?: string;\n fullWidth?: boolean;\n contentWidth?: number | string;\n\n renderSelectionIndicator?: TreeSelectionIndicator;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n id?: string;\n className?: string;\n};\n\n/**\n * Multi-select tree inside a popout, following the same shape as\n * `MultiSearchableSelect`. Picks accumulate; the popout stays open until the\n * user dismisses it (Escape on empty query, outside click, or trigger click).\n */\nexport function MultiTreeSearchableSelect(\n props: MultiTreeSearchableSelectProps\n) {\n const {\n selectedItemIds: selectedItemIdsProp,\n defaultSelectedItemIds,\n onSelectedItemIdsChange,\n ...rest\n } = props;\n\n const isControlled = selectedItemIdsProp !== undefined;\n const [internalIds, setInternalIds] = React.useState<string[]>(() => [\n ...(defaultSelectedItemIds ?? []),\n ]);\n const selectedIds = isControlled ? selectedItemIdsProp ?? [] : internalIds;\n\n const handleSelectedIdsChange = (ids: string[]) => {\n if (!isControlled) setInternalIds(ids);\n onSelectedItemIdsChange?.(ids);\n };\n\n return (\n <TreeSearchableSelectBase\n {...rest}\n selectionMode=\"multiple\"\n selectedIds={selectedIds}\n onSelectedIdsChange={handleSelectedIdsChange}\n closeOnSelect={false}\n />\n );\n}\n"],"mappings":"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","names":["import_react","styled","Tree","React","import_react","import_jsx_runtime","React","import_styled_components","import_seeds_react_icon","import_jsx_runtime","styled","React","React","import_styled_components","import_seeds_react_icon","import_seeds_react_mixins","import_jsx_runtime","styled","id","import_jsx_runtime","React","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Tree.tsx","../src/Common/treeContext.ts","../src/Common/useTreeState.ts","../src/cn.ts","../src/TreeItem.tsx","../src/Common/useTreeKeyboard.ts","../src/Common/treeNavigation.ts","../src/TreeCombobox.tsx","../src/Common/filterTree.ts","../src/SingleTreeSearchableSelect.tsx","../src/Common/TreeSearchableSelectBase.tsx","../src/Common/flattenTree.ts","../src/MultiTreeSearchableSelect.tsx"],"sourcesContent":["export { Tree, type TreeProps } from \"./Tree\";\nexport { TreeItem, type TreeItemProps } from \"./TreeItem\";\nexport { TreeCombobox, type TreeComboboxProps } from \"./TreeCombobox\";\nexport {\n SingleTreeSearchableSelect,\n type SingleTreeSearchableSelectProps,\n} from \"./SingleTreeSearchableSelect\";\nexport {\n MultiTreeSearchableSelect,\n type MultiTreeSearchableSelectProps,\n} from \"./MultiTreeSearchableSelect\";\nexport type {\n TreeItemData,\n TreeSelectionMode,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionIndicatorState,\n} from \"./Common/types\";\n","import * as React from \"react\";\nimport {\n TreeContext,\n TreeItemContext,\n type TreeContextValue,\n} from \"./Common/treeContext\";\nimport { useTreeState } from \"./Common/useTreeState\";\nimport type {\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionMode,\n} from \"./Common/types\";\nimport { cn } from \"./cn\";\n\nexport type TreeProps = {\n children: React.ReactNode;\n /** Accessible name for the tree. One of `aria-label` / `aria-labelledby` is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n\n selectionMode?: TreeSelectionMode;\n selectableNodes?: TreeSelectableNodes;\n\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n defaultSelected?: ReadonlyArray<string>;\n selected?: ReadonlyArray<string>;\n onSelectionChange?: (selected: string[]) => void;\n\n /**\n * Optional render function for a per-item selection indicator (e.g. radio or\n * checkbox). Returns null/undefined for no indicator.\n */\n renderSelectionIndicator?: TreeSelectionIndicator;\n\n /** Item id to receive focus first; defaults to the first treeitem in DOM order. */\n defaultFocusedId?: string;\n /**\n * Controlled focused id. When set, the host owns which item is \"active\" —\n * the roving tabindex target in DOM-focus mode, or the `aria-activedescendant`\n * target in `manageDomFocus={false}` mode.\n */\n focusedId?: string | null;\n onFocusedIdChange?: (id: string | null) => void;\n\n /**\n * When `false`, Tree does not put treeitems in the tab order and does not\n * call `.focus()` on them. Used by `TreeCombobox` so DOM focus can stay on\n * its input while `focusedId` drives `aria-activedescendant`. Defaults to\n * `true`.\n */\n manageDomFocus?: boolean;\n\n className?: string;\n id?: string;\n};\n\nexport const Tree = React.forwardRef<HTMLUListElement, TreeProps>(function Tree(\n props,\n forwardedRef\n) {\n const {\n children,\n selectionMode = \"none\",\n selectableNodes = \"all\",\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n renderSelectionIndicator,\n defaultFocusedId,\n focusedId: focusedIdProp,\n onFocusedIdChange,\n manageDomFocus = true,\n className,\n id,\n } = props;\n\n const ariaLabel = props[\"aria-label\"];\n const ariaLabelledBy = props[\"aria-labelledby\"];\n\n const innerRef = React.useRef<HTMLUListElement>(null);\n React.useImperativeHandle(forwardedRef, () => innerRef.current!, []);\n\n const { expanded, toggleExpanded, selected, toggleSelected } = useTreeState({\n selectionMode,\n selectableNodes,\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n });\n\n const isFocusedControlled = focusedIdProp !== undefined;\n const [internalFocusedId, setInternalFocusedId] = React.useState<\n string | null\n >(defaultFocusedId ?? null);\n const focusedId = isFocusedControlled\n ? focusedIdProp ?? null\n : internalFocusedId;\n\n const setFocusedId = React.useCallback(\n (nextId: string | null) => {\n if (!isFocusedControlled) setInternalFocusedId(nextId);\n onFocusedIdChange?.(nextId);\n },\n [isFocusedControlled, onFocusedIdChange]\n );\n\n const [hasFocused, setHasFocused] = React.useState(false);\n\n // If the focused id points at an item that no longer exists in the DOM\n // (e.g. it was filtered out by a wrapper), reset it to the first visible\n // item so the tree always has a tabbable target. Without this, Tab into\n // the tree lands nowhere and the user has to click to recover.\n React.useLayoutEffect(() => {\n const root = innerRef.current;\n if (!root || focusedId === null) return;\n const stillExists = root.querySelector(\n `[role=\"treeitem\"][data-treeitem-id=\"${CSS.escape(focusedId)}\"]`\n );\n if (stillExists) return;\n const firstVisible = root.querySelector<HTMLElement>('[role=\"treeitem\"]');\n setFocusedId(firstVisible?.dataset.treeitemId ?? null);\n });\n\n const ctxValue = React.useMemo<TreeContextValue>(\n () => ({\n focusedId,\n setFocusedId,\n expanded,\n toggleExpanded,\n selected,\n toggleSelected,\n selectionMode,\n selectableNodes,\n renderSelectionIndicator,\n rootRef: innerRef,\n hasFocused,\n setHasFocused,\n manageDomFocus,\n }),\n [\n focusedId,\n setFocusedId,\n expanded,\n toggleExpanded,\n selected,\n toggleSelected,\n selectionMode,\n selectableNodes,\n renderSelectionIndicator,\n hasFocused,\n manageDomFocus,\n ]\n );\n\n return (\n <TreeContext.Provider value={ctxValue}>\n <TreeItemContext.Provider value={{ level: 1 }}>\n <ul\n ref={innerRef}\n role=\"tree\"\n id={id}\n className={cn(\"seeds-tree\", className)}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-multiselectable={selectionMode === \"multiple\" ? true : undefined}\n >\n {children}\n </ul>\n </TreeItemContext.Provider>\n </TreeContext.Provider>\n );\n});\n","import { createContext, useContext } from \"react\";\nimport type {\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionMode,\n} from \"./types\";\n\nexport type TreeContextValue = {\n /** Roving tabindex / active descendant target. */\n focusedId: string | null;\n setFocusedId: (id: string | null) => void;\n /** Set of expanded branch ids. */\n expanded: ReadonlySet<string>;\n toggleExpanded: (id: string, next?: boolean) => void;\n /** Set of selected ids. */\n selected: ReadonlySet<string>;\n toggleSelected: (id: string, hasChildren: boolean) => void;\n selectionMode: TreeSelectionMode;\n selectableNodes: TreeSelectableNodes;\n renderSelectionIndicator?: TreeSelectionIndicator;\n /** DOM node of the <ul role=\"tree\"> root. Used for DOM-order navigation. */\n rootRef: React.RefObject<HTMLUListElement>;\n /** Whether the tree has received focus yet (controls initial roving tabindex). */\n hasFocused: boolean;\n setHasFocused: (v: boolean) => void;\n /**\n * When true (default), Tree manages DOM focus: items participate in the\n * tab order and `.focus()` is called as the focused id changes. When false,\n * the host (e.g. a combobox input) owns DOM focus and just consumes\n * `focusedId` to drive `aria-activedescendant`.\n */\n manageDomFocus: boolean;\n};\n\nexport const TreeContext = createContext<TreeContextValue | null>(null);\n\nexport function useTreeContext(): TreeContextValue {\n const ctx = useContext(TreeContext);\n if (!ctx) {\n throw new Error(\"TreeItem must be rendered inside a <Tree>.\");\n }\n return ctx;\n}\n\nexport type TreeItemContextValue = {\n /** 1-based depth used for aria-level. */\n level: number;\n};\n\nexport const TreeItemContext = createContext<TreeItemContextValue>({\n level: 1,\n});\n","import { useCallback, useMemo, useState } from \"react\";\nimport type { TreeSelectableNodes, TreeSelectionMode } from \"./types\";\n\ntype UseTreeStateOptions = {\n selectionMode: TreeSelectionMode;\n selectableNodes: TreeSelectableNodes;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n defaultSelected?: ReadonlyArray<string>;\n selected?: ReadonlyArray<string>;\n onSelectionChange?: (selected: string[]) => void;\n};\n\nexport function useTreeState(opts: UseTreeStateOptions) {\n const {\n selectionMode,\n selectableNodes,\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n } = opts;\n\n const [uncontrolledExpanded, setUncontrolledExpanded] = useState<Set<string>>(\n () => new Set(defaultExpanded ?? [])\n );\n const [uncontrolledSelected, setUncontrolledSelected] = useState<Set<string>>(\n () => new Set(defaultSelected ?? [])\n );\n\n const expanded = useMemo(\n () => (expandedProp ? new Set(expandedProp) : uncontrolledExpanded),\n [expandedProp, uncontrolledExpanded]\n );\n\n const selected = useMemo(\n () => (selectedProp ? new Set(selectedProp) : uncontrolledSelected),\n [selectedProp, uncontrolledSelected]\n );\n\n const toggleExpanded = useCallback(\n (id: string, next?: boolean) => {\n const current = expandedProp\n ? new Set(expandedProp)\n : uncontrolledExpanded;\n const willOpen = next ?? !current.has(id);\n const updated = new Set(current);\n if (willOpen) {\n updated.add(id);\n } else {\n updated.delete(id);\n }\n if (!expandedProp) {\n setUncontrolledExpanded(updated);\n }\n onExpandedChange?.(Array.from(updated));\n },\n [expandedProp, uncontrolledExpanded, onExpandedChange]\n );\n\n const toggleSelected = useCallback(\n (id: string, hasChildren: boolean) => {\n if (selectionMode === \"none\") return;\n if (selectableNodes === \"leaves\" && hasChildren) return;\n\n const current = selectedProp\n ? new Set(selectedProp)\n : uncontrolledSelected;\n const updated = new Set<string>();\n\n if (selectionMode === \"single\") {\n if (!current.has(id)) {\n updated.add(id);\n }\n } else {\n current.forEach((v) => updated.add(v));\n if (updated.has(id)) {\n updated.delete(id);\n } else {\n updated.add(id);\n }\n }\n\n if (!selectedProp) {\n setUncontrolledSelected(updated);\n }\n onSelectionChange?.(Array.from(updated));\n },\n [\n selectionMode,\n selectableNodes,\n selectedProp,\n uncontrolledSelected,\n onSelectionChange,\n ]\n );\n\n return {\n expanded,\n toggleExpanded,\n selected,\n toggleSelected,\n };\n}\n","/**\n * Local className merge helper.\n *\n * `cn` is intentionally NOT imported from `@sproutsocial/seeds-react-utilities`\n * (it isn't exported there); each Tailwind/CSS-class Seeds component keeps its\n * own copy, matching the `seeds-react-button` reference.\n */\nexport function cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n","import * as React from \"react\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { TreeItemContext, useTreeContext } from \"./Common/treeContext\";\nimport { useTreeKeyboard } from \"./Common/useTreeKeyboard\";\nimport { treeItemDomId } from \"./Common/treeNavigation\";\nimport { cn } from \"./cn\";\n\nexport type TreeItemProps = {\n id: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n disabled?: boolean;\n children?: React.ReactNode;\n /**\n * Optional override for the row click target. When provided, this is used\n * as the accessible name for the row (otherwise the rendered `label` is).\n */\n \"aria-label\"?: string;\n};\n\nfunction hasTreeItemChildren(children: React.ReactNode): boolean {\n let found = false;\n React.Children.forEach(children, (child) => {\n if (found) return;\n if (!React.isValidElement(child)) return;\n const childType = child.type;\n if (childType === React.Fragment) {\n found = hasTreeItemChildren(\n (child as React.ReactElement<{ children?: React.ReactNode }>).props\n .children\n );\n return;\n }\n // Any other element child counts as a tree item. Consumers should only\n // place TreeItems (or components that render one) inside a TreeItem.\n found = true;\n });\n return found;\n}\n\nexport function TreeItem(props: TreeItemProps) {\n const { id, label, icon, disabled = false, children } = props;\n const ctx = useTreeContext();\n const { level } = React.useContext(TreeItemContext);\n\n const hasChildren = React.useMemo(\n () => hasTreeItemChildren(children),\n [children]\n );\n\n const isExpanded = ctx.expanded.has(id);\n const isSelected = ctx.selected.has(id);\n const selectionMode = ctx.selectionMode;\n\n // Roving tabindex: this item is tabbable when it's the focused id. When the\n // host (e.g. a combobox) drives focus externally, no treeitem is tabbable.\n const itemRef = React.useRef<HTMLLIElement>(null);\n const isTabbable = ctx.manageDomFocus && ctx.focusedId === id;\n\n // On first mount of the very first item, register ourselves as the initial\n // roving target if nothing else has claimed it. Skipped when the host owns\n // focus — the host decides when (if ever) to set an initial active id.\n React.useEffect(() => {\n if (!ctx.manageDomFocus) return;\n if (ctx.focusedId !== null) return;\n const root = ctx.rootRef.current;\n if (!root) return;\n const first = root.querySelector<HTMLElement>('[role=\"treeitem\"]');\n if (first === itemRef.current) {\n ctx.setFocusedId(id);\n }\n // We only want this on mount; deps intentionally minimal.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleKeyDown = useTreeKeyboard(ctx);\n\n const handleRowClick = (e: React.MouseEvent) => {\n if (disabled) return;\n // Ignore clicks that originated on the chevron — it owns its own handler.\n const target = e.target as HTMLElement;\n if (target.closest(\"[data-tree-chevron]\")) return;\n\n ctx.setFocusedId(id);\n if (ctx.manageDomFocus) itemRef.current?.focus();\n\n if (hasChildren && selectionMode === \"none\") {\n ctx.toggleExpanded(id);\n return;\n }\n if (hasChildren && ctx.selectableNodes === \"leaves\") {\n ctx.toggleExpanded(id);\n return;\n }\n if (selectionMode !== \"none\") {\n ctx.toggleSelected(id, hasChildren);\n }\n };\n\n const handleChevronClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (disabled) return;\n ctx.setFocusedId(id);\n if (ctx.manageDomFocus) itemRef.current?.focus();\n ctx.toggleExpanded(id);\n };\n\n const ariaSelected =\n selectionMode === \"single\" && ctx.selectableNodes !== \"leaves\"\n ? isSelected\n : undefined;\n const ariaChecked =\n selectionMode === \"multiple\"\n ? isSelected\n : selectionMode === \"single\" && ctx.selectableNodes === \"leaves\"\n ? isSelected\n : undefined;\n\n const groupId = `${id}__group`;\n const labelId = `${id}__label`;\n\n return (\n <li\n ref={itemRef}\n className=\"seeds-tree-item\"\n id={treeItemDomId(id)}\n role=\"treeitem\"\n data-treeitem-id={id}\n data-treeitem-active={\n !ctx.manageDomFocus && ctx.focusedId === id ? true : undefined\n }\n aria-level={level}\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={ariaSelected}\n aria-checked={ariaChecked}\n aria-disabled={disabled || undefined}\n aria-labelledby={labelId}\n aria-owns={hasChildren && isExpanded ? groupId : undefined}\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => {\n if (!ctx.manageDomFocus) return;\n handleKeyDown(e, {\n id,\n hasChildren,\n isExpanded,\n isDisabled: disabled,\n level,\n });\n }}\n onClick={(e) => {\n // Branch treeitems contain descendant LIs whose row clicks bubble up.\n // Only handle the click if it originated within this LI's own row —\n // not within a descendant treeitem.\n const target = e.target as HTMLElement;\n const nearestTreeitem = target.closest('[role=\"treeitem\"]');\n if (nearestTreeitem !== e.currentTarget) return;\n handleRowClick(e);\n }}\n onMouseDown={(e) => {\n // In external-focus (combobox) mode, mousedown on a tabindex=-1\n // treeitem would still steal DOM focus from the host input. Prevent\n // it so focus stays where the host put it; onClick still fires.\n if (!ctx.manageDomFocus) e.preventDefault();\n }}\n onFocus={() => {\n if (!ctx.manageDomFocus) return;\n if (!ctx.hasFocused) ctx.setHasFocused(true);\n if (ctx.focusedId !== id) ctx.setFocusedId(id);\n }}\n >\n <div\n data-treeitem-row\n className={cn(\"seeds-tree-item-row\", {\n selected: isSelected,\n disabled,\n })}\n style={{ \"--tree-level\": level } as React.CSSProperties}\n >\n {ctx.renderSelectionIndicator &&\n !(ctx.selectableNodes === \"leaves\" && hasChildren)\n ? ctx.renderSelectionIndicator({\n selected: isSelected,\n disabled,\n selectionMode,\n })\n : null}\n\n {icon != null ? (\n <span className=\"seeds-tree-item-icon\" aria-hidden>\n {icon}\n </span>\n ) : null}\n <span className=\"seeds-tree-item-label\" id={labelId}>\n {label}\n </span>\n\n {hasChildren ? (\n <button\n type=\"button\"\n tabIndex={-1}\n data-tree-chevron\n aria-hidden\n className={cn(\"seeds-tree-item-chevron\", {\n expanded: isExpanded,\n })}\n onClick={handleChevronClick}\n >\n <Icon name=\"chevron-down-outline\" size=\"small\" />\n </button>\n ) : null}\n </div>\n\n {hasChildren ? (\n <ul\n className=\"seeds-tree-item-group\"\n role=\"group\"\n id={groupId}\n hidden={!isExpanded}\n >\n <TreeItemContext.Provider value={{ level: level + 1 }}>\n {children}\n </TreeItemContext.Provider>\n </ul>\n ) : null}\n </li>\n );\n}\n\nTreeItem.displayName = \"TreeItem\";\n","import { useCallback, useRef } from \"react\";\nimport type { TreeContextValue } from \"./treeContext\";\nimport {\n computeTreeNavigation,\n getTreeItemId,\n getVisibleTreeItems,\n} from \"./treeNavigation\";\n\nconst TYPEAHEAD_TIMEOUT_MS = 500;\n\nfunction focusItem(el: HTMLElement | undefined) {\n if (!el) return;\n el.focus();\n}\n\n/**\n * Keyboard handler for the WAI-ARIA treeview pattern, bound to each TreeItem\n * via `onKeyDown` when DOM focus lives on treeitems (roving tabindex). The\n * heavy lifting — what to focus next, what to expand/select — is delegated to\n * `computeTreeNavigation` so a combobox host that drives the tree externally\n * can share the exact same navigation rules.\n */\nexport function useTreeKeyboard(ctx: TreeContextValue) {\n const typeaheadBufferRef = useRef(\"\");\n const typeaheadTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleTypeahead = useCallback(\n (char: string, current: HTMLElement, visible: HTMLElement[]) => {\n if (typeaheadTimerRef.current) clearTimeout(typeaheadTimerRef.current);\n typeaheadBufferRef.current = (\n typeaheadBufferRef.current + char\n ).toLowerCase();\n typeaheadTimerRef.current = setTimeout(() => {\n typeaheadBufferRef.current = \"\";\n }, TYPEAHEAD_TIMEOUT_MS);\n\n const buffer = typeaheadBufferRef.current;\n const currentIndex = visible.indexOf(current);\n const ordered = [\n ...visible.slice(currentIndex + 1),\n ...visible.slice(0, currentIndex + 1),\n ];\n const match = ordered.find((el) =>\n (el.textContent ?? \"\").trim().toLowerCase().startsWith(buffer)\n );\n if (match) {\n const id = getTreeItemId(match);\n if (id) ctx.setFocusedId(id);\n focusItem(match);\n }\n },\n [ctx]\n );\n\n return useCallback(\n (\n e: React.KeyboardEvent<HTMLLIElement>,\n itemMeta: {\n id: string;\n hasChildren: boolean;\n isExpanded: boolean;\n isDisabled: boolean;\n level: number;\n }\n ) => {\n if (itemMeta.isDisabled) return;\n // Branch treeitems contain their descendants' LIs, so keydowns bubble up\n // through every ancestor TreeItem. Only handle the keydown on the LI\n // that actually has focus, otherwise ancestor handlers fight the\n // descendant for control of the roving tabindex.\n if (e.target !== e.currentTarget) return;\n\n const root = ctx.rootRef.current;\n const current = e.currentTarget;\n\n const result = computeTreeNavigation(root, current, e.key, {\n id: itemMeta.id,\n hasChildren: itemMeta.hasChildren,\n isExpanded: itemMeta.isExpanded,\n level: itemMeta.level,\n });\n\n if (result.preventDefault) e.preventDefault();\n\n if (result.expandToggle) {\n ctx.toggleExpanded(result.expandToggle.id, result.expandToggle.next);\n }\n if (result.selectToggle) {\n ctx.toggleSelected(\n result.selectToggle.id,\n result.selectToggle.hasChildren\n );\n }\n if (result.expandSiblings) {\n result.expandSiblings.forEach((id) => ctx.toggleExpanded(id, true));\n }\n if (result.nextFocusedId) {\n ctx.setFocusedId(result.nextFocusedId);\n if (ctx.manageDomFocus) {\n const next = root?.querySelector<HTMLElement>(\n `[data-treeitem-id=\"${CSS.escape(result.nextFocusedId)}\"]`\n );\n focusItem(next ?? undefined);\n }\n }\n\n // Printable-char typeahead fires only when the navigation table didn't\n // claim the key. Skip it when DOM focus is external (combobox mode) —\n // there the host input is the type target, not the tree.\n if (\n !result.preventDefault &&\n ctx.manageDomFocus &&\n e.key.length === 1 &&\n /\\S/.test(e.key) &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.altKey\n ) {\n handleTypeahead(e.key, current, getVisibleTreeItems(root));\n }\n },\n [ctx, handleTypeahead]\n );\n}\n","/**\n * Pure navigation logic for the WAI-ARIA treeview pattern.\n *\n * `useTreeKeyboard` uses this when DOM focus lives on the focused treeitem\n * (roving tabindex). A combobox-style host that keeps DOM focus on an input\n * and reflects the active item via `aria-activedescendant` uses the same\n * function — it just skips the `.focus()` step.\n */\n\nexport type TreeNavigationResult = {\n /** True when the caller should call `event.preventDefault()`. */\n preventDefault: boolean;\n /** Item the host should make active next (roving focus / active descendant). */\n nextFocusedId?: string;\n /** Branch to expand or collapse. */\n expandToggle?: { id: string; next?: boolean };\n /** Item whose selection should be toggled (Enter / Space). */\n selectToggle?: { id: string; hasChildren: boolean };\n /** Sibling branch ids to expand (the `*` key). */\n expandSiblings?: string[];\n};\n\nexport function getVisibleTreeItems(root: HTMLElement | null): HTMLElement[] {\n if (!root) return [];\n const all = Array.from(\n root.querySelectorAll<HTMLElement>('[role=\"treeitem\"]')\n );\n return all.filter((el) => {\n if (el.getAttribute(\"aria-disabled\") === \"true\") return false;\n let parent = el.parentElement;\n while (parent && parent !== root) {\n if (\n parent.getAttribute(\"role\") === \"group\" &&\n parent.hasAttribute(\"hidden\")\n ) {\n return false;\n }\n parent = parent.parentElement;\n }\n return true;\n });\n}\n\nexport function getTreeItemId(el: HTMLElement): string | null {\n return el.dataset.treeitemId ?? null;\n}\n\n/** DOM `id` we apply to each treeitem so a combobox host can target it via `aria-activedescendant`. */\nexport function treeItemDomId(itemId: string): string {\n return `${itemId}__item`;\n}\n\nexport type TreeNavigationMeta = {\n id: string;\n hasChildren: boolean;\n isExpanded: boolean;\n level: number;\n};\n\nexport function computeTreeNavigation(\n root: HTMLElement | null,\n currentEl: HTMLElement | null,\n key: string,\n meta: TreeNavigationMeta | null\n): TreeNavigationResult {\n const visible = getVisibleTreeItems(root);\n if (visible.length === 0) return { preventDefault: false };\n\n const idOf = (el: HTMLElement | undefined): string | undefined => {\n if (!el) return undefined;\n return getTreeItemId(el) ?? undefined;\n };\n\n // No current item — ArrowDown/Home land on the first visible item;\n // ArrowUp/End land on the last. (Used by the combobox when the user\n // first presses an arrow with no item highlighted.)\n if (!currentEl || !meta) {\n if (key === \"ArrowDown\" || key === \"Home\") {\n return { preventDefault: true, nextFocusedId: idOf(visible[0]) };\n }\n if (key === \"ArrowUp\" || key === \"End\") {\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[visible.length - 1]),\n };\n }\n return { preventDefault: false };\n }\n\n const currentIndex = visible.indexOf(currentEl);\n if (currentIndex === -1) return { preventDefault: false };\n\n const clamp = (i: number) => Math.max(0, Math.min(visible.length - 1, i));\n\n switch (key) {\n case \"ArrowDown\":\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[clamp(currentIndex + 1)]),\n };\n case \"ArrowUp\":\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[clamp(currentIndex - 1)]),\n };\n case \"ArrowRight\": {\n if (meta.hasChildren && !meta.isExpanded) {\n return {\n preventDefault: true,\n expandToggle: { id: meta.id, next: true },\n };\n }\n if (meta.hasChildren && meta.isExpanded) {\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[clamp(currentIndex + 1)]),\n };\n }\n return { preventDefault: true };\n }\n case \"ArrowLeft\": {\n if (meta.hasChildren && meta.isExpanded) {\n return {\n preventDefault: true,\n expandToggle: { id: meta.id, next: false },\n };\n }\n let parent: HTMLElement | null = currentEl.parentElement;\n while (parent && parent !== root) {\n if (parent.getAttribute(\"role\") === \"group\") {\n const parentItem = parent.parentElement;\n if (parentItem?.getAttribute(\"role\") === \"treeitem\") {\n return {\n preventDefault: true,\n nextFocusedId: idOf(parentItem),\n };\n }\n }\n parent = parent.parentElement;\n }\n return { preventDefault: true };\n }\n case \"Home\":\n return { preventDefault: true, nextFocusedId: idOf(visible[0]) };\n case \"End\":\n return {\n preventDefault: true,\n nextFocusedId: idOf(visible[visible.length - 1]),\n };\n case \"Enter\":\n case \" \":\n return {\n preventDefault: true,\n selectToggle: { id: meta.id, hasChildren: meta.hasChildren },\n };\n case \"*\": {\n const siblings = Array.from(\n currentEl.parentElement?.children ?? []\n ).filter(\n (el): el is HTMLElement =>\n el instanceof HTMLElement && el.getAttribute(\"role\") === \"treeitem\"\n );\n const toExpand = siblings\n .filter((s) => s.getAttribute(\"aria-expanded\") === \"false\")\n .map((s) => getTreeItemId(s))\n .filter((id): id is string => id !== null);\n return { preventDefault: true, expandSiblings: toExpand };\n }\n }\n return { preventDefault: false };\n}\n","import * as React from \"react\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { Tree, type TreeProps } from \"./Tree\";\nimport { TreeItem } from \"./TreeItem\";\nimport { cn } from \"./cn\";\nimport { filterTree } from \"./Common/filterTree\";\nimport { computeTreeNavigation, treeItemDomId } from \"./Common/treeNavigation\";\nimport type { TreeItemData } from \"./Common/types\";\n\nconst NAV_KEYS = new Set([\n \"ArrowDown\",\n \"ArrowUp\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Home\",\n \"End\",\n \"Enter\",\n]);\n\nexport type TreeComboboxProps = Omit<\n TreeProps,\n | \"children\"\n | \"focusedId\"\n | \"onFocusedIdChange\"\n | \"defaultFocusedId\"\n | \"manageDomFocus\"\n | \"aria-label\"\n | \"aria-labelledby\"\n> & {\n items: ReadonlyArray<TreeItemData>;\n /** Placeholder for the combobox input. */\n placeholder?: string;\n /** Text shown when the query has no matches. */\n emptyText?: string;\n /** Accessible name for the combobox. One of `aria-label` / `aria-labelledby` is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n /** Controlled query value. */\n query?: string;\n /** Uncontrolled initial query. */\n defaultQuery?: string;\n onQueryChange?: (query: string) => void;\n};\n\n/**\n * Combobox + tree pattern. Implements the WAI-ARIA combobox pattern with a\n * tree as the popup (`aria-haspopup=\"tree\"`). DOM focus stays on the input;\n * `aria-activedescendant` points at the active treeitem, which the input's\n * arrow-key handler moves through the visible tree. Selection and expansion\n * reuse the underlying Tree's logic — Enter on the input synthesizes a click\n * on the active row, ArrowRight/Left compute the new expanded set and pass\n * it through Tree's controlled `expanded` prop.\n */\nexport function TreeCombobox(props: TreeComboboxProps) {\n const {\n items,\n placeholder = \"Search...\",\n emptyText = \"No results found.\",\n query: queryProp,\n defaultQuery = \"\",\n onQueryChange,\n selectionMode = \"none\",\n selectableNodes = \"all\",\n defaultExpanded,\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected,\n selected: selectedProp,\n onSelectionChange,\n renderSelectionIndicator,\n id,\n className,\n } = props;\n const ariaLabel = props[\"aria-label\"];\n const ariaLabelledBy = props[\"aria-labelledby\"];\n\n const [uncontrolledQuery, setUncontrolledQuery] =\n React.useState(defaultQuery);\n const query = queryProp ?? uncontrolledQuery;\n const setQuery = (next: string) => {\n if (queryProp === undefined) setUncontrolledQuery(next);\n onQueryChange?.(next);\n };\n\n // Track the user's last \"real\" expansion state so it can be restored when\n // the query clears, matching the prior SearchableTree behavior.\n const [userExpanded, setUserExpanded] = React.useState<string[]>(() => [\n ...(defaultExpanded ?? expandedProp ?? []),\n ]);\n\n const { items: visibleItems, forceExpanded } = React.useMemo(\n () => filterTree([...items], query),\n [items, query]\n );\n\n const isFiltering = query.trim().length > 0;\n const effectiveExpanded = isFiltering\n ? Array.from(new Set([...userExpanded, ...forceExpanded]))\n : expandedProp ?? userExpanded;\n\n const handleExpandedChange = (next: string[]) => {\n if (!isFiltering) {\n setUserExpanded(next);\n }\n onExpandedChange?.(next);\n };\n\n const [focusedId, setFocusedId] = React.useState<string | null>(null);\n\n const treeRef = React.useRef<HTMLUListElement>(null);\n const reactId = React.useId();\n const treeDomId = id ? `${id}-tree` : `${reactId}-tree`;\n\n const findTreeItemEl = (itemId: string): HTMLElement | null =>\n treeRef.current?.querySelector<HTMLElement>(\n `[role=\"treeitem\"][data-treeitem-id=\"${CSS.escape(itemId)}\"]`\n ) ?? null;\n\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n if (query.length > 0) {\n e.preventDefault();\n setQuery(\"\");\n setFocusedId(null);\n }\n return;\n }\n if (!NAV_KEYS.has(e.key)) return;\n\n const currentEl = focusedId ? findTreeItemEl(focusedId) : null;\n const meta =\n currentEl && focusedId\n ? {\n id: focusedId,\n hasChildren: currentEl.getAttribute(\"aria-expanded\") !== null,\n isExpanded: currentEl.getAttribute(\"aria-expanded\") === \"true\",\n level: parseInt(currentEl.getAttribute(\"aria-level\") ?? \"1\", 10),\n }\n : null;\n\n // Enter: replay a row click on the active treeitem so we get TreeItem's\n // exact selection/expansion semantics (single vs multi, leaves-only,\n // branch-vs-leaf) for free.\n if (e.key === \"Enter\") {\n if (!currentEl) return;\n e.preventDefault();\n const row = currentEl.querySelector<HTMLElement>(\"[data-treeitem-row]\");\n row?.click();\n return;\n }\n\n const result = computeTreeNavigation(\n treeRef.current,\n currentEl,\n e.key,\n meta\n );\n if (result.preventDefault) e.preventDefault();\n\n if (result.expandToggle) {\n const current = new Set(effectiveExpanded);\n const willOpen =\n result.expandToggle.next ?? !current.has(result.expandToggle.id);\n if (willOpen) current.add(result.expandToggle.id);\n else current.delete(result.expandToggle.id);\n handleExpandedChange(Array.from(current));\n }\n if (result.nextFocusedId) {\n setFocusedId(result.nextFocusedId);\n }\n };\n\n // If a filter change drops the active item out of the visible set, the\n // Tree's recovery layout-effect rebases focusedId via onFocusedIdChange.\n // We accept that and don't reset focusedId on filter ourselves — clearing\n // happens explicitly on Escape.\n\n // Keep the active treeitem visible as the user navigates with the\n // keyboard. In DOM-focus mode the browser auto-scrolls on `.focus()`, but\n // combobox mode skips that call (focus stays on the input), so we have to\n // scroll explicitly to meet the WAI-ARIA combobox/treeview expectation\n // that the active option stays in view. `block: \"nearest\"` only scrolls\n // when the row is actually off-screen.\n React.useLayoutEffect(() => {\n if (!focusedId) return;\n const itemEl = findTreeItemEl(focusedId);\n const row =\n itemEl?.querySelector<HTMLElement>(\"[data-treeitem-row]\") ?? itemEl;\n // jsdom doesn't implement scrollIntoView; bail there.\n if (row && typeof row.scrollIntoView === \"function\") {\n row.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n }\n // findTreeItemEl is read from a ref so it doesn't need to be a dep.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [focusedId]);\n\n const showEmpty = visibleItems.length === 0;\n\n return (\n <div className={cn(\"seeds-tree-combobox\", className)}>\n <div className=\"seeds-tree-combobox-search\">\n <div className=\"seeds-tree-combobox-input-group\">\n <Icon name=\"magnifying-glass-outline\" size=\"small\" aria-hidden />\n <input\n className=\"seeds-tree-combobox-input\"\n type=\"text\"\n role=\"combobox\"\n id={id}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-expanded={!showEmpty}\n aria-controls={treeDomId}\n aria-haspopup=\"tree\"\n aria-autocomplete=\"list\"\n aria-activedescendant={\n focusedId ? treeItemDomId(focusedId) : undefined\n }\n placeholder={placeholder}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={handleInputKeyDown}\n />\n </div>\n </div>\n\n <div className=\"seeds-tree-combobox-list\">\n <Tree\n ref={treeRef}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n id={treeDomId}\n manageDomFocus={false}\n selectionMode={selectionMode}\n selectableNodes={selectableNodes}\n expanded={effectiveExpanded}\n onExpandedChange={handleExpandedChange}\n selected={selectedProp}\n defaultSelected={defaultSelected}\n onSelectionChange={onSelectionChange}\n renderSelectionIndicator={renderSelectionIndicator}\n focusedId={focusedId}\n onFocusedIdChange={setFocusedId}\n >\n {visibleItems.map((item) => (\n <TreeNode key={item.id} item={item} />\n ))}\n </Tree>\n\n {showEmpty ? (\n <div\n className=\"seeds-tree-combobox-empty\"\n role=\"status\"\n aria-live=\"polite\"\n >\n {emptyText}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction TreeNode({ item }: { item: TreeItemData }) {\n return (\n <TreeItem\n id={item.id}\n label={item.label}\n icon={item.icon}\n disabled={item.disabled}\n >\n {item.children?.map((child) => (\n <TreeNode key={child.id} item={child} />\n ))}\n </TreeItem>\n );\n}\n","import type { TreeItemData } from \"./types\";\n\nexport type FilterResult = {\n /** Items to render (parents with no matching descendants are removed). */\n items: TreeItemData[];\n /** Ids of branches that should be force-expanded so matches are visible. */\n forceExpanded: string[];\n};\n\n/**\n * Returns the subtree of items where `label` (or any descendant label) matches\n * `query`, plus the set of branch ids that should be opened to reveal matches.\n *\n * Why: TreeCombobox needs both a filtered list and the ancestor ids of every\n * match so users can see what their search hit.\n * How to apply: pass the result to <Tree expanded={...}>.\n */\nexport function filterTree(\n items: ReadonlyArray<TreeItemData>,\n query: string\n): FilterResult {\n const normalized = query.trim().toLowerCase();\n if (!normalized) {\n return { items: [...items], forceExpanded: [] };\n }\n\n const forceExpanded = new Set<string>();\n\n const walk = (node: TreeItemData): TreeItemData | null => {\n const matches = node.label.toLowerCase().includes(normalized);\n const filteredChildren = (node.children ?? [])\n .map(walk)\n .filter((c): c is TreeItemData => c !== null);\n\n if (filteredChildren.length > 0 && node.children) {\n forceExpanded.add(node.id);\n }\n\n if (matches || filteredChildren.length > 0) {\n return {\n ...node,\n children: node.children ? filteredChildren : undefined,\n };\n }\n return null;\n };\n\n const filtered = items.map(walk).filter((n): n is TreeItemData => n !== null);\n\n return { items: filtered, forceExpanded: Array.from(forceExpanded) };\n}\n","import * as React from \"react\";\nimport {\n TreeSearchableSelectBase,\n type RenderTrigger,\n} from \"./Common/TreeSearchableSelectBase\";\nimport type {\n TreeItemData,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n} from \"./Common/types\";\n\nexport type SingleTreeSearchableSelectProps = {\n items: ReadonlyArray<TreeItemData>;\n selectableNodes?: TreeSelectableNodes;\n\n selectedItemId?: string | null;\n defaultSelectedItemId?: string | null;\n onSelectedItemIdChange?: (id: string | null) => void;\n\n /** Accessible name for the trigger. One of label / labelledby is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n\n /** Render override for the trigger label area. */\n renderTrigger?: RenderTrigger;\n\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n disabled?: boolean;\n isInvalid?: boolean;\n required?: boolean;\n readOnly?: boolean;\n /** Name for the hidden form input, enabling participation in native form submission. */\n name?: string;\n fullWidth?: boolean;\n contentWidth?: number | string;\n\n renderSelectionIndicator?: TreeSelectionIndicator;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n id?: string;\n className?: string;\n};\n\n/**\n * Single-select tree inside a popout, following the same shape as\n * `SingleSearchableSelect`. Picks close the popout and return focus to the\n * trigger.\n */\nexport function SingleTreeSearchableSelect(\n props: SingleTreeSearchableSelectProps\n) {\n const {\n selectedItemId: selectedItemIdProp,\n defaultSelectedItemId = null,\n onSelectedItemIdChange,\n ...rest\n } = props;\n\n const isControlled = selectedItemIdProp !== undefined;\n const [internalId, setInternalId] = React.useState<string | null>(\n defaultSelectedItemId\n );\n const selectedItemId = isControlled ? selectedItemIdProp ?? null : internalId;\n\n const selectedIds = React.useMemo(\n () => (selectedItemId ? [selectedItemId] : []),\n [selectedItemId]\n );\n\n const handleSelectedIdsChange = (ids: string[]) => {\n const next = ids[0] ?? null;\n if (!isControlled) setInternalId(next);\n onSelectedItemIdChange?.(next);\n };\n\n return (\n <TreeSearchableSelectBase\n {...rest}\n selectionMode=\"single\"\n selectedIds={selectedIds}\n onSelectedIdsChange={handleSelectedIdsChange}\n closeOnSelect\n />\n );\n}\n","import * as React from \"react\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { Popout } from \"@sproutsocial/seeds-react-popout/v2\";\nimport { TreeCombobox } from \"../TreeCombobox\";\nimport { cn } from \"../cn\";\nimport { flattenTreeItems } from \"./flattenTree\";\nimport type {\n TreeItemData,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n TreeSelectionMode,\n} from \"./types\";\n\nconst MAX_INLINE_LABELS = 3;\n\n/** Resolve the popout width prop to a CSS length for `--tree-select-width`. */\nfunction popoutWidth(width?: number | string): string | undefined {\n if (width === undefined) return undefined;\n return typeof width === \"number\" ? `${width}px` : width;\n}\n\nexport type RenderTrigger = (selected: TreeItemData[]) => React.ReactNode;\n\ntype TreeSearchableSelectBaseProps = {\n items: ReadonlyArray<TreeItemData>;\n\n selectionMode: Exclude<TreeSelectionMode, \"none\">;\n selectableNodes?: TreeSelectableNodes;\n /** Selected ids in the underlying Tree's array form. */\n selectedIds: ReadonlyArray<string>;\n /** Fires with the next selected ids whenever Tree's onSelectionChange fires. */\n onSelectedIdsChange: (ids: string[]) => void;\n\n /** Accessible name for the trigger. Required (label or labelledby). */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n\n /** Trigger placeholder when nothing is selected. */\n placeholder?: string;\n /** Search input placeholder inside the popout. */\n searchPlaceholder?: string;\n /** Empty-state text shown inside the popout when the query has no matches. */\n emptyText?: string;\n\n /** Render override for the trigger label area. Receives resolved selected items. */\n renderTrigger?: RenderTrigger;\n\n /** Open state — controllable. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n /** Close the popout immediately after a selection change. Single-select uses this. */\n closeOnSelect: boolean;\n\n disabled?: boolean;\n isInvalid?: boolean;\n required?: boolean;\n readOnly?: boolean;\n /**\n * Name for the hidden form input. When set, the component participates in\n * native HTML form submission. For multi-select, one `<input type=\"hidden\">`\n * is rendered per selected id under this name (so `formData.getAll(name)`\n * returns every selection).\n */\n name?: string;\n fullWidth?: boolean;\n\n /**\n * Popout content width. Defaults to the trigger's width (via Radix's\n * `--radix-popover-trigger-width`). Pass a number (px) or any valid CSS\n * width string to override.\n */\n contentWidth?: number | string;\n\n /** Tree props passed through. */\n renderSelectionIndicator?: TreeSelectionIndicator;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n id?: string;\n className?: string;\n};\n\nfunction defaultRenderTrigger(\n selected: TreeItemData[],\n placeholder: string\n): React.ReactNode {\n if (selected.length === 0) {\n return (\n <span className=\"seeds-tree-select-placeholder\">{placeholder}</span>\n );\n }\n if (selected.length <= MAX_INLINE_LABELS) {\n return selected.map((s) => s.label).join(\", \");\n }\n return `${selected.length} selected`;\n}\n\nexport function TreeSearchableSelectBase(props: TreeSearchableSelectBaseProps) {\n const {\n items,\n selectionMode,\n selectableNodes,\n selectedIds,\n onSelectedIdsChange,\n placeholder = \"Select...\",\n searchPlaceholder = \"Search...\",\n emptyText = \"No results found.\",\n renderTrigger,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n closeOnSelect,\n disabled,\n isInvalid,\n required,\n readOnly,\n name,\n fullWidth = true,\n contentWidth,\n renderSelectionIndicator,\n defaultExpanded,\n expanded,\n onExpandedChange,\n id,\n className,\n } = props;\n const ariaLabel = props[\"aria-label\"];\n const ariaLabelledBy = props[\"aria-labelledby\"];\n const ariaDescribedBy = props[\"aria-describedby\"];\n\n const isOpenControlled = openProp !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n const open = isOpenControlled ? !!openProp : uncontrolledOpen;\n const setOpen = (next: boolean) => {\n if (!isOpenControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n };\n\n // Persist the search query across open/close so users don't lose their\n // place after picking a multi-select item.\n const [query, setQuery] = React.useState(\"\");\n\n // Stable id for the popup so the trigger's `aria-controls` resolves to a\n // real DOM element when open. Colons from React.useId() get stripped — axe\n // rejects them inside aria-* attribute values.\n const reactId = React.useId();\n const popupId = `tree-select-popup-${reactId.replace(/:/g, \"\")}`;\n\n // Resolve selected ids to data once per change.\n const flat = React.useMemo(() => flattenTreeItems(items), [items]);\n const selectedItems = React.useMemo(() => {\n const order = new Map(flat.map((it, i) => [it.id, i] as const));\n return selectedIds\n .map((id) => flat.find((it) => it.id === id))\n .filter((it): it is TreeItemData => it != null)\n .sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0));\n }, [flat, selectedIds]);\n\n const handleSelectionChange = (next: string[]) => {\n onSelectedIdsChange(next);\n if (closeOnSelect) {\n setOpen(false);\n }\n };\n\n const triggerContent = renderTrigger\n ? renderTrigger(selectedItems)\n : defaultRenderTrigger(selectedItems, placeholder);\n\n // Hidden input mirrors Base UI's pattern (see v3 SearchableSelect):\n // - Single-select: the primary input carries the value + name, so the\n // form picks it up like any text input.\n // - Multi-select: the primary input has no name (doesn't submit) and a\n // `<input type=\"hidden\">` is rendered per selected id so\n // `formData.getAll(name)` returns every selection.\n // When no `name` is provided, only an id-based primary input is rendered\n // so the `FormField → input` association keeps working.\n const isMulti = selectionMode === \"multiple\";\n const primaryInputName = isMulti ? undefined : name;\n const primaryInputId =\n id && primaryInputName == null ? `${id}-hidden-input` : undefined;\n\n return (\n <>\n <input\n className=\"seeds-tree-select-hidden-input\"\n type=\"text\"\n id={primaryInputId}\n name={primaryInputName}\n value={isMulti ? \"\" : selectedIds[0] ?? \"\"}\n onChange={() => {\n // Controlled value with no user-driven mutation — value updates come\n // from the combobox's onSelectedIdsChange path, not from the input.\n }}\n disabled={disabled}\n required={required && !isMulti}\n readOnly={readOnly}\n tabIndex={-1}\n aria-hidden=\"true\"\n />\n {isMulti && name\n ? selectedIds.map((selectedId) => (\n <input\n key={selectedId}\n type=\"hidden\"\n name={name}\n value={selectedId}\n />\n ))\n : null}\n <Popout\n open={open}\n onOpenChange={setOpen}\n side=\"bottom\"\n align=\"start\"\n // Popout v2's default has padding: space[400] around its content. Our\n // inner sections (search header + tree list) own their padding, so we\n // strip the outer padding here to match the v3 SearchableSelect popup.\n style={{ padding: 0 }}\n onEscapeKeyDown={(event) => {\n // When the user has a query typed, the first Escape should clear the\n // query (handled inside TreeCombobox) and leave the popout open.\n // The second Escape (with empty query) closes it.\n if (query.length > 0) {\n event.preventDefault();\n }\n }}\n content={\n <div\n className=\"seeds-tree-select-popout\"\n id={popupId}\n style={\n {\n \"--tree-select-width\": popoutWidth(contentWidth),\n } as React.CSSProperties\n }\n >\n <TreeCombobox\n /*\n * The wrapper's `aria-label` / `aria-labelledby` already names the\n * outer trigger combobox. Giving the inner search input the same\n * name produces two `role=\"combobox\"` elements with identical\n * accessible names — confusing for AT and ambiguous for tests.\n * The inner input is the \"search-within-the-popup\" control, so\n * give it a distinct, generic label.\n */\n aria-label=\"Search\"\n items={items}\n placeholder={searchPlaceholder}\n emptyText={emptyText}\n query={query}\n onQueryChange={setQuery}\n selectionMode={selectionMode}\n selectableNodes={selectableNodes}\n selected={selectedIds}\n onSelectionChange={handleSelectionChange}\n renderSelectionIndicator={renderSelectionIndicator}\n defaultExpanded={defaultExpanded}\n expanded={expanded}\n onExpandedChange={onExpandedChange}\n />\n </div>\n }\n >\n <button\n className={cn(\"seeds-tree-select-trigger\", className, {\n \"full-width\": fullWidth,\n invalid: !!isInvalid,\n })}\n type=\"button\"\n id={id}\n disabled={disabled}\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-controls={open ? popupId : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={isInvalid || undefined}\n aria-required={required || undefined}\n >\n <span className=\"seeds-tree-select-trigger-label\">\n {triggerContent}\n </span>\n <span\n className={cn(\"seeds-tree-select-chevron\", { open })}\n aria-hidden\n >\n <Icon name=\"chevron-down-outline\" size=\"small\" />\n </span>\n </button>\n </Popout>\n </>\n );\n}\n","import type { TreeItemData } from \"./types\";\n\n/**\n * Walk a tree depth-first and return every item in a flat array, preserving\n * the original visit order.\n *\n * Used by `TreeSearchableSelect` wrappers to resolve selected ids back to\n * their `TreeItemData` for rendering trigger labels.\n */\nexport function flattenTreeItems(\n items: ReadonlyArray<TreeItemData>\n): TreeItemData[] {\n const out: TreeItemData[] = [];\n const walk = (nodes: ReadonlyArray<TreeItemData>) => {\n for (const node of nodes) {\n out.push(node);\n if (node.children) walk(node.children);\n }\n };\n walk(items);\n return out;\n}\n","import * as React from \"react\";\nimport {\n TreeSearchableSelectBase,\n type RenderTrigger,\n} from \"./Common/TreeSearchableSelectBase\";\nimport type {\n TreeItemData,\n TreeSelectableNodes,\n TreeSelectionIndicator,\n} from \"./Common/types\";\n\nexport type MultiTreeSearchableSelectProps = {\n items: ReadonlyArray<TreeItemData>;\n selectableNodes?: TreeSelectableNodes;\n\n selectedItemIds?: ReadonlyArray<string>;\n defaultSelectedItemIds?: ReadonlyArray<string>;\n onSelectedItemIdsChange?: (ids: string[]) => void;\n\n /** Accessible name for the trigger. One of label / labelledby is required. */\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n\n /** Render override for the trigger label area. */\n renderTrigger?: RenderTrigger;\n\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n\n disabled?: boolean;\n isInvalid?: boolean;\n required?: boolean;\n readOnly?: boolean;\n /**\n * Name for the form inputs. Renders one `<input type=\"hidden\">` per selected\n * id under this name so `formData.getAll(name)` returns every selection.\n */\n name?: string;\n fullWidth?: boolean;\n contentWidth?: number | string;\n\n renderSelectionIndicator?: TreeSelectionIndicator;\n defaultExpanded?: ReadonlyArray<string>;\n expanded?: ReadonlyArray<string>;\n onExpandedChange?: (expanded: string[]) => void;\n\n id?: string;\n className?: string;\n};\n\n/**\n * Multi-select tree inside a popout, following the same shape as\n * `MultiSearchableSelect`. Picks accumulate; the popout stays open until the\n * user dismisses it (Escape on empty query, outside click, or trigger click).\n */\nexport function MultiTreeSearchableSelect(\n props: MultiTreeSearchableSelectProps\n) {\n const {\n selectedItemIds: selectedItemIdsProp,\n defaultSelectedItemIds,\n onSelectedItemIdsChange,\n ...rest\n } = props;\n\n const isControlled = selectedItemIdsProp !== undefined;\n const [internalIds, setInternalIds] = React.useState<string[]>(() => [\n ...(defaultSelectedItemIds ?? []),\n ]);\n const selectedIds = isControlled ? selectedItemIdsProp ?? [] : internalIds;\n\n const handleSelectedIdsChange = (ids: string[]) => {\n if (!isControlled) setInternalIds(ids);\n onSelectedItemIdsChange?.(ids);\n };\n\n return (\n <TreeSearchableSelectBase\n {...rest}\n selectionMode=\"multiple\"\n selectedIds={selectedIds}\n onSelectedIdsChange={handleSelectedIdsChange}\n closeOnSelect={false}\n />\n );\n}\n"],"mappings":"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","names":["import_react","Tree","React","import_react","import_jsx_runtime","React","import_seeds_react_icon","import_jsx_runtime","React","React","import_seeds_react_icon","import_jsx_runtime","id","import_jsx_runtime","React","import_jsx_runtime"]}