@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
178 lines (177 loc) • 6.06 kB
JavaScript
"use client";
import { getAllCheckedNodes } from "./get-all-checked-nodes/get-all-checked-nodes.mjs";
import { getAllChildrenNodes, getChildrenNodesValues } from "./get-children-nodes-values/get-children-nodes-values.mjs";
import { memoizedIsNodeChecked } from "./is-node-checked/is-node-checked.mjs";
import { memoizedIsNodeIndeterminate } from "./is-node-indeterminate/is-node-indeterminate.mjs";
import { useCallback, useState } from "react";
import { useUncontrolled } from "@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 === "*") return Object.keys(state).reduce((acc, key) => ({
...acc,
[key]: true
}), {});
expandedNodesValues.forEach((node) => {
state[node] = true;
});
return state;
}
function getInitialCheckedState(initialState, data) {
const acc = [];
initialState.forEach((node) => acc.push(...getChildrenNodesValues(node, data)));
return Array.from(new Set(acc));
}
function useTree({ initialSelectedState = [], expandedState, initialCheckedState = [], checkedState, initialExpandedState = {}, selectedState, multiple = false, onNodeCollapse, onNodeExpand, onCheckedStateChange, onSelectedStateChange, onExpandedStateChange } = {}) {
const [data, setData] = useState([]);
const [_expandedState, setExpandedState] = useUncontrolled({
value: expandedState,
defaultValue: initialExpandedState,
finalValue: {},
onChange: onExpandedStateChange
});
const [_selectedState, setSelectedState] = useUncontrolled({
value: selectedState,
defaultValue: initialSelectedState,
finalValue: [],
onChange: onSelectedStateChange
});
const [_checkedState, setCheckedState] = useUncontrolled({
value: checkedState,
defaultValue: initialCheckedState,
finalValue: [],
onChange: onCheckedStateChange
});
const [anchorNode, setAnchorNode] = useState(null);
const initialize = useCallback((_data) => {
setExpandedState(getInitialTreeExpandedState(_expandedState, _data, _selectedState));
setCheckedState(getInitialCheckedState(_checkedState, _data));
setData(_data);
}, [
_selectedState,
_checkedState,
_expandedState
]);
const toggleExpanded = useCallback((value) => {
const nextState = {
..._expandedState,
[value]: !_expandedState[value]
};
nextState[value] ? onNodeExpand?.(value) : onNodeCollapse?.(value);
setExpandedState(nextState);
}, [
onNodeCollapse,
onNodeExpand,
_expandedState
]);
const collapse = useCallback((value) => {
if (_expandedState[value] !== false) onNodeCollapse?.(value);
setExpandedState({
..._expandedState,
[value]: false
});
}, [onNodeCollapse, _expandedState]);
const expand = useCallback((value) => {
if (_expandedState[value] !== true) onNodeExpand?.(value);
setExpandedState({
..._expandedState,
[value]: true
});
}, [onNodeExpand, _expandedState]);
const expandAllNodes = useCallback(() => {
const nextState = { ..._expandedState };
Object.keys(nextState).forEach((key) => {
nextState[key] = true;
});
setExpandedState(nextState);
}, [_expandedState]);
const collapseAllNodes = useCallback(() => {
const nextState = { ..._expandedState };
Object.keys(nextState).forEach((key) => {
nextState[key] = false;
});
setExpandedState(nextState);
}, [_expandedState]);
const toggleSelected = 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 = useCallback((value) => {
setAnchorNode(value);
setSelectedState(multiple ? _selectedState.includes(value) ? _selectedState : [..._selectedState, value] : [value]);
}, [_selectedState]);
const deselect = useCallback((value) => {
anchorNode === value && setAnchorNode(null);
setSelectedState(_selectedState.filter((item) => item !== value));
}, [_selectedState]);
const clearSelected = useCallback(() => {
setSelectedState([]);
setAnchorNode(null);
}, []);
const checkNode = useCallback((value) => {
const checkedNodes = getChildrenNodesValues(value, data);
setCheckedState(Array.from(new Set([..._checkedState, ...checkedNodes])));
}, [data, _checkedState]);
const uncheckNode = useCallback((value) => {
const checkedNodes = getChildrenNodesValues(value, data);
setCheckedState(_checkedState.filter((item) => !checkedNodes.includes(item)));
}, [data, _checkedState]);
const checkAllNodes = useCallback(() => {
setCheckedState(getAllChildrenNodes(data));
}, [data]);
const uncheckAllNodes = useCallback(() => {
setCheckedState([]);
}, []);
const getCheckedNodes = () => getAllCheckedNodes(data, _checkedState).result;
const isNodeChecked = (value) => memoizedIsNodeChecked(value, data, _checkedState);
const isNodeIndeterminate = (value) => memoizedIsNodeIndeterminate(value, data, _checkedState);
return {
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
};
}
//#endregion
export { getTreeExpandedState, useTree };
//# sourceMappingURL=use-tree.mjs.map