UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

160 lines (154 loc) • 5.17 kB
'use client'; import _extends from "@babel/runtime/helpers/esm/extends"; import * as React from 'react'; import useSlotProps from '@mui/utils/useSlotProps'; import { useStore } from '@mui/x-internals/store'; import { warnOnce } from '@mui/x-internals/warning'; import { TreeItemLoader } from "../../TreeItemLoader/index.mjs"; import { TreeItemLoaderContext } from "../../TreeItemLoader/TreeItemLoaderContext.mjs"; import { useTreeViewRootProps } from "../hooks/useTreeViewRootProps.mjs"; import { itemsSelectors } from "../plugins/items/index.mjs"; import { selectionSelectors } from "../plugins/selection/index.mjs"; import { jsx as _jsx } from "react/jsx-runtime"; export const DEFAULT_LOADING_ITEMS_COUNT = 5; export const MAX_LOADING_ITEMS_COUNT = 100; export function getLoadingItemsCount(itemsCount) { if (process.env.NODE_ENV !== 'production') { if (itemsCount != null && (!Number.isFinite(itemsCount) || itemsCount < 0)) { warnOnce([`MUI X: The \`itemsCount\` value in \`slotProps.loading\` received an invalid value (${itemsCount}).`, 'It must be a non-negative finite number.']); } } const rawCount = itemsCount ?? DEFAULT_LOADING_ITEMS_COUNT; return Number.isFinite(rawCount) ? Math.max(1, Math.min(MAX_LOADING_ITEMS_COUNT, Math.floor(rawCount))) : DEFAULT_LOADING_ITEMS_COUNT; } /** * The owner state of the `loading` slot. */ function RichTreeViewItemLoaderRow(props) { const { classes, slots, slotProps, ownerState } = props; const ItemLoader = slots.itemLoader ?? TreeItemLoader; const itemLoaderProps = useSlotProps({ elementType: ItemLoader, externalSlotProps: slotProps?.itemLoader, className: classes.itemLoader, additionalProps: { role: 'treeitem', 'aria-disabled': true }, ownerState }); return /*#__PURE__*/_jsx(ItemLoader, _extends({}, itemLoaderProps)); } /** * Renders the default loading rows without any wrapper. * Used by `RichTreeViewLoading` for the whole-tree loading state and by * `RichTreeViewItem` for the children of an item that lazily loads them. * It must render inside a `TreeItemLoaderContext` provider. */ export function RichTreeViewItemLoaders(props) { const { classes, slots, slotProps, itemsCount } = props; const { itemDepth, isCheckboxSelectionEnabled } = React.useContext(TreeItemLoaderContext); return /*#__PURE__*/_jsx(React.Fragment, { children: Array.from({ length: itemsCount }, (_, index) => /*#__PURE__*/_jsx(RichTreeViewItemLoaderRow, { classes: classes, slots: slots, slotProps: slotProps, ownerState: { index, itemsCount, itemDepth, isCheckboxSelectionEnabled } }, index)) }); } /** * Provides the layout information the loading rows need to `TreeItemLoader`. * Wraps both the default rows and a custom `loading` slot, so custom loading * UIs composed with `TreeItemLoader` keep the correct depth and height. */ export function RichTreeViewLoadingContext(props) { const { store, itemDepth = 0, children } = props; const itemHeight = useStore(store, itemsSelectors.itemHeight); const isCheckboxSelectionEnabled = useStore(store, selectionSelectors.isCheckboxSelectionEnabled); const contextValue = React.useMemo(() => ({ itemDepth, itemHeight, isCheckboxSelectionEnabled }), [itemDepth, itemHeight, isCheckboxSelectionEnabled]); return /*#__PURE__*/_jsx(TreeItemLoaderContext.Provider, { value: contextValue, children: children }); } /** * Renders the loading placeholder shared by `RichTreeView` and `RichTreeViewPro`. * It reuses `useTreeViewRootProps` so the root element keeps the same `role="tree"`, * `id`, `aria-multiselectable` and slot/className behavior as the non-loading tree. */ export function RichTreeViewLoading(props) { const { store, slots, slotProps, ownerState, forwardedProps, rootRef, classes } = props; const getRootProps = useTreeViewRootProps(store, forwardedProps, rootRef); const Root = slots.root; const Loading = slots.loading; const loadingProps = useSlotProps({ elementType: Loading ?? 'div', externalSlotProps: slotProps?.loading, ownerState: { itemId: null } }); const itemsCount = getLoadingItemsCount(loadingProps.itemsCount); const rootProps = useSlotProps({ elementType: Root, externalSlotProps: slotProps?.root, className: classes.root, getSlotProps: getRootProps, additionalProps: _extends({ 'aria-busy': true }, forwardedProps['aria-label'] == null && forwardedProps['aria-labelledby'] == null ? { 'aria-label': 'Loading' } : {}), ownerState }); return /*#__PURE__*/_jsx(Root, _extends({}, rootProps, { children: /*#__PURE__*/_jsx(RichTreeViewLoadingContext, { store: store, children: Loading ? /*#__PURE__*/_jsx(Loading, _extends({}, loadingProps, { itemsCount: itemsCount })) : /*#__PURE__*/_jsx(RichTreeViewItemLoaders, { classes: classes, slots: slots, slotProps: slotProps, itemsCount: itemsCount }) }) })); }