UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

141 lines (136 loc) 4.2 kB
import * as React from 'react'; import type { CommonProps } from '../../utils/index.js'; export type NodeData<T> = { /** * Array of the child nodes contained in the node. */ subNodes?: Array<T>; /** * Unique id of the node. */ nodeId: string; /** * Custom type used to map type `T` to `NodeData` */ node: T; /** * Flag whether the node is expanded. */ isExpanded?: boolean; /** * Flag whether the node is disabled. */ isDisabled?: boolean; /** * Flag whether the node is selected. */ isSelected?: boolean; /** * Flag whether the node has sub-nodes. * Used to determine if node should be expandable. */ hasSubNodes: boolean; }; export type NodeRenderProps<T> = Omit<NodeData<T>, 'subNodes'>; export type TreeProps<T> = { /** * Modify size of the tree. * * @default 'default' */ size?: 'default' | 'small'; /** * Render function that should return the node element. * Recommended to use `TreeNode` component. * ***Note**: When virtualization is enabled, the return value of `nodeRenderer()` is cloned and a `ref` is passed to it. Thus, you would need a `React.forwardRef` in the component returned by `nodeRenderer()`, except if you are returning `TreeNode` since that already forwards its ref. * @example * const nodeRenderer = React.useCallback(({ node, ...rest }: NodeRenderProps<DataType>) => ( * <TreeNode * label={node.label} * onNodeExpanded={onNodeExpanded} * {...rest} * /> * ), [onNodeExpanded]) */ nodeRenderer: (props: NodeRenderProps<T>) => React.JSX.Element; /** * Array of custom data used for `TreeNodes` inside `Tree`. */ data: T[]; /** * Function that maps your `data` entry to `NodeData` that has all info about the node state. * It will be used to render a tree node in `nodeRenderer`. * Must be memoized. * @example * const getNode = React.useCallback((node: DemoData): NodeData<DemoData> => { * return { * subNodes: node.subItems, * nodeId: node.id, * node, * isExpanded: expandedNodes[node.id], * hasSubNodes: node.subItems.length > 0, * }; * }, [expandedNodes]); */ getNode: (node: T) => NodeData<T>; /** * Virtualization is used to have a better performance with a lot of nodes. * * When enabled, Tree DOM structure will change - it will have a wrapper div * to which `className` and `style` will be applied. * @default false * @beta */ enableVirtualization?: boolean; } & CommonProps; /** * Tree component used to display a hierarchical structure of `TreeNodes`. * User should control state of expanded, selected and disabled nodes using `getNode` prop. * @example type DemoData = { id: string; label: string; subItems: DemoData[]; }; const data: Array<DemoData> = [ { id: 'Node-1', label: 'Facility 1', subItems: [{ id: 'Node-1-1', label: 'Unit 1', subItems: [] }], }, { id: 'Node-2', label: 'Facility 2', subItems: [{ id: 'Node-2-1', label: 'Unit 2', subItems: [] }], }, ]; const [expandedNodes, setExpandedNodes] = React.useState<Record<string, boolean>>({}); const onNodeExpanded = React.useCallback((nodeId: string, isExpanded: boolean) => { setExpandedNodes((oldExpanded) => ({ ...oldExpanded, [nodeId]: isExpanded })); }, []); const getNode = React.useCallback((node: DemoData): NodeData<DemoData> => { return { subNodes: node.subItems, nodeId: node.id, node, isExpanded: expandedNodes[node.id], hasSubNodes: node.subItems.length > 0, }; }, [expandedNodes]); <Tree<DemoData> data={data} getNode={getNode} nodeRenderer={React.useCallback(({ node, ...rest }) => ( <TreeNode label={node.label} onNodeExpanded={onNodeExpanded} {...rest} /> ), [onNodeExpanded])} /> */ export declare const Tree: { <T>(props: TreeProps<T>): React.JSX.Element; displayName: string; };