UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

152 lines (149 loc) • 5.79 kB
'use client'; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; import _extends from "@babel/runtime/helpers/esm/extends"; const _excluded = ["ownerState"]; import * as React from 'react'; import { EMPTY_ARRAY } from '@base-ui/utils/empty'; import { useStore } from '@mui/x-internals/store'; import useSlotProps from '@mui/utils/useSlotProps'; import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare'; import { TreeItem } from "../../TreeItem/index.mjs"; import { itemsSelectors } from "../plugins/items/index.mjs"; import { useTreeViewContext, useTreeViewStyleContext } from "../TreeViewProvider/index.mjs"; import { expansionSelectors } from "../plugins/expansion/index.mjs"; import { lazyLoadingSelectors } from "../plugins/lazyLoading/index.mjs"; import { RichTreeViewItemLoaders, RichTreeViewLoadingContext, getLoadingItemsCount, MAX_LOADING_ITEMS_COUNT } from "./RichTreeViewLoading.mjs"; import { useTreeViewRootProps } from "../hooks/useTreeViewRootProps.mjs"; import { jsx as _jsx } from "react/jsx-runtime"; const RichTreeViewItemsContext = /*#__PURE__*/React.createContext(null); if (process.env.NODE_ENV !== "production") RichTreeViewItemsContext.displayName = "RichTreeViewItemsContext"; const selectorNoChildren = () => EMPTY_ARRAY; const selectorChildrenIdsNull = state => itemsSelectors.itemOrderedChildrenIds(state, null); /** * Renders the loading rows for the children of an item that lazily loads them. * It only mounts while the item is loading, so the `loading` slot props are not * resolved for the other items. */ function RichTreeViewItemLoadingChildren({ itemId }) { const { store } = useTreeViewContext(); const { classes, slots: styleSlots, slotProps: styleSlotProps } = useTreeViewStyleContext(); const itemDepth = useStore(store, itemsSelectors.itemDepth, itemId); const loadingChildrenCount = useStore(store, lazyLoadingSelectors.itemLoadingChildrenCount, itemId); const Loading = styleSlots.loading; const loadingProps = useSlotProps({ elementType: Loading ?? 'div', externalSlotProps: styleSlotProps.loading, ownerState: { itemId } }); // The count reported by `getChildrenCount()` wins over `slotProps.loading.itemsCount`, // which only acts as a fallback when the count is unknown. const itemsCount = loadingChildrenCount > 0 ? Math.min(loadingChildrenCount, MAX_LOADING_ITEMS_COUNT) : getLoadingItemsCount(loadingProps.itemsCount); return /*#__PURE__*/_jsx(RichTreeViewLoadingContext, { store: store, itemDepth: itemDepth + 1, children: Loading ? /*#__PURE__*/_jsx(Loading, _extends({}, loadingProps, { itemsCount: itemsCount })) : /*#__PURE__*/_jsx(RichTreeViewItemLoaders, { classes: classes, slots: { itemLoader: styleSlots.itemLoader }, slotProps: { itemLoader: styleSlotProps.itemLoader }, itemsCount: itemsCount }) }); } export const RichTreeViewItem = /*#__PURE__*/React.memo(function RichTreeViewItem({ itemSlot, itemSlotProps, itemId, skipChildren }) { const renderItemForRichTreeView = React.useContext(RichTreeViewItemsContext); const { store } = useTreeViewContext(); const itemMeta = useStore(store, itemsSelectors.itemMeta, itemId); const children = useStore(store, skipChildren ? selectorNoChildren : itemsSelectors.itemOrderedChildrenIds, itemId); const isLoadingChildren = useStore(store, lazyLoadingSelectors.isItemLoading, itemId); const Item = itemSlot ?? TreeItem; const _useSlotProps = useSlotProps({ elementType: Item, externalSlotProps: itemSlotProps, additionalProps: { label: itemMeta?.label, id: itemMeta?.idAttribute, itemId }, ownerState: { itemId, label: itemMeta?.label } }), itemProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded); let renderedChildren = renderItemForRichTreeView ? children?.map(renderItemForRichTreeView) : null; if (isLoadingChildren && !skipChildren && (children == null || children.length === 0)) { renderedChildren = /*#__PURE__*/_jsx(RichTreeViewItemLoadingChildren, { itemId: itemId }); } return /*#__PURE__*/_jsx(Item, _extends({}, itemProps, { children: renderedChildren })); }, fastObjectShallowCompare); if (process.env.NODE_ENV !== "production") RichTreeViewItem.displayName = "RichTreeViewItem"; export function RichTreeViewItems(props) { const { slots, slotProps, ownerState, forwardedProps, rootRef } = props; const { store } = useTreeViewContext(); const { classes } = useTreeViewStyleContext(); const itemSlot = slots?.item; const itemSlotProps = slotProps?.item; const domStructure = useStore(store, itemsSelectors.domStructure); const items = useStore(store, domStructure === 'flat' ? expansionSelectors.flatList : selectorChildrenIdsNull); const getRootProps = useTreeViewRootProps(store, forwardedProps, rootRef); const Root = slots.root; const rootProps = useSlotProps({ elementType: Root, externalSlotProps: slotProps?.root, className: classes.root, getSlotProps: getRootProps, ownerState }); const skipChildren = domStructure === 'flat'; const renderItem = React.useCallback(itemId => { return /*#__PURE__*/_jsx(RichTreeViewItem, { itemSlot: itemSlot, itemSlotProps: itemSlotProps, itemId: itemId, skipChildren: skipChildren }, itemId); }, [itemSlot, itemSlotProps, skipChildren]); return /*#__PURE__*/_jsx(RichTreeViewItemsContext.Provider, { value: renderItem, children: /*#__PURE__*/_jsx(Root, _extends({}, rootProps, { children: items.map(renderItem) })) }); }