UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

187 lines (185 loc) 6.8 kB
'use client'; import _extends from "@babel/runtime/helpers/esm/extends"; import * as React from 'react'; import useEventCallback from '@mui/utils/useEventCallback'; import useForkRef from '@mui/utils/useForkRef'; import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; import { publishTreeViewEvent } from "../../utils/publishTreeViewEvent.js"; import { useTreeViewContext } from "../../TreeViewProvider/index.js"; import { TreeViewChildrenItemContext, TreeViewChildrenItemProvider } from "../../TreeViewProvider/TreeViewChildrenItemProvider.js"; import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "../useTreeViewItems/useTreeViewItems.utils.js"; import { TreeViewItemDepthContext } from "../../TreeViewItemDepthContext/index.js"; import { generateTreeItemIdAttribute } from "../../corePlugins/useTreeViewId/useTreeViewId.utils.js"; import { itemHasChildren } from "../../../hooks/useTreeItemUtils/useTreeItemUtils.js"; import { useSelector } from "../../hooks/useSelector.js"; import { selectorTreeViewId } from "../../corePlugins/useTreeViewId/useTreeViewId.selectors.js"; import { jsx as _jsx } from "react/jsx-runtime"; export const useTreeViewJSXItems = ({ instance, store }) => { instance.preventItemUpdates(); const insertJSXItem = useEventCallback(item => { store.update(prevState => { if (prevState.items.itemMetaLookup[item.id] != null) { throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', `Two items were provided with the same id in the \`items\` prop: "${item.id}"`].join('\n')); } return _extends({}, prevState, { items: _extends({}, prevState.items, { itemMetaLookup: _extends({}, prevState.items.itemMetaLookup, { [item.id]: item }), // For Simple Tree View, we don't have a proper `item` object, so we create a very basic one. itemModelLookup: _extends({}, prevState.items.itemModelLookup, { [item.id]: { id: item.id, label: item.label ?? '' } }) }) }); }); return () => { store.update(prevState => { const newItemMetaLookup = _extends({}, prevState.items.itemMetaLookup); const newItemModelLookup = _extends({}, prevState.items.itemModelLookup); delete newItemMetaLookup[item.id]; delete newItemModelLookup[item.id]; return _extends({}, prevState, { items: _extends({}, prevState.items, { itemMetaLookup: newItemMetaLookup, itemModelLookup: newItemModelLookup }) }); }); publishTreeViewEvent(instance, 'removeItem', { id: item.id }); }; }); const setJSXItemsOrderedChildrenIds = (parentId, orderedChildrenIds) => { const parentIdWithDefault = parentId ?? TREE_VIEW_ROOT_PARENT_ID; store.update(prevState => _extends({}, prevState, { items: _extends({}, prevState.items, { itemOrderedChildrenIdsLookup: _extends({}, prevState.items.itemOrderedChildrenIdsLookup, { [parentIdWithDefault]: orderedChildrenIds }), itemChildrenIndexesLookup: _extends({}, prevState.items.itemChildrenIndexesLookup, { [parentIdWithDefault]: buildSiblingIndexes(orderedChildrenIds) }) }) })); }; const mapFirstCharFromJSX = useEventCallback((itemId, firstChar) => { instance.updateFirstCharMap(firstCharMap => { firstCharMap[itemId] = firstChar; return firstCharMap; }); return () => { instance.updateFirstCharMap(firstCharMap => { const newMap = _extends({}, firstCharMap); delete newMap[itemId]; return newMap; }); }; }); return { instance: { insertJSXItem, setJSXItemsOrderedChildrenIds, mapFirstCharFromJSX } }; }; const useTreeViewJSXItemsItemPlugin = ({ props, rootRef, contentRef }) => { const { instance, store } = useTreeViewContext(); const { children, disabled = false, label, itemId, id } = props; const parentContext = React.useContext(TreeViewChildrenItemContext); if (parentContext == null) { throw new Error(['MUI X: Could not find the Tree View Children Item context.', 'It looks like you rendered your component outside of a SimpleTreeView parent component.', 'This can also happen if you are bundling multiple versions of the Tree View.'].join('\n')); } const { registerChild, unregisterChild, parentId } = parentContext; const expandable = itemHasChildren(children); const pluginContentRef = React.useRef(null); const handleContentRef = useForkRef(pluginContentRef, contentRef); const treeId = useSelector(store, selectorTreeViewId); // Prevent any flashing useEnhancedEffect(() => { const idAttribute = generateTreeItemIdAttribute({ itemId, treeId, id }); registerChild(idAttribute, itemId); return () => { unregisterChild(idAttribute); unregisterChild(idAttribute); }; }, [store, instance, registerChild, unregisterChild, itemId, id, treeId]); useEnhancedEffect(() => { return instance.insertJSXItem({ id: itemId, idAttribute: id, parentId, expandable, disabled }); }, [instance, parentId, itemId, expandable, disabled, id]); React.useEffect(() => { if (label) { return instance.mapFirstCharFromJSX(itemId, (pluginContentRef.current?.textContent ?? '').substring(0, 1).toLowerCase()); } return undefined; }, [instance, itemId, label]); return { contentRef: handleContentRef, rootRef }; }; useTreeViewJSXItems.itemPlugin = useTreeViewJSXItemsItemPlugin; useTreeViewJSXItems.wrapItem = ({ children, itemId, idAttribute }) => { // eslint-disable-next-line react-hooks/rules-of-hooks const depthContext = React.useContext(TreeViewItemDepthContext); return /*#__PURE__*/_jsx(TreeViewChildrenItemProvider, { itemId: itemId, idAttribute: idAttribute, children: /*#__PURE__*/_jsx(TreeViewItemDepthContext.Provider, { value: depthContext + 1, children: children }) }); }; if (process.env.NODE_ENV !== "production") useTreeViewJSXItems.wrapItem.displayName = "useTreeViewJSXItems.wrapItem"; useTreeViewJSXItems.wrapRoot = ({ children }) => /*#__PURE__*/_jsx(TreeViewChildrenItemProvider, { itemId: null, idAttribute: null, children: /*#__PURE__*/_jsx(TreeViewItemDepthContext.Provider, { value: 0, children: children }) }); if (process.env.NODE_ENV !== "production") useTreeViewJSXItems.wrapRoot.displayName = "useTreeViewJSXItems.wrapRoot"; useTreeViewJSXItems.params = {};