UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

330 lines (329 loc) 10.6 kB
"use client"; require("../../_virtual/_rolldown/runtime.cjs"); const require_get_children_nodes_values = require("./get-children-nodes-values/get-children-nodes-values.cjs"); const require_get_all_checked_nodes = require("./get-all-checked-nodes/get-all-checked-nodes.cjs"); const require_is_node_checked = require("./is-node-checked/is-node-checked.cjs"); const require_is_node_indeterminate = require("./is-node-indeterminate/is-node-indeterminate.cjs"); let react = require("react"); let _mantine_hooks = require("@mantine/hooks"); //#region packages/@mantine/core/src/components/Tree/use-tree.ts function getInitialTreeExpandedState(initialState, data, value, acc = {}) { data.forEach((node) => { acc[node.value] = node.value in initialState ? initialState[node.value] : node.value === value; if (Array.isArray(node.children)) getInitialTreeExpandedState(initialState, node.children, value, acc); }); return acc; } function getTreeExpandedState(data, expandedNodesValues) { const state = getInitialTreeExpandedState({}, data, []); if (expandedNodesValues === "*") { const result = {}; const keys = Object.keys(state); for (let i = 0; i < keys.length; i++) result[keys[i]] = true; return result; } expandedNodesValues.forEach((node) => { state[node] = true; }); return state; } function getInitialCheckedState(initialState, data, checkStrictly) { if (checkStrictly) return initialState; const acc = []; initialState.forEach((node) => acc.push(...require_get_children_nodes_values.getChildrenNodesValues(node, data))); return Array.from(new Set(acc)); } function getAllNodeValues(data) { const acc = []; for (const node of data) { acc.push(node.value); if (Array.isArray(node.children) && node.children.length > 0) acc.push(...getAllNodeValues(node.children)); } return acc; } function useTree({ initialSelectedState = [], expandedState, initialCheckedState = [], checkedState, initialExpandedState = {}, selectedState, multiple = false, onNodeCollapse, onNodeExpand, onCheckedStateChange, onSelectedStateChange, onExpandedStateChange, onLoadChildren, checkStrictly = false } = {}) { const [data, setData] = (0, react.useState)([]); const [_expandedState, setExpandedState] = (0, _mantine_hooks.useUncontrolled)({ value: expandedState, defaultValue: initialExpandedState, finalValue: {}, onChange: onExpandedStateChange }); const [_selectedState, setSelectedState] = (0, _mantine_hooks.useUncontrolled)({ value: selectedState, defaultValue: initialSelectedState, finalValue: [], onChange: onSelectedStateChange }); const [_checkedState, setCheckedState] = (0, _mantine_hooks.useUncontrolled)({ value: checkedState, defaultValue: initialCheckedState, finalValue: [], onChange: onCheckedStateChange }); const [anchorNode, setAnchorNode] = (0, react.useState)(null); const loadingNodesRef = (0, react.useRef)(/* @__PURE__ */ new Set()); const loadedNodesRef = (0, react.useRef)(/* @__PURE__ */ new Set()); const [loadingNodes, setLoadingNodes] = (0, react.useState)([]); const [loadErrors, setLoadErrors] = (0, react.useState)({}); const initialize = (0, react.useCallback)((_data) => { setExpandedState(getInitialTreeExpandedState(_expandedState, _data, _selectedState)); setCheckedState(getInitialCheckedState(_checkedState, _data, checkStrictly)); setData(_data); }, [ _selectedState, _checkedState, _expandedState, checkStrictly ]); const loadNodeImpl = (0, react.useCallback)(async (value) => { if (!onLoadChildren) return; if (loadingNodesRef.current.has(value) || loadedNodesRef.current.has(value)) return; loadingNodesRef.current.add(value); setLoadingNodes(Array.from(loadingNodesRef.current)); setLoadErrors((prev) => { if (!(value in prev)) return prev; const next = { ...prev }; delete next[value]; return next; }); try { await onLoadChildren(value); loadedNodesRef.current.add(value); } catch (error) { const err = error instanceof Error ? error : new Error(String(error)); setLoadErrors((prev) => ({ ...prev, [value]: err })); } finally { loadingNodesRef.current.delete(value); setLoadingNodes(Array.from(loadingNodesRef.current)); } }, [onLoadChildren]); const tryLoadAsync = (0, react.useCallback)((value) => { if (!onLoadChildren) return; const node = require_get_children_nodes_values.findTreeNode(value, data); if (node && node.hasChildren && !Array.isArray(node.children)) loadNodeImpl(value); }, [ onLoadChildren, data, loadNodeImpl ]); const toggleExpanded = (0, react.useCallback)((value) => { const nextState = { ..._expandedState, [value]: !_expandedState[value] }; nextState[value] ? onNodeExpand?.(value) : onNodeCollapse?.(value); if (nextState[value]) tryLoadAsync(value); setExpandedState(nextState); }, [ onNodeCollapse, onNodeExpand, _expandedState, tryLoadAsync ]); const collapse = (0, react.useCallback)((value) => { if (_expandedState[value] !== false) onNodeCollapse?.(value); setExpandedState({ ..._expandedState, [value]: false }); }, [onNodeCollapse, _expandedState]); const expand = (0, react.useCallback)((value) => { if (_expandedState[value] !== true) onNodeExpand?.(value); tryLoadAsync(value); setExpandedState({ ..._expandedState, [value]: true }); }, [ onNodeExpand, _expandedState, tryLoadAsync ]); const expandAllNodes = (0, react.useCallback)(() => { const nextState = { ..._expandedState }; Object.keys(nextState).forEach((key) => { nextState[key] = true; tryLoadAsync(key); }); setExpandedState(nextState); }, [_expandedState, tryLoadAsync]); const collapseAllNodes = (0, react.useCallback)(() => { const nextState = { ..._expandedState }; Object.keys(nextState).forEach((key) => { nextState[key] = false; }); setExpandedState(nextState); }, [_expandedState]); const toggleSelected = (0, react.useCallback)((value) => { if (!multiple) { if (_selectedState.includes(value)) { setAnchorNode(null); return []; } setAnchorNode(value); return [value]; } if (_selectedState.includes(value)) { setAnchorNode(null); return _selectedState.filter((item) => item !== value); } setAnchorNode(value); setSelectedState([..._selectedState, value]); }, [_selectedState]); const select = (0, react.useCallback)((value) => { setAnchorNode(value); setSelectedState(multiple ? _selectedState.includes(value) ? _selectedState : [..._selectedState, value] : [value]); }, [_selectedState]); const deselect = (0, react.useCallback)((value) => { anchorNode === value && setAnchorNode(null); setSelectedState(_selectedState.filter((item) => item !== value)); }, [_selectedState]); const clearSelected = (0, react.useCallback)(() => { setSelectedState([]); setAnchorNode(null); }, []); const checkNode = (0, react.useCallback)((value) => { if (checkStrictly) { if (!_checkedState.includes(value)) setCheckedState([..._checkedState, value]); } else { const checkedNodes = require_get_children_nodes_values.getChildrenNodesValues(value, data); setCheckedState(Array.from(new Set([..._checkedState, ...checkedNodes]))); } }, [ data, _checkedState, checkStrictly ]); const uncheckNode = (0, react.useCallback)((value) => { if (checkStrictly) setCheckedState(_checkedState.filter((item) => item !== value)); else { const checkedNodes = require_get_children_nodes_values.getChildrenNodesValues(value, data); setCheckedState(_checkedState.filter((item) => !checkedNodes.includes(item))); } }, [ data, _checkedState, checkStrictly ]); const checkAllNodes = (0, react.useCallback)(() => { if (checkStrictly) setCheckedState(getAllNodeValues(data)); else setCheckedState(require_get_children_nodes_values.getAllChildrenNodes(data)); }, [data, checkStrictly]); const uncheckAllNodes = (0, react.useCallback)(() => { setCheckedState([]); }, []); const getCheckedNodes = (0, react.useCallback)(() => { if (checkStrictly) return _checkedState.map((value) => { const node = require_get_children_nodes_values.findTreeNode(value, data); return { checked: true, indeterminate: false, value, hasChildren: node ? Array.isArray(node.children) && node.children.length > 0 || !!node.hasChildren : false }; }); return require_get_all_checked_nodes.getAllCheckedNodes(data, _checkedState).result; }, [ checkStrictly, _checkedState, data ]); const isNodeChecked = (0, react.useCallback)((value) => { if (checkStrictly) return _checkedState.includes(value); return require_is_node_checked.memoizedIsNodeChecked(value, data, _checkedState); }, [ checkStrictly, _checkedState, data ]); const isNodeIndeterminate = (0, react.useCallback)((value) => { if (checkStrictly) return false; return require_is_node_indeterminate.memoizedIsNodeIndeterminate(value, data, _checkedState); }, [ checkStrictly, _checkedState, data ]); const isNodeLoading = (0, react.useCallback)((value) => loadingNodes.includes(value), [loadingNodes]); const getNodeLoadError = (0, react.useCallback)((value) => loadErrors[value] || null, [loadErrors]); const invalidateNode = (0, react.useCallback)((value) => { loadedNodesRef.current.delete(value); setLoadErrors((prev) => { if (!(value in prev)) return prev; const next = { ...prev }; delete next[value]; return next; }); }, []); return (0, react.useMemo)(() => ({ checkStrictly, multiple, expandedState: _expandedState, selectedState: _selectedState, checkedState: _checkedState, anchorNode, initialize, toggleExpanded, collapse, expand, expandAllNodes, collapseAllNodes, setExpandedState, checkNode, uncheckNode, checkAllNodes, uncheckAllNodes, setCheckedState, toggleSelected, select, deselect, clearSelected, setSelectedState, getCheckedNodes, isNodeChecked, isNodeIndeterminate, isNodeLoading, getNodeLoadError, loadNode: loadNodeImpl, invalidateNode }), [ checkStrictly, multiple, _expandedState, _selectedState, _checkedState, anchorNode, initialize, toggleExpanded, collapse, expand, expandAllNodes, collapseAllNodes, setExpandedState, checkNode, uncheckNode, checkAllNodes, uncheckAllNodes, setCheckedState, toggleSelected, select, deselect, clearSelected, setSelectedState, getCheckedNodes, isNodeChecked, isNodeIndeterminate, isNodeLoading, getNodeLoadError, loadNodeImpl, invalidateNode ]); } //#endregion exports.getTreeExpandedState = getTreeExpandedState; exports.useTree = useTree; //# sourceMappingURL=use-tree.cjs.map