@voxel51/voodo 0.0.30 → 0.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/components/Checkbox/Checkbox.d.ts +3 -0
  2. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  3. package/dist/components/Pill/Pill.d.ts +1 -0
  4. package/dist/components/Pill/Pill.d.ts.map +1 -1
  5. package/dist/components/TreeSelect/TreeSelect.d.ts +33 -0
  6. package/dist/components/TreeSelect/TreeSelect.d.ts.map +1 -0
  7. package/dist/components/TreeSelect/TreeSelectNode.d.ts +21 -0
  8. package/dist/components/TreeSelect/TreeSelectNode.d.ts.map +1 -0
  9. package/dist/components/TreeSelect/TreeSelectPanel.d.ts +21 -0
  10. package/dist/components/TreeSelect/TreeSelectPanel.d.ts.map +1 -0
  11. package/dist/components/TreeSelect/TreeSelectSearchInput.d.ts +16 -0
  12. package/dist/components/TreeSelect/TreeSelectSearchInput.d.ts.map +1 -0
  13. package/dist/components/TreeSelect/TreeSelectTrigger.d.ts +22 -0
  14. package/dist/components/TreeSelect/TreeSelectTrigger.d.ts.map +1 -0
  15. package/dist/components/TreeSelect/index.d.ts +4 -0
  16. package/dist/components/TreeSelect/index.d.ts.map +1 -0
  17. package/dist/components/TreeSelect/tree.d.ts +100 -0
  18. package/dist/components/TreeSelect/tree.d.ts.map +1 -0
  19. package/dist/components/TreeSelect/types.d.ts +163 -0
  20. package/dist/components/TreeSelect/types.d.ts.map +1 -0
  21. package/dist/components/index.d.ts +1 -0
  22. package/dist/components/index.d.ts.map +1 -1
  23. package/dist/index.cjs +6 -6
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.js +7865 -6355
  26. package/dist/index.js.map +1 -1
  27. package/dist/util/useTree.d.ts +126 -0
  28. package/dist/util/useTree.d.ts.map +1 -0
  29. package/dist/voodo.css +1 -1
  30. package/package.json +3 -1
