UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

149 lines (148 loc) 5.01 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { useAssertModelConsistency } from '@mui/x-internals/useAssertModelConsistency'; import { useStableCallback } from '@base-ui/utils/useStableCallback'; import { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect'; import { expansionSelectors } from "./useTreeViewExpansion.selectors.js"; import { getExpansionTrigger } from "./useTreeViewExpansion.utils.js"; import { itemsSelectors } 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 }); useIsoLayoutEffect(() => { const newExpansionTrigger = getExpansionTrigger({ isItemEditable: params.isItemEditable, expansionTrigger: params.expansionTrigger }); if (store.state.expansion.expansionTrigger === newExpansionTrigger) { return; } store.set('expansion', _extends({}, store.state.expansion, { expansionTrigger: newExpansionTrigger })); }, [store, params.isItemEditable, params.expansionTrigger]); const setExpandedItems = (event, value) => { if (params.expandedItems === undefined) { store.set('expansion', _extends({}, store.state.expansion, { expandedItems: value })); } params.onExpandedItemsChange?.(event, value); }; const resetItemExpansion = useStableCallback(() => { setExpandedItems(null, []); }); const applyItemExpansion = useStableCallback(({ itemId, event, shouldBeExpanded }) => { const oldExpanded = expansionSelectors.expandedItemsRaw(store.state); 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 = useStableCallback(({ itemId, event = null, shouldBeExpanded }) => { const isExpandedBefore = expansionSelectors.isItemExpanded(store.state, 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 isItemExpanded = useStableCallback(itemId => { return expansionSelectors.isItemExpanded(store.state, itemId); }); const expandAllSiblings = (event, itemId) => { const itemMeta = itemsSelectors.itemMeta(store.state, itemId); if (itemMeta == null) { return; } const siblings = itemsSelectors.itemOrderedChildrenIds(store.state, itemMeta.parentId); const diff = siblings.filter(child => expansionSelectors.isItemExpandable(store.state, child) && !expansionSelectors.isItemExpanded(store.state, child)); const newExpanded = expansionSelectors.expandedItemsRaw(store.state).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. */ useIsoLayoutEffect(() => { const expandedItems = params.expandedItems; if (expandedItems !== undefined) { store.set('expansion', _extends({}, store.state.expansion, { expandedItems })); } }, [store, params.expandedItems]); return { publicAPI: { setItemExpansion, isItemExpanded }, instance: { setItemExpansion, applyItemExpansion, expandAllSiblings, resetItemExpansion } }; }; 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 };