var $9QJ9Y$babelruntimehelpersextends = require("@babel/runtime/helpers/extends"); var $9QJ9Y$react = require("react"); var $9QJ9Y$radixuiprimitive = require("@radix-ui/primitive"); var $9QJ9Y$radixuireactcollection = require("@radix-ui/react-collection"); var $9QJ9Y$radixuireactcomposerefs = require("@radix-ui/react-compose-refs"); var $9QJ9Y$radixuireactcontext = require("@radix-ui/react-context"); var $9QJ9Y$radixuireactid = require("@radix-ui/react-id"); var $9QJ9Y$radixuireactprimitive = require("@radix-ui/react-primitive"); var $9QJ9Y$radixuireactusecallbackref = require("@radix-ui/react-use-callback-ref"); var $9QJ9Y$radixuireactusecontrollablestate = require("@radix-ui/react-use-controllable-state"); var $9QJ9Y$radixuireactdirection = require("@radix-ui/react-direction"); function $parcel$export(e, n, v, s) { Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); } function $parcel$interopDefault(a) { return a && a.__esModule ? a.default : a; } $parcel$export(module.exports, "createRovingFocusGroupScope", () => $0063afae63b3fa70$export$c7109489551a4f4); $parcel$export(module.exports, "RovingFocusGroup", () => $0063afae63b3fa70$export$8699f7c8af148338); $parcel$export(module.exports, "RovingFocusGroupItem", () => $0063afae63b3fa70$export$ab9df7c53fe8454); $parcel$export(module.exports, "Root", () => $0063afae63b3fa70$export$be92b6f5f03c0fe9); $parcel$export(module.exports, "Item", () => $0063afae63b3fa70$export$6d08773d2e66f8f2); const $0063afae63b3fa70$var$ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus'; const $0063afae63b3fa70$var$EVENT_OPTIONS = { bubbles: false, cancelable: true }; /* ------------------------------------------------------------------------------------------------- * RovingFocusGroup * -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$GROUP_NAME = 'RovingFocusGroup'; const [$0063afae63b3fa70$var$Collection, $0063afae63b3fa70$var$useCollection, $0063afae63b3fa70$var$createCollectionScope] = $9QJ9Y$radixuireactcollection.createCollection($0063afae63b3fa70$var$GROUP_NAME); const [$0063afae63b3fa70$var$createRovingFocusGroupContext, $0063afae63b3fa70$export$c7109489551a4f4] = $9QJ9Y$radixuireactcontext.createContextScope($0063afae63b3fa70$var$GROUP_NAME, [ $0063afae63b3fa70$var$createCollectionScope ]); const [$0063afae63b3fa70$var$RovingFocusProvider, $0063afae63b3fa70$var$useRovingFocusContext] = $0063afae63b3fa70$var$createRovingFocusGroupContext($0063afae63b3fa70$var$GROUP_NAME); const $0063afae63b3fa70$export$8699f7c8af148338 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{ return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Provider, { scope: props.__scopeRovingFocusGroup }, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.Slot, { scope: props.__scopeRovingFocusGroup }, /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusGroupImpl, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({}, props, { ref: forwardedRef })))); }); /*#__PURE__*/ Object.assign($0063afae63b3fa70$export$8699f7c8af148338, { displayName: $0063afae63b3fa70$var$GROUP_NAME }); /* -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$RovingFocusGroupImpl = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , orientation: orientation , loop: loop = false , dir: dir , currentTabStopId: currentTabStopIdProp , defaultCurrentTabStopId: defaultCurrentTabStopId , onCurrentTabStopIdChange: onCurrentTabStopIdChange , onEntryFocus: onEntryFocus , ...groupProps } = props; const ref = $9QJ9Y$react.useRef(null); const composedRefs = $9QJ9Y$radixuireactcomposerefs.useComposedRefs(forwardedRef, ref); const direction = $9QJ9Y$radixuireactdirection.useDirection(dir); const [currentTabStopId = null, setCurrentTabStopId] = $9QJ9Y$radixuireactusecontrollablestate.useControllableState({ prop: currentTabStopIdProp, defaultProp: defaultCurrentTabStopId, onChange: onCurrentTabStopIdChange }); const [isTabbingBackOut, setIsTabbingBackOut] = $9QJ9Y$react.useState(false); const handleEntryFocus = $9QJ9Y$radixuireactusecallbackref.useCallbackRef(onEntryFocus); const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup); const isClickFocusRef = $9QJ9Y$react.useRef(false); const [focusableItemsCount, setFocusableItemsCount] = $9QJ9Y$react.useState(0); $9QJ9Y$react.useEffect(()=>{ const node = ref.current; if (node) { node.addEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus); return ()=>node.removeEventListener($0063afae63b3fa70$var$ENTRY_FOCUS, handleEntryFocus) ; } }, [ handleEntryFocus ]); return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$RovingFocusProvider, { scope: __scopeRovingFocusGroup, orientation: orientation, dir: direction, loop: loop, currentTabStopId: currentTabStopId, onItemFocus: $9QJ9Y$react.useCallback((tabStopId)=>setCurrentTabStopId(tabStopId) , [ setCurrentTabStopId ]), onItemShiftTab: $9QJ9Y$react.useCallback(()=>setIsTabbingBackOut(true) , []), onFocusableItemAdd: $9QJ9Y$react.useCallback(()=>setFocusableItemsCount((prevCount)=>prevCount + 1 ) , []), onFocusableItemRemove: $9QJ9Y$react.useCallback(()=>setFocusableItemsCount((prevCount)=>prevCount - 1 ) , []) }, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.div, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({ tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0, "data-orientation": orientation }, groupProps, { ref: composedRefs, style: { outline: 'none', ...props.style }, onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, ()=>{ isClickFocusRef.current = true; }), onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, (event)=>{ // We normally wouldn't need this check, because we already check // that the focus is on the current target and not bubbling to it. // We do this because Safari doesn't focus buttons when clicked, and // instead, the wrapper will get focused and not through a bubbling event. const isKeyboardFocus = !isClickFocusRef.current; if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) { const entryFocusEvent = new CustomEvent($0063afae63b3fa70$var$ENTRY_FOCUS, $0063afae63b3fa70$var$EVENT_OPTIONS); event.currentTarget.dispatchEvent(entryFocusEvent); if (!entryFocusEvent.defaultPrevented) { const items = getItems().filter((item)=>item.focusable ); const activeItem = items.find((item)=>item.active ); const currentItem = items.find((item)=>item.id === currentTabStopId ); const candidateItems = [ activeItem, currentItem, ...items ].filter(Boolean); const candidateNodes = candidateItems.map((item)=>item.ref.current ); $0063afae63b3fa70$var$focusFirst(candidateNodes); } } isClickFocusRef.current = false; }), onBlur: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onBlur, ()=>setIsTabbingBackOut(false) ) }))); }); /* ------------------------------------------------------------------------------------------------- * RovingFocusGroupItem * -----------------------------------------------------------------------------------------------*/ const $0063afae63b3fa70$var$ITEM_NAME = 'RovingFocusGroupItem'; const $0063afae63b3fa70$export$ab9df7c53fe8454 = /*#__PURE__*/ $9QJ9Y$react.forwardRef((props, forwardedRef)=>{ const { __scopeRovingFocusGroup: __scopeRovingFocusGroup , focusable: focusable = true , active: active = false , tabStopId: tabStopId , ...itemProps } = props; const autoId = $9QJ9Y$radixuireactid.useId(); const id = tabStopId || autoId; const context = $0063afae63b3fa70$var$useRovingFocusContext($0063afae63b3fa70$var$ITEM_NAME, __scopeRovingFocusGroup); const isCurrentTabStop = context.currentTabStopId === id; const getItems = $0063afae63b3fa70$var$useCollection(__scopeRovingFocusGroup); const { onFocusableItemAdd: onFocusableItemAdd , onFocusableItemRemove: onFocusableItemRemove } = context; $9QJ9Y$react.useEffect(()=>{ if (focusable) { onFocusableItemAdd(); return ()=>onFocusableItemRemove() ; } }, [ focusable, onFocusableItemAdd, onFocusableItemRemove ]); return /*#__PURE__*/ $9QJ9Y$react.createElement($0063afae63b3fa70$var$Collection.ItemSlot, { scope: __scopeRovingFocusGroup, id: id, focusable: focusable, active: active }, /*#__PURE__*/ $9QJ9Y$react.createElement($9QJ9Y$radixuireactprimitive.Primitive.span, ($parcel$interopDefault($9QJ9Y$babelruntimehelpersextends))({ tabIndex: isCurrentTabStop ? 0 : -1, "data-orientation": context.orientation }, itemProps, { ref: forwardedRef, onMouseDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onMouseDown, (event)=>{ // We prevent focusing non-focusable items on `mousedown`. // Even though the item has tabIndex={-1}, that only means take it out of the tab order. if (!focusable) event.preventDefault(); // Safari doesn't focus a button when clicked so we run our logic on mousedown also else context.onItemFocus(id); }), onFocus: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onFocus, ()=>context.onItemFocus(id) ), onKeyDown: $9QJ9Y$radixuiprimitive.composeEventHandlers(props.onKeyDown, (event)=>{ if (event.key === 'Tab' && event.shiftKey) { context.onItemShiftTab(); return; } if (event.target !== event.currentTarget) return; const focusIntent = $0063afae63b3fa70$var$getFocusIntent(event, context.orientation, context.dir); if (focusIntent !== undefined) { event.preventDefault(); const items = getItems().filter((item)=>item.focusable ); let candidateNodes = items.map((item)=>item.ref.current ); if (focusIntent === 'last') candidateNodes.reverse(); else if (focusIntent === 'prev' || focusIntent === 'next') { if (focusIntent === 'prev') candidateNodes.reverse(); const currentIndex = candidateNodes.indexOf(event.currentTarget); candidateNodes = context.loop ? $0063afae63b3fa70$var$wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1); } /** * Imperative focus during keydown is risky so we prevent React's batching updates * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332 */ setTimeout(()=>$0063afae63b3fa70$var$focusFirst(candidateNodes) ); } }) }))); }); /*#__PURE__*/ Object.assign($0063afae63b3fa70$export$ab9df7c53fe8454, { displayName: $0063afae63b3fa70$var$ITEM_NAME }); /* -----------------------------------------------------------------------------------------------*/ // prettier-ignore const $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT = { ArrowLeft: 'prev', ArrowUp: 'prev', ArrowRight: 'next', ArrowDown: 'next', PageUp: 'first', Home: 'first', PageDown: 'last', End: 'last' }; function $0063afae63b3fa70$var$getDirectionAwareKey(key, dir) { if (dir !== 'rtl') return key; return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key; } function $0063afae63b3fa70$var$getFocusIntent(event, orientation, dir) { const key = $0063afae63b3fa70$var$getDirectionAwareKey(event.key, dir); if (orientation === 'vertical' && [ 'ArrowLeft', 'ArrowRight' ].includes(key)) return undefined; if (orientation === 'horizontal' && [ 'ArrowUp', 'ArrowDown' ].includes(key)) return undefined; return $0063afae63b3fa70$var$MAP_KEY_TO_FOCUS_INTENT[key]; } function $0063afae63b3fa70$var$focusFirst(candidates) { const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement; for (const candidate of candidates){ // if focus is already where we want to go, we don't want to keep going through the candidates if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return; candidate.focus(); if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return; } } /** * Wraps an array around itself at a given start index * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']` */ function $0063afae63b3fa70$var$wrapArray(array, startIndex) { return array.map((_, index)=>array[(startIndex + index) % array.length] ); } const $0063afae63b3fa70$export$be92b6f5f03c0fe9 = $0063afae63b3fa70$export$8699f7c8af148338; const $0063afae63b3fa70$export$6d08773d2e66f8f2 = $0063afae63b3fa70$export$ab9df7c53fe8454; //# sourceMappingURL=index.js.map