@@ -4,6 +4,7 @@ type ModifiedCheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, "size"
4
4
  export interface CheckboxProps extends ModifiedCheckboxProps {
5
5
  checked?: boolean;
6
6
  onChange?: (checked: boolean) => void;
7
+ indeterminate?: boolean;
7
8
  label?: string;
8
9
  disabled?: boolean;
9
10
  size?: Size;
@@ -34,6 +35,8 @@ export interface CheckboxProps extends ModifiedCheckboxProps {
34
35
  *
35
36
  * @param checked `checked` state of the checkbox.
36
37
  * @param onChange Change handler for when the checked state changes.
38
+ * @param indeterminate When true (and `checked` is false), renders a dash icon,
39
+ * indicating partial selection among descendants. Ignored when `checked` is true.
37
40
  * @param size Size of the checkbox; this controls both the checkbox itself and the associated label. See {@link Size}.
38
41
  * @param radius Border radius of the checkbox; this controls the styling of the checkbox itself. See {@link Radius}.
39
42
  * @param className `class` overrides to apply to the checkbox.
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAMrD,OAAO,EAOL,MAAM,EACN,IAAI,EAGL,MAAM,SAAS,CAAC;AAGjB,KAAK,qBAAqB,GAAG,IAAI,CAC/B,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAC3D,CAAC;AAEF,MAAM,WAAW,aAAc,SAAQ,qBAAqB;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CA6DtC,CAAC"}
1
+ {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAMrD,OAAO,EAQL,MAAM,EACN,IAAI,EAGL,MAAM,SAAS,CAAC;AAGjB,KAAK,qBAAqB,GAAG,IAAI,CAC/B,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAC3D,CAAC;AAEF,MAAM,WAAW,aAAc,SAAQ,qBAAqB;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CA0EtC,CAAC"}
@@ -10,6 +10,7 @@ export interface PillProps extends HTMLAttributes<HTMLSpanElement> {
10
10
  isStatus?: boolean;
11
11
  backgroundColor?: PillColor;
12
12
  icon?: IconName;
13
+ onRemove?: () => void;
13
14
  }
14
15
  /**
15
16
  * A basic pill component.
@@ -1 +1 @@
1
- {"version":3,"file":"Pill.d.ts","sourceRoot":"","sources":["../../../src/components/Pill/Pill.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAMhD,OAAO,EACL,eAAe,EACf,QAAQ,EACR,MAAM,EACN,aAAa,EACb,MAAM,EACN,IAAI,EAEJ,WAAW,EACX,SAAS,EACV,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AACxD,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,aAAa,GAAG,WAAW,CAAC;AAEtE,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,eAAe,CAAC;IAChE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAQD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CA6C9B,CAAC"}
1
+ {"version":3,"file":"Pill.d.ts","sourceRoot":"","sources":["../../../src/components/Pill/Pill.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAMhD,OAAO,EACL,eAAe,EACf,QAAQ,EACR,MAAM,EACN,aAAa,EACb,MAAM,EACN,IAAI,EAEJ,WAAW,EACX,SAAS,EACV,MAAM,SAAS,CAAC;AAIjB,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;AACxD,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,aAAa,GAAG,WAAW,CAAC;AAEtE,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,eAAe,CAAC;IAChE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAQD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAoE9B,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { FC } from 'react';
2
+ import { TreeSelectProps } from './types';
3
+ /**
4
+ * A tree-shaped selection control that renders nodes in a
5
+ * searchable dropdown panel styled to match {@link Select}.
6
+ *
7
+ * Supports single-select with full keyboard navigation (ARIA treeview pattern).
8
+ *
9
+ * Paths are represented as {@link TreePath} — ordered arrays of raw node
10
+ * names. No encoding is needed, even when names contain `/` or `%`.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const tree: TreeNode = {
15
+ * name: "vehicle_type",
16
+ * values: [
17
+ * { name: "car", values: [{ name: "Honda" }, { name: "Toyota" }] },
18
+ * { name: "motorcycle" },
19
+ * ],
20
+ * };
21
+ *
22
+ * const [value, setValue] = useState<TreePath | undefined>();
23
+ *
24
+ * <TreeSelect
25
+ * root={tree}
26
+ * value={value}
27
+ * onChange={(path) => setValue(path ?? undefined)}
28
+ * placeholder="Select a vehicle…"
29
+ * />
30
+ * ```
31
+ */
32
+ export declare const TreeSelect: FC<TreeSelectProps>;
33
+ //# sourceMappingURL=TreeSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeSelect.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/TreeSelect.tsx"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,EAAE,EAMR,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EAAsB,eAAe,EAAE,MAAM,SAAS,CAAC;AAWnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAoV1C,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { FC } from 'react';
2
+ import { UseTreeReturn } from '../../util/useTree';
3
+ import { ResolvedNode } from './types';
4
+ export interface TreeSelectNodeProps {
5
+ resolved: ResolvedNode;
6
+ tree: UseTreeReturn;
7
+ query?: string;
8
+ multiSelect?: boolean;
9
+ onRetryLoad?: (path: string) => void;
10
+ }
11
+ /**
12
+ * Renders a single node row. The parent renders a flat list of all visible
13
+ * nodes (via `tree.visibleNodes`), so this component never recurses.
14
+ * Depth-based indentation produces the visual tree hierarchy.
15
+ * All state is driven by the `tree` hook — this component is purely
16
+ * presentational.
17
+ *
18
+ * @internal For use by TreeSelectPanel.
19
+ */
20
+ export declare const TreeSelectNode: FC<TreeSelectNodeProps>;
21
+ //# sourceMappingURL=TreeSelectNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeSelectNode.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/TreeSelectNode.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAwBvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAqBD;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAgKlD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { CSSProperties, FC, RefObject } from 'react';
2
+ import { ZIndex } from '../../types';
3
+ import { UseTreeReturn } from '../../util/useTree';
4
+ export interface TreeSelectPanelProps {
5
+ floatingRef: (node: HTMLElement | null) => void;
6
+ floatingStyles: CSSProperties;
7
+ portal?: boolean;
8
+ zIndex?: ZIndex;
9
+ panelId: string;
10
+ query: string;
11
+ onQueryChange: (q: string) => void;
12
+ debouncedQuery: string;
13
+ searchInputRef: RefObject<HTMLInputElement | null>;
14
+ tree: UseTreeReturn;
15
+ filteredTree: boolean;
16
+ multiSelect?: boolean;
17
+ onRetryLoad?: (path: string) => void;
18
+ panelMaxHeight?: string;
19
+ }
20
+ export declare const TreeSelectPanel: FC<TreeSelectPanelProps>;
21
+ //# sourceMappingURL=TreeSelectPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeSelectPanel.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/TreeSelectPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,EAAE,EAGP,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAMf,OAAO,EAUL,MAAM,EAEP,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AA4BpD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACnD,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAeD,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAmHpD,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { FC, KeyboardEvent, Ref } from 'react';
2
+ export interface TreeSelectSearchInputProps {
3
+ value: string;
4
+ onChange: (value: string) => void;
5
+ onKeyDown: (e: KeyboardEvent) => void;
6
+ inputRef: Ref<HTMLInputElement>;
7
+ activeDescendantId?: string;
8
+ }
9
+ /**
10
+ * Sticky search bar rendered at the top of the TreeSelect panel.
11
+ * Owns the magnifier icon, text input, and clear button.
12
+ *
13
+ * @internal For use by TreeSelectPanel.
14
+ */
15
+ export declare const TreeSelectSearchInput: FC<TreeSelectSearchInputProps>;
16
+ //# sourceMappingURL=TreeSelectSearchInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeSelectSearchInput.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/TreeSelectSearchInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,aAAa,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAiB9D,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CA+DhE,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { FC } from 'react';
2
+ export interface TreeSelectTriggerProps {
3
+ multiSelect?: boolean;
4
+ value: string | string[] | undefined;
5
+ disabled?: boolean;
6
+ placeholder?: string;
7
+ isOpen: boolean;
8
+ panelId: string;
9
+ hasValue: boolean;
10
+ getDisplayValue: (path: string | null) => string;
11
+ onToggle: () => void;
12
+ onClear: () => void;
13
+ onRemoveOne: (path: string) => void;
14
+ }
15
+ /**
16
+ * Trigger element for TreeSelect. Renders either a pill-based multi-select
17
+ * trigger or a single-select read-only input, branching on `multiSelect`.
18
+ *
19
+ * @internal For use by TreeSelect.
20
+ */
21
+ export declare const TreeSelectTrigger: FC<TreeSelectTriggerProps>;
22
+ //# sourceMappingURL=TreeSelectTrigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TreeSelectTrigger.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/TreeSelectTrigger.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAkBvC,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;IACjD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AA6DD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAyFxD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { TreeSelect } from './TreeSelect';
2
+ export type { TreeNode, TreePath, TreeSelectProps } from './types';
3
+ export { formatBreadcrumb, getNodeByPath } from './tree';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { ResolvedNode, TreeNode, TreePath } from './types';
2
+ /**
3
+ * Converts a {@link TreePath} of raw node names to an internal encoded string.
4
+ * @internal
5
+ */
6
+ export declare function toInternalPath(segments: TreePath): string;
7
+ /**
8
+ * Converts an internal encoded path string to a {@link TreePath} of raw node names.
9
+ * @internal
10
+ */
11
+ export declare function fromInternalPath(path: string): TreePath;
12
+ /**
13
+ * Whether a node is selectable given the current mode flags.
14
+ *
15
+ * A node is selectable when:
16
+ * 1. Its `can_select` is not explicitly `false` (defaults to `true`).
17
+ * 2. If `leavesOnly` is enabled, the node must be a leaf.
18
+ */
19
+ export declare function isSelectable(node: TreeNode, leavesOnly?: boolean): boolean;
20
+ /**
21
+ * Recursively resolves a {@link TreeNode} subtree into a parallel
22
+ * {@link ResolvedNode} tree with pre-computed paths, depths, and
23
+ * selectability flags.
24
+ *
25
+ * @param root The root node of the tree.
26
+ * @param options.leavesOnly When `true`, branch nodes are marked non-selectable.
27
+ * @param loadedChildren Cache of asynchronously fetched children, keyed by
28
+ * slash-delimited path. When a node has `values: []` and a cache entry
29
+ * exists, the cached children are used in place of the empty array.
30
+ * @returns The resolved root node (callers typically render its `children`).
31
+ */
32
+ export declare function buildResolvedTree(root: TreeNode, options?: {
33
+ leavesOnly?: boolean;
34
+ }, loadedChildren?: Map<string, TreeNode[]>): ResolvedNode;
35
+ /**
36
+ * Filters a resolved tree for a search query, returning a pruned copy of the
37
+ * tree that contains only:
38
+ * - Matched nodes (case-insensitive name substring match, any node)
39
+ * - Every ancestor of a match (force-expanded so the match is visible)
40
+ * - Siblings of each match (rendered but subtrees pruned)
41
+ * - Direct children of each match (rendered collapsed)
42
+ *
43
+ * Returns `null` when no nodes match the query.
44
+ */
45
+ export declare function filterTreeForQuery(resolved: ResolvedNode, query: string): {
46
+ tree: ResolvedNode;
47
+ forceOpenPaths: Set<string>;
48
+ } | null;
49
+ /**
50
+ * Resolves a {@link TreePath} back to the corresponding
51
+ * {@link TreeNode} in the original tree.
52
+ *
53
+ * @returns The matching node, or `undefined` if the path doesn't match.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * const node = getNodeByPath(root, ["vehicle_type", "car", "make", "Honda"]);
58
+ * // node?.name === "Honda"
59
+ * ```
60
+ */
61
+ export declare function getNodeByPath(root: TreeNode, path: TreePath): TreeNode | undefined;
62
+ /**
63
+ * Internal variant of {@link getNodeByPath} that accepts an encoded
64
+ * internal path string. Used by `TreeSelect.tsx` to resolve nodes from
65
+ * the encoded paths stored on {@link ResolvedNode}.
66
+ * @internal
67
+ */
68
+ export declare function getNodeByInternalPath(root: TreeNode, internalPath: string): TreeNode | undefined;
69
+ /**
70
+ * Returns the parent of an internal encoded path by stripping the last
71
+ * segment, or `undefined` for root-level paths (single segment).
72
+ * @internal
73
+ */
74
+ export declare function getParentPath(path: string): string | undefined;
75
+ /**
76
+ * Depth-first walk of a resolved tree returning nodes in DOM render order.
77
+ * Skips the root itself (callers render `root.children`). For each child,
78
+ * includes the child, then if `isOpen(child.path)` returns true, recurses
79
+ * into its children. This mirrors exactly what `TreeSelectNode` renders.
80
+ */
81
+ export declare function flattenVisible(root: ResolvedNode, isOpen: (path: string) => boolean): ResolvedNode[];
82
+ /**
83
+ * Collects the paths of every non-leaf (branch) node in a resolved tree.
84
+ * Useful for resolving `defaultExpanded: true` into a concrete set of paths.
85
+ */
86
+ export declare function collectBranchPaths(root: ResolvedNode): Set<string>;
87
+ /**
88
+ * Formats a {@link TreePath} as a human-readable breadcrumb string.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * formatBreadcrumb(["vehicle_type", "car", "make", "Honda"]);
93
+ * // "vehicle_type / car / make / Honda"
94
+ *
95
+ * formatBreadcrumb(["music", "rock", "AC/DC"]);
96
+ * // "music / rock / AC/DC"
97
+ * ```
98
+ */
99
+ export declare function formatBreadcrumb(path: TreePath): string;
100
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA8BhE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEvD;AAcD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,UAAQ,GAAG,OAAO,CAIxE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,EACtC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,GACvC,YAAY,CAyCd;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,MAAM,GACZ;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAyE5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,QAAQ,GACb,QAAQ,GAAG,SAAS,CAatB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,QAAQ,EACd,YAAY,EAAE,MAAM,GACnB,QAAQ,GAAG,SAAS,CAEtB;AAWD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAChC,YAAY,EAAE,CAiBhB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBlE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,163 @@
1
+ import { HTMLAttributes } from 'react';
2
+ import { SelectAnchor } from '../Select';
3
+ import { ZIndex } from '../../types';
4
+ /**
5
+ * An ordered list of node names from root to the target node.
6
+ *
7
+ * Each element is the raw {@link TreeNode.name} — no encoding is needed.
8
+ * For example, a path to an "AC/DC" node under "rock" under "music"
9
+ * is simply `["music", "rock", "AC/DC"]`.
10
+ */
11
+ export type TreePath = readonly string[];
12
+ /**
13
+ * A node within a tree.
14
+ *
15
+ * `values` has three meaningful states:
16
+ * - `TreeNode[]` (non-empty) — branch with known, loaded children.
17
+ * - `[]` — branch whose children have not yet been loaded (truncated by
18
+ * the source). Renders with a chevron; expanding it triggers
19
+ * `loadChildren` (when wired up).
20
+ * - `undefined` — leaf node; the field is omitted entirely.
21
+ */
22
+ export interface TreeNode {
23
+ name: string;
24
+ description?: string;
25
+ can_select?: boolean;
26
+ deprecated?: boolean;
27
+ values?: TreeNode[];
28
+ }
29
+ /**
30
+ * Pre-computed representation of a {@link TreeNode} produced by
31
+ * {@link buildResolvedTree}. Carries the original node plus derived metadata
32
+ * so the renderer never needs to recompute selectability or paths.
33
+ */
34
+ export interface ResolvedNode {
35
+ /** Reference to the original input node. */
36
+ node: TreeNode;
37
+ /** Slash-delimited path from the root, e.g. `"car/Honda/model/Civic"`. */
38
+ path: string;
39
+ /** Zero-based depth in the tree (root children = 0). */
40
+ depth: number;
41
+ /** Whether this node can be selected given current mode flags. */
42
+ selectable: boolean;
43
+ /** `true` when the source node has `values: undefined` (a true leaf). */
44
+ isLeaf: boolean;
45
+ /**
46
+ * `true` when the source node has `values: []` (truncated branch) and
47
+ * no cached children have been loaded for this path yet. Renders as a
48
+ * branch (chevron visible) with an empty `children` array.
49
+ */
50
+ isLazyBranch: boolean;
51
+ /** Pre-resolved children, in source order. Empty array for leaves and lazy branches. */
52
+ children: ResolvedNode[];
53
+ /** 1-based position among siblings (for `aria-posinset`). */
54
+ posinset: number;
55
+ /** Total number of siblings including this node (for `aria-setsize`). */
56
+ setsize: number;
57
+ }
58
+ /**
59
+ * Props shared by single-select and multi-select modes.
60
+ */
61
+ interface TreeSelectBaseProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
62
+ /** The root node of the tree. */
63
+ root: TreeNode;
64
+ /**
65
+ * When `true`, only leaf nodes (nodes with no children) are selectable.
66
+ * Branch nodes still expand/collapse but cannot be picked as values.
67
+ * @default false
68
+ */
69
+ leavesOnly?: boolean;
70
+ /** If `true`, the entire component is disabled. */
71
+ disabled?: boolean;
72
+ /** Placeholder text shown in the input when no value is selected. */
73
+ placeholder?: string;
74
+ /**
75
+ * Position of the dropdown panel relative to the trigger.
76
+ * Reuses {@link SelectAnchor} for consistency with {@link Select}.
77
+ */
78
+ anchor?: SelectAnchor;
79
+ /**
80
+ * Renders the dropdown panel in a portal so it escapes overflow-hidden
81
+ * ancestors. Defaults to `false`.
82
+ */
83
+ portal?: boolean;
84
+ /** Explicit z-index for the dropdown panel. */
85
+ zIndex?: ZIndex;
86
+ /**
87
+ * Maximum height of the dropdown panel. Accepts any valid CSS length value
88
+ * (e.g. `"400px"`, `"50vh"`). Defaults to `"18rem"` (equivalent to
89
+ * Tailwind's `max-h-72`).
90
+ */
91
+ panelMaxHeight?: string;
92
+ /**
93
+ * Custom formatter for the trigger display text when a value is selected.
94
+ * Receives the selected path (as a {@link TreePath} of raw node names)
95
+ * and the corresponding {@link TreeNode}.
96
+ * When omitted, the node name is shown (e.g. `"Civic"`).
97
+ */
98
+ displayValue?: (path: TreePath, node: TreeNode) => string;
99
+ /**
100
+ * Fetches children for a lazy branch (a node whose `values` is an empty
101
+ * array). Called exactly once per lazy branch on first user-initiated
102
+ * expand. Receives a {@link TreePath} of raw node names.
103
+ * The returned children are spliced into the tree and cached for
104
+ * the lifetime of `root`. Errors set the branch to an "error" state with
105
+ * an inline retry control.
106
+ */
107
+ loadChildren?: (path: TreePath) => Promise<TreeNode[]>;
108
+ /**
109
+ * Branches to expand when the panel first opens. Unlike `forceOpenPaths`
110
+ * (which prevents collapsing), these paths are user-collapsible and
111
+ * restored on panel re-open.
112
+ *
113
+ * - `TreePath[]` — explicit branch paths (each a {@link TreePath} of
114
+ * raw node names) to start expanded.
115
+ * - `true` — expand every branch in the tree.
116
+ * - `false` / `undefined` — expand nothing (default).
117
+ */
118
+ defaultExpanded?: readonly TreePath[] | boolean;
119
+ }
120
+ /**
121
+ * Single-select mode (default). `value` is a {@link TreePath} and
122
+ * `onChange` fires with the selected path or `null` on clear.
123
+ */
124
+ interface TreeSelectSingleProps extends TreeSelectBaseProps {
125
+ multiSelect?: false;
126
+ /**
127
+ * Currently selected node path as a {@link TreePath} — an ordered array
128
+ * of raw node names from root to the selected node. No encoding needed.
129
+ */
130
+ value?: TreePath;
131
+ /**
132
+ * Fires when the user selects or clears a node. The path argument is a
133
+ * {@link TreePath} of raw node names, or `null` when cleared.
134
+ */
135
+ onChange?: (path: TreePath | null) => void;
136
+ }
137
+ /**
138
+ * Multi-select mode. `value` is an array of {@link TreePath} entries and
139
+ * `onChange` fires with the full updated array on every toggle.
140
+ */
141
+ interface TreeSelectMultiProps extends TreeSelectBaseProps {
142
+ multiSelect: true;
143
+ /**
144
+ * Currently selected node paths. Each entry is a {@link TreePath} —
145
+ * an ordered array of raw node names. No encoding needed.
146
+ */
147
+ value?: readonly TreePath[];
148
+ /**
149
+ * Fires with the updated array whenever a node is toggled. Each entry
150
+ * is a {@link TreePath} of raw node names.
151
+ */
152
+ onChange?: (paths: TreePath[]) => void;
153
+ }
154
+ /**
155
+ * Props for {@link TreeSelect}.
156
+ *
157
+ * Discriminated on `multiSelect`:
158
+ * - `multiSelect?: false` (default) — single-select; `value` is `TreePath`, `onChange` fires `TreePath | null`.
159
+ * - `multiSelect: true` — multi-select; `value` is `readonly TreePath[]`, `onChange` fires `TreePath[]`.
160
+ */
161
+ export type TreeSelectProps = TreeSelectSingleProps | TreeSelectMultiProps;
162
+ export {};
163
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/TreeSelect/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,MAAM,EAAE,CAAC;AAEzC;;;;;;;;;GASG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,IAAI,EAAE,QAAQ,CAAC;IACf,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,wFAAwF;IACxF,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,mBAAoB,SAAQ,IAAI,CACxC,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,iCAAiC;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC;IAC1D;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvD;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC;CACjD;AAED;;;GAGG;AACH,UAAU,qBAAsB,SAAQ,mBAAmB;IACzD,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;CAC5C;AAED;;;GAGG;AACH,UAAU,oBAAqB,SAAQ,mBAAmB;IACxD,WAAW,EAAE,IAAI,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;CACxC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,qBAAqB,GAAG,oBAAoB,CAAC"}
@@ -37,5 +37,6 @@ export * from './Toggle';
37
37
  export * from './ToggleSwitch';
38
38
  export * from './Toolbar';
39
39
  export * from './Tooltip';
40
+ export * from './TreeSelect';
40
41
  export * from './UnsetHint';
41
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}