@mui/x-tree-view
Version:
The community edition of the MUI X Tree View components.
149 lines (148 loc) • 4.95 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { useAssertModelConsistency } from '@mui/x-internals/useAssertModelConsistency';
import useEventCallback from '@mui/utils/useEventCallback';
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
import { selectorExpandedItems, selectorIsItemExpandable, selectorIsItemExpanded } from "./useTreeViewExpansion.selectors.js";
import { getExpansionTrigger } from "./useTreeViewExpansion.utils.js";
import { selectorItemMeta, selectorItemOrderedChildrenIds } from "../useTreeViewItems/useTreeViewItems.selectors.js";
import { publishTreeViewEvent } from "../../utils/publishTreeViewEvent.js";
export const useTreeViewExpansion = ({
instance,
store,
params
}) => {
useAssertModelConsistency({
componentName: 'Tree View',
propName: 'expandedItems',
controlled: params.expandedItems,
defaultValue: params.defaultExpandedItems
});
useEnhancedEffect(() => {
store.update(prevState => {
const newExpansionTrigger = getExpansionTrigger({
isItemEditable: params.isItemEditable,
expansionTrigger: params.expansionTrigger
});
if (prevState.expansion.expansionTrigger === newExpansionTrigger) {
return prevState;
}
return _extends({}, prevState, {
expansion: _extends({}, prevState.expansion, {
expansionTrigger: newExpansionTrigger
})
});
});
}, [store, params.isItemEditable, params.expansionTrigger]);
const setExpandedItems = (event, value) => {
if (params.expandedItems === undefined) {
store.update(prevState => _extends({}, prevState, {
expansion: _extends({}, prevState.expansion, {
expandedItems: value
})
}));
}
params.onExpandedItemsChange?.(event, value);
};
const applyItemExpansion = useEventCallback(({
itemId,
event,
shouldBeExpanded
}) => {
const oldExpanded = selectorExpandedItems(store.value);
let newExpanded;
if (shouldBeExpanded) {
newExpanded = [itemId].concat(oldExpanded);
} else {
newExpanded = oldExpanded.filter(id => id !== itemId);
}
if (params.onItemExpansionToggle) {
params.onItemExpansionToggle(event, itemId, shouldBeExpanded);
}
setExpandedItems(event, newExpanded);
});
const setItemExpansion = useEventCallback(({
itemId,
event = null,
shouldBeExpanded
}) => {
const isExpandedBefore = selectorIsItemExpanded(store.value, itemId);
const cleanShouldBeExpanded = shouldBeExpanded ?? !isExpandedBefore;
if (isExpandedBefore === cleanShouldBeExpanded) {
return;
}
const eventParameters = {
isExpansionPrevented: false,
shouldBeExpanded: cleanShouldBeExpanded,
event,
itemId
};
publishTreeViewEvent(instance, 'beforeItemToggleExpansion', eventParameters);
if (eventParameters.isExpansionPrevented) {
return;
}
instance.applyItemExpansion({
itemId,
event,
shouldBeExpanded: cleanShouldBeExpanded
});
});
const expandAllSiblings = (event, itemId) => {
const itemMeta = selectorItemMeta(store.value, itemId);
if (itemMeta == null) {
return;
}
const siblings = selectorItemOrderedChildrenIds(store.value, itemMeta.parentId);
const diff = siblings.filter(child => selectorIsItemExpandable(store.value, child) && !selectorIsItemExpanded(store.value, child));
const newExpanded = selectorExpandedItems(store.value).concat(diff);
if (diff.length > 0) {
if (params.onItemExpansionToggle) {
diff.forEach(newlyExpandedItemId => {
params.onItemExpansionToggle(event, newlyExpandedItemId, true);
});
}
setExpandedItems(event, newExpanded);
}
};
/**
* Update the controlled model when the `expandedItems` prop changes.
*/
useEnhancedEffect(() => {
const expandedItems = params.expandedItems;
if (expandedItems !== undefined) {
store.update(prevState => _extends({}, prevState, {
expansion: _extends({}, prevState.expansion, {
expandedItems
})
}));
}
}, [store, params.expandedItems]);
return {
publicAPI: {
setItemExpansion
},
instance: {
setItemExpansion,
applyItemExpansion,
expandAllSiblings
}
};
};
const DEFAULT_EXPANDED_ITEMS = [];
useTreeViewExpansion.applyDefaultValuesToParams = ({
params
}) => _extends({}, params, {
defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS
});
useTreeViewExpansion.getInitialState = params => ({
expansion: {
expandedItems: params.expandedItems === undefined ? params.defaultExpandedItems : params.expandedItems,
expansionTrigger: getExpansionTrigger(params)
}
});
useTreeViewExpansion.params = {
expandedItems: true,
defaultExpandedItems: true,
onExpandedItemsChange: true,
onItemExpansionToggle: true,
expansionTrigger: true
};