UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

272 lines (268 loc) 11.5 kB
"use strict"; 'use client'; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useTreeItem = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _store = require("@mui/x-internals/store"); var _extractEventHandlers = _interopRequireDefault(require("@mui/utils/extractEventHandlers")); var _useMergedRefs = require("@base-ui/utils/useMergedRefs"); var _TreeViewProvider = require("../internals/TreeViewProvider"); var _useTreeItemUtils = require("../hooks/useTreeItemUtils"); var _TreeViewItemDepthContext = require("../internals/TreeViewItemDepthContext"); var _tree = require("../internals/utils/tree"); var _focus = require("../internals/plugins/focus"); var _items = require("../internals/plugins/items"); var _id = require("../internals/plugins/id"); var _expansion = require("../internals/plugins/expansion"); var _selection = require("../internals/plugins/selection"); // TODO v8: Remove the lazy loading plugin from the typing on the community useTreeItem and ask users to pass the TStore generic. const depthSelector = (state, itemId, depthContext) => { if (typeof depthContext === 'function') { return depthContext(state, itemId); } return depthContext; }; const useTreeItem = parameters => { const { runItemPlugins, publicAPI, store } = (0, _TreeViewProvider.useTreeViewContext)(); const depthContext = React.useContext(_TreeViewItemDepthContext.TreeViewItemDepthContext); const depth = (0, _store.useStore)(store, depthSelector, parameters.itemId, depthContext); const { id, itemId, label, children, rootRef } = parameters; const { rootRef: pluginRootRef, contentRef, propsEnhancers } = runItemPlugins(parameters); const { interactions, status } = (0, _useTreeItemUtils.useTreeItemUtils)({ itemId, children }); const rootRefObject = React.useRef(null); const contentRefObject = React.useRef(null); const handleRootRef = (0, _useMergedRefs.useMergedRefs)(rootRef, pluginRootRef, rootRefObject); const handleContentRef = (0, _useMergedRefs.useMergedRefs)(contentRef, contentRefObject); const checkboxRef = React.useRef(null); const isCheckboxSelectionEnabled = (0, _store.useStore)(store, _selection.selectionSelectors.isCheckboxSelectionEnabled); const idAttribute = (0, _store.useStore)(store, _id.idSelectors.treeItemIdAttribute, itemId, id); const shouldBeAccessibleWithTab = (0, _store.useStore)(store, _focus.focusSelectors.isItemTheDefaultFocusableItem, itemId); const sharedPropsEnhancerParams = { rootRefObject, contentRefObject, interactions }; const createRootHandleFocus = otherHandlers => event => { otherHandlers.onFocus?.(event); if (event.defaultMuiPrevented) { return; } if (!status.focused && _items.itemsSelectors.canItemBeFocused(store.state, itemId) && event.currentTarget === event.target) { store.focus.focusItem(event, itemId); } }; const createRootHandleBlur = otherHandlers => event => { otherHandlers.onBlur?.(event); if (event.defaultMuiPrevented) { return; } const rootElement = store.items.getItemDOMElement(itemId); // Don't blur the root when switching to editing mode // the input that triggers the root blur can be either the relatedTarget (when entering editing state) or the target (when exiting editing state) // when we enter the editing state, we focus the input -> we don't want to remove the focused item from the state if (status.editing || // we can exit the editing state by clicking outside the input (within the Tree Item) or by pressing Enter or Escape -> we don't want to remove the focused item from the state in these cases // we can also exit the editing state by clicking on the root itself -> want to remove the focused item from the state in this case event.relatedTarget && (0, _tree.isTargetInDescendants)(event.relatedTarget, rootElement) && (event.target && event.target?.dataset?.element === 'labelInput' && (0, _tree.isTargetInDescendants)(event.target, rootElement) || event.relatedTarget?.dataset?.element === 'labelInput')) { return; } store.focus.removeFocusedItem(); }; const createRootHandleKeyDown = otherHandlers => event => { otherHandlers.onKeyDown?.(event); if (event.defaultMuiPrevented || event.target?.dataset?.element === 'labelInput') { return; } store.keyboardNavigation.handleItemKeyDown(event, itemId); }; const createLabelHandleDoubleClick = otherHandlers => event => { otherHandlers.onDoubleClick?.(event); if (event.defaultMuiPrevented) { return; } interactions.toggleItemEditing(); }; const createContentHandleClick = otherHandlers => event => { otherHandlers.onClick?.(event); store.items.handleItemClick(event, itemId); if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) { return; } if (_expansion.expansionSelectors.triggerSlot(store.state) === 'content') { interactions.handleExpansion(event); } if (!isCheckboxSelectionEnabled) { interactions.handleSelection(event); } }; const createContentHandleMouseDown = otherHandlers => event => { otherHandlers.onMouseDown?.(event); if (event.defaultMuiPrevented) { return; } // Prevent text selection if (event.shiftKey || event.ctrlKey || event.metaKey || status.disabled) { event.preventDefault(); } }; const createIconContainerHandleClick = otherHandlers => event => { otherHandlers.onClick?.(event); if (event.defaultMuiPrevented) { return; } if (_expansion.expansionSelectors.triggerSlot(store.state) === 'iconContainer') { interactions.handleExpansion(event); } }; const getContextProviderProps = () => ({ itemId, id }); const getRootProps = (externalProps = {}) => { const externalEventHandlers = (0, _extends2.default)({}, (0, _extractEventHandlers.default)(parameters), (0, _extractEventHandlers.default)(externalProps)); const props = (0, _extends2.default)({}, externalEventHandlers, { ref: handleRootRef, role: 'treeitem', tabIndex: shouldBeAccessibleWithTab ? 0 : -1, id: idAttribute, 'aria-expanded': status.expandable ? status.expanded : undefined, 'aria-disabled': status.disabled || undefined }, externalProps, { style: (0, _extends2.default)({}, externalProps.style ?? {}, { '--TreeView-itemDepth': depth }), onFocus: createRootHandleFocus(externalEventHandlers), onBlur: createRootHandleBlur(externalEventHandlers), onKeyDown: createRootHandleKeyDown(externalEventHandlers) }); const enhancedRootProps = propsEnhancers.root?.((0, _extends2.default)({}, sharedPropsEnhancerParams, { externalEventHandlers })) ?? {}; return (0, _extends2.default)({}, props, enhancedRootProps); }; const getContentProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); const props = (0, _extends2.default)({}, externalEventHandlers, externalProps, { ref: handleContentRef, onClick: createContentHandleClick(externalEventHandlers), onMouseDown: createContentHandleMouseDown(externalEventHandlers), status }); ['expanded', 'selected', 'focused', 'disabled', 'editing', 'editable'].forEach(key => { if (status[key]) { props[`data-${key}`] = ''; } }); const enhancedContentProps = propsEnhancers.content?.((0, _extends2.default)({}, sharedPropsEnhancerParams, { externalEventHandlers })) ?? {}; return (0, _extends2.default)({}, props, enhancedContentProps); }; const getCheckboxProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); const props = (0, _extends2.default)({}, externalEventHandlers, { ref: checkboxRef, 'aria-hidden': true }, externalProps); const enhancedCheckboxProps = propsEnhancers.checkbox?.((0, _extends2.default)({}, sharedPropsEnhancerParams, { externalEventHandlers })) ?? {}; return (0, _extends2.default)({}, props, enhancedCheckboxProps); }; const getLabelProps = (externalProps = {}) => { const externalEventHandlers = (0, _extends2.default)({}, (0, _extractEventHandlers.default)(externalProps)); const props = (0, _extends2.default)({}, externalEventHandlers, { children: label }, externalProps, { onDoubleClick: createLabelHandleDoubleClick(externalEventHandlers) }); const enhancedLabelProps = propsEnhancers.label?.((0, _extends2.default)({}, sharedPropsEnhancerParams, { externalEventHandlers })) ?? {}; return (0, _extends2.default)({}, enhancedLabelProps, props); }; const getLabelInputProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); const enhancedLabelInputProps = propsEnhancers.labelInput?.((0, _extends2.default)({}, sharedPropsEnhancerParams, { externalEventHandlers })) ?? {}; return (0, _extends2.default)({}, externalProps, enhancedLabelInputProps); }; const getIconContainerProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); return (0, _extends2.default)({}, externalEventHandlers, externalProps, { onClick: createIconContainerHandleClick(externalEventHandlers) }); }; const getErrorContainerProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); return (0, _extends2.default)({}, externalEventHandlers, externalProps); }; const getLoadingContainerProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); return (0, _extends2.default)({ size: '12px', thickness: 6 }, externalEventHandlers, externalProps); }; const getGroupTransitionProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); const response = (0, _extends2.default)({}, externalEventHandlers, { unmountOnExit: true, component: 'ul', role: 'group', in: status.expanded, children }, externalProps); return response; }; const getDragAndDropOverlayProps = (externalProps = {}) => { const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps); const enhancedDragAndDropOverlayProps = propsEnhancers.dragAndDropOverlay?.((0, _extends2.default)({}, sharedPropsEnhancerParams, { externalEventHandlers })) ?? {}; return (0, _extends2.default)({}, externalProps, enhancedDragAndDropOverlayProps); }; return { getContextProviderProps, getRootProps, getContentProps, getGroupTransitionProps, getIconContainerProps, getCheckboxProps, getLabelProps, getLabelInputProps, getDragAndDropOverlayProps, getErrorContainerProps, getLoadingContainerProps, rootRef: handleRootRef, status, publicAPI }; }; exports.useTreeItem = useTreeItem;