UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

149 lines (148 loc) 4.95 kB
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 };