@mui/x-tree-view
Version:
The community edition of the MUI X Tree View components.
80 lines (79 loc) • 2.56 kB
JavaScript
import { useRefWithInit } from '@base-ui/utils/useRefWithInit';
import { getLookupFromArray } from "../internals/plugins/selection/TreeViewSelectionPlugin.js";
const defaultGetItemId = item => item.id;
const defaultGetItemChildren = item => item.children;
/**
* Applies the selection propagation rules to the selected items.
* The value is only computed during the first render, any update of the parameters will be ignored.
*
* Uncontrolled example:
* ```tsx
* const defaultSelectedItems = useApplyPropagationToSelectedItemsOnMount({
* items: props.items,
* selectionPropagation: props.selectionPropagation,
* selectedItems: ['10', '11', '13', '14'],
* });
*
* return (
* <RichTreeView
* items={props.items}
* selectionPropagation={props.selectionPropagation}
* defaultSelectedItems={defaultSelectedItems}
* />
* );
* ```
*
* Controlled example:
* ```tsx
* const initialSelectedItems = useApplyPropagationToSelectedItemsOnMount({
* items: props.items,
* selectionPropagation: props.selectionPropagation,
* selectedItems: ['10', '11', '13', '14'],
* });
*
* const [selectedItems, setSelectedItems] = React.useState(initialSelectedItems);
*
* return (
* <RichTreeView
* items={props.items}
* selectionPropagation={props.selectionPropagation}
* selectedItems={selectedItems}
* onSelectedItemsChange={setSelectedItems}
* />
* );
* ```
*/
export function useApplyPropagationToSelectedItemsOnMount(parameters) {
const {
items: itemsParam,
getItemId = defaultGetItemId,
getItemChildren = defaultGetItemChildren,
selectedItems,
selectionPropagation
} = parameters;
return useRefWithInit(() => {
const lookup = getLookupFromArray(selectedItems);
function walk(items, isParentSelected) {
for (const item of items) {
const itemId = getItemId(item);
let isSelected = lookup[itemId];
if (!isSelected && selectionPropagation.descendants && isParentSelected) {
lookup[itemId] = true;
isSelected = true;
}
const children = getItemChildren(item) ?? [];
if (children.length > 0) {
walk(children, isSelected);
if (!isSelected && selectionPropagation.parents) {
const areAllChildrenSelected = children.every(childId => lookup[getItemId(childId)]);
if (areAllChildrenSelected) {
lookup[itemId] = true;
}
}
}
}
}
walk(itemsParam, false);
return Object.keys(lookup);
}).current;
}