UNPKG

carbon-components-svelte

Version:
241 lines (215 loc) 6.95 kB
import { SvelteComponentTyped } from "svelte"; import type { SvelteHTMLElements } from "svelte/elements"; export type TreeNode<Id = (string|number)> = { id: Id; text: any; icon?: any; /** Whether the node is disabled */ disabled?: boolean; /** Optional URL the node links to */ href?: string; /** Optional link target (e.g., "_blank") */ target?: string; nodes?: TreeNode<Id>[]; }; export type ShowNodeOptions = { /** Whether to expand the node and its ancestors (default: true) */ expand?: boolean; /** Whether to select the node (default: true) */ select?: boolean; /** Whether to focus the node (default: true) */ focus?: boolean; }; export type TreeViewExpandedChange<Id = (string|number)> = { /** The full set of expanded node ids after the change */ expandedIds: ReadonlyArray<Id>; /** Node ids expanded since the previous change */ added: Array<Id>; /** Node ids collapsed since the previous change */ removed: Array<Id>; }; export type TreeViewSelectionChange<Id = (string|number)> = { /** The full set of selected node ids after the change */ selectedIds: ReadonlyArray<Id>; /** Node ids selected since the previous change */ added: Array<Id>; /** Node ids deselected since the previous change */ removed: Array<Id>; }; export type CarbonTreeViewContext<Node extends TreeNode<any> = TreeNode<any>> = { treeId: any; activeNodeId: import("svelte/store").Writable<Node["id"]>; selectedNodeIds: import("svelte/store").Writable<ReadonlyArray<Node["id"]>>; expandedNodeIds: import("svelte/store").Writable<ReadonlyArray<Node["id"]>>; selectedIdsSetStore: import("svelte/store").Writable<Set<Node["id"]>>; expandedIdsSetStore: import("svelte/store").Writable<Set<Node["id"]>>; multiselectStore: import("svelte/store").Writable<boolean>; clickNode: (node: Node, event?: Event) => void; selectNode: (node: Node) => void; expandNode: (node: Node, expanded: boolean) => void; focusNode: (node: Node) => void; toggleNode: (node: Node) => void; }; type $RestProps = SvelteHTMLElements["ul"]; type $Props<Node extends TreeNode<any> = TreeNode<any>> = { /** * Provide an array of nodes to render. * @default [] */ nodes?: ReadonlyArray<Node>; /** * Set the current active node id. * Only one node can be active. * @default "" */ activeId?: Node["id"]; /** * Set the node ids to be selected. * @default [] */ selectedIds?: ReadonlyArray<Node["id"]>; /** * Set the node ids to be expanded. * @default [] */ expandedIds?: ReadonlyArray<Node["id"]>; /** * Specify the TreeView size. * @default "default" */ size?: "default" | "compact"; /** * Specify the label text * @default "" */ labelText?: string; /** * Set to `true` to visually hide the label text * @default false */ hideLabel?: boolean; /** * Set to `true` to automatically collapse sibling nodes when expanding a node. * When enabled, only one node at each level can be expanded at a time. * @default false */ autoCollapse?: boolean; /** * Set to `true` to enable multi-select mode. * Supports Ctrl/Cmd+Click (toggle) and Shift+Click (range select). * @default false */ multiselect?: boolean; /** * When `multiselect` is true, `multiselectMode` controls how many nodes a selection gesture includes: * - `'node'`: only the clicked/active node (default) * - `'shallow'`: the node plus its direct non-disabled children * - `'deep'`: the node plus all non-disabled descendants * @default "node" */ multiselectMode?: 'node' | 'shallow' | 'deep'; labelChildren?: (this: void) => void; children?: (this: void, ...args: [{ node: Node & { expanded: boolean; leaf: boolean; selected: boolean; } }]) => void; [key: `data-${string}`]: unknown; }; export type TreeViewProps<Node extends TreeNode<any> = TreeNode<any>> = Omit<$RestProps, keyof $Props<Node>> & $Props<Node>; export default class TreeView<Node extends TreeNode<any> = TreeNode<any>> extends SvelteComponentTyped< TreeViewProps<Node>, { focus: CustomEvent<Node & { expanded: boolean; leaf: boolean; selected: boolean }>; keydown: WindowEventMap["keydown"]; select: CustomEvent<Node & { expanded: boolean; leaf: boolean; selected: boolean }>; "select:change": CustomEvent<TreeViewSelectionChange<Node["id"]>>; toggle: CustomEvent<Node & { expanded: boolean; leaf: boolean; selected: boolean }>; "toggle:change": CustomEvent<TreeViewExpandedChange<Node["id"]>>; }, { default: { node: Node & { expanded: boolean; leaf: boolean; selected: boolean; } }; labelChildren: Record<string, never>; } > { /** * Programmatically expand all nodes * @example * ```svelte * <TreeView bind:this={treeView} {nodes} /> * <button on:click={() => treeView.expandAll()}>Expand All</button> * ``` */ expandAll: () => void; /** * Programmatically collapse all nodes * @example * ```svelte * <TreeView bind:this={treeView} {nodes} /> * <button on:click={() => treeView.collapseAll()}>Collapse All</button> * ``` */ collapseAll: () => void; /** * Programmatically expand a subset of nodes. * Expands all nodes if no argument is provided. * Filter function should return `true` for nodes to expand. If not provided, expands all nodes. * @example * ```svelte * <TreeView bind:this={treeView} {nodes} /> * <button on:click={() => treeView.expandNodes((node) => node.id.startsWith('folder-'))}> * Expand Folders * </button> * ``` */ expandNodes: (filterNode?: (node: Node) => boolean) => void; /** * Programmatically collapse a subset of nodes. * Collapses all nodes if no argument is provided. * Filter function should return `true` for nodes to collapse. If not provided, collapses all nodes. * @example * ```svelte * <TreeView bind:this={treeView} {nodes} /> * <button on:click={() => treeView.collapseNodes((node) => node.id.startsWith('folder-'))}> * Collapse Folders * </button> * ``` */ collapseNodes: (filterNode?: (node: Node) => boolean) => void; /** * Programmatically show a node by `id`. * By default, the matching node will be expanded, selected, and focused. * Use the options parameter to customize this behavior. * @example * ```svelte * <TreeView bind:this={treeView} {nodes} /> * <button on:click={() => treeView.showNode('node-123')}> * Show Node * </button> * <button on:click={() => treeView.showNode('node-123', { expand: false, focus: false })}> * Show Node (No Expand/Focus) * </button> * ``` */ showNode: (id: Node["id"], options?: ShowNodeOptions) => void; }