UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

121 lines (118 loc) 4.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useTreeViewFocus = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _useEventCallback = require("@base-ui-components/utils/useEventCallback"); var _store = require("@mui/x-internals/store"); var _useTreeViewFocus = require("./useTreeViewFocus.selectors"); var _useTreeViewExpansion = require("../useTreeViewExpansion/useTreeViewExpansion.selectors"); var _useTreeViewItems = require("../useTreeViewItems/useTreeViewItems.selectors"); const useTreeViewFocus = ({ instance, params, store }) => { const setFocusedItemId = (0, _useEventCallback.useEventCallback)(itemId => { const focusedItemId = _useTreeViewFocus.focusSelectors.focusedItemId(store.state); if (focusedItemId === itemId) { return; } store.set('focus', (0, _extends2.default)({}, store.state.focus, { focusedItemId: itemId })); }); const isItemVisible = itemId => { const itemMeta = _useTreeViewItems.itemsSelectors.itemMeta(store.state, itemId); return itemMeta && (itemMeta.parentId == null || _useTreeViewExpansion.expansionSelectors.isItemExpanded(store.state, itemMeta.parentId)); }; const innerFocusItem = (event, itemId) => { const itemElement = instance.getItemDOMElement(itemId); if (itemElement) { itemElement.focus(); } setFocusedItemId(itemId); if (params.onItemFocus) { params.onItemFocus(event, itemId); } }; const focusItem = (0, _useEventCallback.useEventCallback)((event, itemId) => { // If we receive an itemId, and it is visible, the focus will be set to it if (isItemVisible(itemId)) { innerFocusItem(event, itemId); } }); const removeFocusedItem = (0, _useEventCallback.useEventCallback)(() => { const focusedItemId = _useTreeViewFocus.focusSelectors.focusedItemId(store.state); if (focusedItemId == null) { return; } const itemMeta = _useTreeViewItems.itemsSelectors.itemMeta(store.state, focusedItemId); if (itemMeta) { const itemElement = instance.getItemDOMElement(focusedItemId); if (itemElement) { itemElement.blur(); } } setFocusedItemId(null); }); // Whenever the items change, we need to ensure the focused item is still present. (0, _store.useStoreEffect)(store, _useTreeViewItems.itemsSelectors.itemMetaLookup, () => { const focusedItemId = _useTreeViewFocus.focusSelectors.focusedItemId(store.state); if (focusedItemId == null) { return; } const hasItemBeenRemoved = !_useTreeViewItems.itemsSelectors.itemMeta(store.state, focusedItemId); if (!hasItemBeenRemoved) { return; } const defaultFocusableItemId = _useTreeViewFocus.focusSelectors.defaultFocusableItemId(store.state); if (defaultFocusableItemId == null) { setFocusedItemId(null); return; } innerFocusItem(null, defaultFocusableItemId); }); const createRootHandleFocus = otherHandlers => event => { otherHandlers.onFocus?.(event); if (event.defaultMuiPrevented) { return; } // if the event bubbled (which is React specific) we don't want to steal focus const defaultFocusableItemId = _useTreeViewFocus.focusSelectors.defaultFocusableItemId(store.state); if (event.target === event.currentTarget && defaultFocusableItemId != null) { innerFocusItem(event, defaultFocusableItemId); } }; const createRootHandleBlur = otherHandlers => event => { otherHandlers.onBlur?.(event); if (event.defaultMuiPrevented) { return; } setFocusedItemId(null); }; return { getRootProps: otherHandlers => ({ onFocus: createRootHandleFocus(otherHandlers), onBlur: createRootHandleBlur(otherHandlers) }), publicAPI: { focusItem }, instance: { focusItem, removeFocusedItem } }; }; exports.useTreeViewFocus = useTreeViewFocus; useTreeViewFocus.getInitialState = () => ({ focus: { focusedItemId: null } }); useTreeViewFocus.params = { onItemFocus: true };