UNPKG

@ariakit/react-core

Version:

Ariakit React core

335 lines (302 loc) 13.1 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); var _2XVCJUVBcjs = require('./2XVCJUVB.cjs'); var _EOGOO37Xcjs = require('./EOGOO37X.cjs'); var _BB34VMZXcjs = require('./BB34VMZX.cjs'); var _RDNUVX4Vcjs = require('./RDNUVX4V.cjs'); var _SQLDFLTEcjs = require('./SQLDFLTE.cjs'); var _4KGS3DOWcjs = require('./4KGS3DOW.cjs'); // src/composite/composite.tsx var _array = require('@ariakit/core/utils/array'); var _dom = require('@ariakit/core/utils/dom'); var _events = require('@ariakit/core/utils/events'); var _focus = require('@ariakit/core/utils/focus'); var _misc = require('@ariakit/core/utils/misc'); var _react = require('react'); var _jsxruntime = require('react/jsx-runtime'); var TagName = "div"; function isGrid(items) { return items.some((item) => !!item.rowId); } function isPrintableKey(event) { const target = event.target; if (target && !_dom.isTextField.call(void 0, target)) return false; return event.key.length === 1 && !event.ctrlKey && !event.metaKey; } function isModifierKey(event) { return event.key === "Shift" || event.key === "Control" || event.key === "Alt" || event.key === "Meta"; } function useKeyboardEventProxy(store, onKeyboardEvent, previousElementRef) { return _4KGS3DOWcjs.useEvent.call(void 0, (event) => { var _a; onKeyboardEvent == null ? void 0 : onKeyboardEvent(event); if (event.defaultPrevented) return; if (event.isPropagationStopped()) return; if (!_events.isSelfTarget.call(void 0, event)) return; if (isModifierKey(event)) return; if (isPrintableKey(event)) return; const state = store.getState(); const activeElement = (_a = _2XVCJUVBcjs.getEnabledItem.call(void 0, store, state.activeId)) == null ? void 0 : _a.element; if (!activeElement) return; const { view, ...eventInit } = event; const previousElement = previousElementRef == null ? void 0 : previousElementRef.current; if (activeElement !== previousElement) { activeElement.focus(); } if (!_events.fireKeyboardEvent.call(void 0, activeElement, event.type, eventInit)) { event.preventDefault(); } if (event.currentTarget.contains(activeElement)) { event.stopPropagation(); } }); } function findFirstEnabledItemInTheLastRow(items) { return _2XVCJUVBcjs.findFirstEnabledItem.call(void 0, _array.flatten2DArray.call(void 0, _array.reverseArray.call(void 0, _2XVCJUVBcjs.groupItemsByRows.call(void 0, items))) ); } function withBaseScrollPreserved(store, callback) { const { virtualFocus, baseElement } = store.getState(); if (!virtualFocus || !baseElement || !_dom.isTextField.call(void 0, baseElement)) { callback(); return; } const savedScrollLeft = baseElement.scrollLeft; const savedScrollTop = baseElement.scrollTop; callback(); baseElement.scrollLeft = savedScrollLeft; baseElement.scrollTop = savedScrollTop; } function useScheduleFocus(store) { const [scheduled, setScheduled] = _react.useState.call(void 0, false); const schedule = _react.useCallback.call(void 0, () => setScheduled(true), []); const activeItem = _RDNUVX4Vcjs.useStoreState.call(void 0, store, (state) => _2XVCJUVBcjs.getEnabledItem.call(void 0, store, state.activeId) ); _react.useEffect.call(void 0, () => { const activeElement = activeItem == null ? void 0 : activeItem.element; if (!scheduled) return; if (!activeElement) return; setScheduled(false); withBaseScrollPreserved(store, () => { activeElement.focus({ preventScroll: true }); }); }, [store, activeItem, scheduled]); return schedule; } var useComposite = _SQLDFLTEcjs.createHook.call(void 0, function useComposite2({ store, composite = true, focusOnMove = composite, moveOnKeyPress = true, ...props }) { const context = _EOGOO37Xcjs.useCompositeProviderContext.call(void 0, ); store = store || context; _misc.invariant.call(void 0, store, process.env.NODE_ENV !== "production" && "Composite must receive a `store` prop or be wrapped in a CompositeProvider component." ); const ref = _react.useRef.call(void 0, null); const previousElementRef = _react.useRef.call(void 0, null); const scheduleFocus = useScheduleFocus(store); const moves = _RDNUVX4Vcjs.useStoreState.call(void 0, store, "moves"); const [, setBaseElement] = _4KGS3DOWcjs.useTransactionState.call(void 0, composite ? store.setBaseElement : null ); _react.useEffect.call(void 0, () => { var _a; if (!store) return; if (!moves) return; if (!composite) return; if (!focusOnMove) return; const { activeId: activeId2 } = store.getState(); const itemElement = (_a = _2XVCJUVBcjs.getEnabledItem.call(void 0, store, activeId2)) == null ? void 0 : _a.element; if (!itemElement) return; withBaseScrollPreserved(store, () => _focus.focusIntoView.call(void 0, itemElement)); }, [store, moves, composite, focusOnMove]); _4KGS3DOWcjs.useSafeLayoutEffect.call(void 0, () => { if (!store) return; if (!moves) return; if (!composite) return; const { baseElement, activeId: activeId2 } = store.getState(); const isSelfAcive = activeId2 === null; if (!isSelfAcive) return; if (!baseElement) return; const previousElement = previousElementRef.current; previousElementRef.current = null; if (previousElement) { _events.fireBlurEvent.call(void 0, previousElement, { relatedTarget: baseElement }); } if (!_focus.hasFocus.call(void 0, baseElement)) { baseElement.focus(); } }, [store, moves, composite]); const activeId = _RDNUVX4Vcjs.useStoreState.call(void 0, store, "activeId"); const virtualFocus = _RDNUVX4Vcjs.useStoreState.call(void 0, store, "virtualFocus"); _4KGS3DOWcjs.useSafeLayoutEffect.call(void 0, () => { var _a; if (!store) return; if (!composite) return; if (!virtualFocus) return; const previousElement = previousElementRef.current; previousElementRef.current = null; if (!previousElement) return; const activeElement = (_a = _2XVCJUVBcjs.getEnabledItem.call(void 0, store, activeId)) == null ? void 0 : _a.element; const relatedTarget = activeElement || _dom.getActiveElement.call(void 0, previousElement); if (relatedTarget === previousElement) return; _events.fireBlurEvent.call(void 0, previousElement, { relatedTarget }); }, [store, activeId, virtualFocus, composite]); const onKeyDownCapture = useKeyboardEventProxy( store, props.onKeyDownCapture, previousElementRef ); const onKeyUpCapture = useKeyboardEventProxy( store, props.onKeyUpCapture, previousElementRef ); const onFocusCaptureProp = props.onFocusCapture; const onFocusCapture = _4KGS3DOWcjs.useEvent.call(void 0, (event) => { onFocusCaptureProp == null ? void 0 : onFocusCaptureProp(event); if (event.defaultPrevented) return; if (!store) return; const { virtualFocus: virtualFocus2 } = store.getState(); if (!virtualFocus2) return; const previousActiveElement = event.relatedTarget; const isSilentlyFocused = _2XVCJUVBcjs.silentlyFocused.call(void 0, event.currentTarget); if (_events.isSelfTarget.call(void 0, event) && isSilentlyFocused) { event.stopPropagation(); previousElementRef.current = previousActiveElement; } }); const onFocusProp = props.onFocus; const onFocus = _4KGS3DOWcjs.useEvent.call(void 0, (event) => { onFocusProp == null ? void 0 : onFocusProp(event); if (event.defaultPrevented) return; if (!composite) return; if (!store) return; const { relatedTarget } = event; const { virtualFocus: virtualFocus2 } = store.getState(); if (virtualFocus2) { if (_events.isSelfTarget.call(void 0, event) && !_2XVCJUVBcjs.isItem.call(void 0, store, relatedTarget)) { queueMicrotask(scheduleFocus); } } else if (_events.isSelfTarget.call(void 0, event)) { store.setActiveId(null); } }); const onBlurCaptureProp = props.onBlurCapture; const onBlurCapture = _4KGS3DOWcjs.useEvent.call(void 0, (event) => { var _a; onBlurCaptureProp == null ? void 0 : onBlurCaptureProp(event); if (event.defaultPrevented) return; if (!store) return; const { virtualFocus: virtualFocus2, activeId: activeId2 } = store.getState(); if (!virtualFocus2) return; const activeElement = (_a = _2XVCJUVBcjs.getEnabledItem.call(void 0, store, activeId2)) == null ? void 0 : _a.element; const nextActiveElement = event.relatedTarget; const nextActiveElementIsItem = _2XVCJUVBcjs.isItem.call(void 0, store, nextActiveElement); const previousElement = previousElementRef.current; previousElementRef.current = null; if (_events.isSelfTarget.call(void 0, event) && nextActiveElementIsItem) { if (nextActiveElement === activeElement) { if (previousElement && previousElement !== nextActiveElement) { _events.fireBlurEvent.call(void 0, previousElement, event); } } else if (activeElement) { _events.fireBlurEvent.call(void 0, activeElement, event); } else if (previousElement) { _events.fireBlurEvent.call(void 0, previousElement, event); } event.stopPropagation(); } else { const targetIsItem = _2XVCJUVBcjs.isItem.call(void 0, store, event.target); if (!targetIsItem && activeElement) { _events.fireBlurEvent.call(void 0, activeElement, event); } } }); const onKeyDownProp = props.onKeyDown; const moveOnKeyPressProp = _4KGS3DOWcjs.useBooleanEvent.call(void 0, moveOnKeyPress); const onKeyDown = _4KGS3DOWcjs.useEvent.call(void 0, (event) => { var _a; onKeyDownProp == null ? void 0 : onKeyDownProp(event); if (event.nativeEvent.isComposing) return; if (event.defaultPrevented) return; if (!store) return; if (!_events.isSelfTarget.call(void 0, event)) return; const { orientation, renderedItems, activeId: activeId2 } = store.getState(); const activeItem = _2XVCJUVBcjs.getEnabledItem.call(void 0, store, activeId2); if ((_a = activeItem == null ? void 0 : activeItem.element) == null ? void 0 : _a.isConnected) return; const isVertical = orientation !== "horizontal"; const isHorizontal = orientation !== "vertical"; const grid = isGrid(renderedItems); const isHorizontalKey = event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Home" || event.key === "End"; if (isHorizontalKey && _dom.isTextField.call(void 0, event.currentTarget)) return; const up = () => { if (grid) { const item = findFirstEnabledItemInTheLastRow(renderedItems); return item == null ? void 0 : item.id; } return store == null ? void 0 : store.last(); }; const keyMap = { ArrowUp: (grid || isVertical) && up, ArrowRight: (grid || isHorizontal) && store.first, ArrowDown: (grid || isVertical) && store.first, ArrowLeft: (grid || isHorizontal) && store.last, Home: store.first, End: store.last, PageUp: store.first, PageDown: store.last }; const action = keyMap[event.key]; if (action) { const id = action(); if (id !== void 0) { if (!moveOnKeyPressProp(event)) return; event.preventDefault(); store.move(id); } } }); props = _4KGS3DOWcjs.useWrapElement.call(void 0, props, (element) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _EOGOO37Xcjs.CompositeContextProvider, { value: store, children: element }), [store] ); const activeDescendant = _RDNUVX4Vcjs.useStoreState.call(void 0, store, (state) => { var _a; if (!store) return; if (!composite) return; if (!state.virtualFocus) return; return (_a = _2XVCJUVBcjs.getEnabledItem.call(void 0, store, state.activeId)) == null ? void 0 : _a.id; }); props = { "aria-activedescendant": activeDescendant, ...props, ref: _4KGS3DOWcjs.useMergeRefs.call(void 0, ref, setBaseElement, props.ref), onKeyDownCapture, onKeyUpCapture, onFocusCapture, onFocus, onBlurCapture, onKeyDown }; const focusable = _RDNUVX4Vcjs.useStoreState.call(void 0, store, (state) => composite && (state.virtualFocus || state.activeId === null) ); props = _BB34VMZXcjs.useFocusable.call(void 0, { focusable, ...props }); return props; } ); var Composite = _SQLDFLTEcjs.forwardRef.call(void 0, function Composite2(props) { const htmlProps = useComposite(props); return _SQLDFLTEcjs.createElement.call(void 0, TagName, htmlProps); }); exports.useComposite = useComposite; exports.Composite = Composite;