UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

290 lines (286 loc) 12.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 _extractEventHandlers = _interopRequireDefault(require("@mui/utils/extractEventHandlers")); var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef")); var _TreeViewProvider = require("../internals/TreeViewProvider"); var _useTreeItemUtils = require("../hooks/useTreeItemUtils"); var _TreeViewItemDepthContext = require("../internals/TreeViewItemDepthContext"); var _tree = require("../internals/utils/tree"); var _useSelector = require("../internals/hooks/useSelector"); var _useTreeViewFocus = require("../internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors"); var _useTreeViewId = require("../internals/corePlugins/useTreeViewId/useTreeViewId.utils"); var _useTreeViewItems = require("../internals/plugins/useTreeViewItems/useTreeViewItems.selectors"); var _useTreeViewId2 = require("../internals/corePlugins/useTreeViewId/useTreeViewId.selectors"); var _useTreeViewExpansion = require("../internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors"); var _useTreeViewSelection = require("../internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors"); const useTreeItem = parameters => { const { runItemPlugins, instance, publicAPI, store } = (0, _TreeViewProvider.useTreeViewContext)(); const depthContext = React.useContext(_TreeViewItemDepthContext.TreeViewItemDepthContext); const depth = (0, _useSelector.useSelector)(store, (...params) => { if (typeof depthContext === 'function') { return depthContext(...params); } return depthContext; }, parameters.itemId); 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, _useForkRef.default)(rootRef, pluginRootRef, rootRefObject); const handleContentRef = (0, _useForkRef.default)(contentRef, contentRefObject); const checkboxRef = React.useRef(null); const treeId = (0, _useSelector.useSelector)(store, _useTreeViewId2.selectorTreeViewId); const isSelectionEnabledForItem = (0, _useSelector.useSelector)(store, _useTreeViewSelection.selectorIsItemSelectionEnabled, itemId); const isCheckboxSelectionEnabled = (0, _useSelector.useSelector)(store, _useTreeViewSelection.selectorIsCheckboxSelectionEnabled); const idAttribute = (0, _useTreeViewId.generateTreeItemIdAttribute)({ itemId, treeId, id }); const shouldBeAccessibleWithTab = (0, _useSelector.useSelector)(store, _useTreeViewFocus.selectorIsItemTheDefaultFocusableItem, itemId); const sharedPropsEnhancerParams = { rootRefObject, contentRefObject, interactions }; const createRootHandleFocus = otherHandlers => event => { otherHandlers.onFocus?.(event); if (event.defaultMuiPrevented) { return; } if (!status.focused && (0, _useTreeViewItems.selectorCanItemBeFocused)(store.value, itemId) && event.currentTarget === event.target) { instance.focusItem(event, itemId); } }; const createRootHandleBlur = otherHandlers => event => { otherHandlers.onBlur?.(event); if (event.defaultMuiPrevented) { return; } const rootElement = instance.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; } instance.removeFocusedItem(); }; const createRootHandleKeyDown = otherHandlers => event => { otherHandlers.onKeyDown?.(event); if (event.defaultMuiPrevented || event.target?.dataset?.element === 'labelInput') { return; } instance.handleItemKeyDown(event, itemId); }; const createLabelHandleDoubleClick = otherHandlers => event => { otherHandlers.onDoubleClick?.(event); if (event.defaultMuiPrevented) { return; } interactions.toggleItemEditing(); }; const createContentHandleClick = otherHandlers => event => { otherHandlers.onClick?.(event); instance.handleItemClick(event, itemId); if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) { return; } if ((0, _useTreeViewExpansion.selectorItemExpansionTrigger)(store.value) === '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 ((0, _useTreeViewExpansion.selectorItemExpansionTrigger)(store.value) === 'iconContainer') { interactions.handleExpansion(event); } }; const getContextProviderProps = () => ({ itemId, id }); const getRootProps = (externalProps = {}) => { const externalEventHandlers = (0, _extends2.default)({}, (0, _extractEventHandlers.default)(parameters), (0, _extractEventHandlers.default)(externalProps)); // https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ let ariaSelected; if (status.selected) { // - each selected node has aria-selected set to true. ariaSelected = true; } else if (!isSelectionEnabledForItem) { // - if the tree contains nodes that are not selectable, aria-selected is not present on those nodes. ariaSelected = undefined; } else { // - all nodes that are selectable but not selected have aria-selected set to false. ariaSelected = false; } const props = (0, _extends2.default)({}, externalEventHandlers, { ref: handleRootRef, role: 'treeitem', tabIndex: shouldBeAccessibleWithTab ? 0 : -1, id: idAttribute, 'aria-expanded': status.expandable ? status.expanded : undefined, 'aria-selected': ariaSelected, '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 }, 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;