@loke/ui
Version:
2 lines (1 loc) • 9.08 kB
JavaScript
var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames,getOwnPropertyDescriptor:__getOwnPropDesc}=Object,__hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node,__toESMCache_esm,__toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__toCommonJS=(from)=>{var entry=(__moduleCache??=new WeakMap).get(from),desc;if(entry)return entry;if(entry=__defProp({},"__esModule",{value:!0}),from&&typeof from==="object"||typeof from==="function"){for(var key of __getOwnPropNames(from))if(!__hasOwnProp.call(entry,key))__defProp(entry,key,{get:__accessProp.bind(from,key),enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return __moduleCache.set(from,entry),entry},__moduleCache;var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var exports_roving_focus={};__export(exports_roving_focus,{createRovingFocusGroupScope:()=>createRovingFocusGroupScope,RovingFocusGroupItem:()=>RovingFocusGroupItem,RovingFocusGroup:()=>RovingFocusGroup,Root:()=>Root,Item:()=>Item});module.exports=__toCommonJS(exports_roving_focus);var import_collection=require("@loke/ui/collection"),import_compose_events=require("@loke/ui/compose-events"),import_compose_refs=require("@loke/ui/compose-refs"),import_context=require("@loke/ui/context"),import_primitive=require("@loke/ui/primitive"),import_use_callback_ref=require("@loke/ui/use-callback-ref"),import_use_controllable_state=require("@loke/ui/use-controllable-state"),import_use_direction=require("@loke/ui/use-direction"),import_use_id=require("@loke/ui/use-id"),import_react=require("react"),jsx_runtime=require("react/jsx-runtime"),ENTRY_FOCUS="rovingFocusGroup.onEntryFocus",EVENT_OPTIONS={bubbles:!1,cancelable:!0},GROUP_NAME="RovingFocusGroup",[Collection,useCollection,createCollectionScope]=import_collection.createCollection(GROUP_NAME),[createRovingFocusGroupContext,createRovingFocusGroupScope]=import_context.createContextScope(GROUP_NAME,[createCollectionScope]),[RovingFocusProvider,useRovingFocusContext]=createRovingFocusGroupContext(GROUP_NAME),RovingFocusGroup=import_react.forwardRef((props,forwardedRef)=>{return jsx_runtime.jsx(Collection.Provider,{scope:props.__scopeRovingFocusGroup,children:jsx_runtime.jsx(Collection.Slot,{scope:props.__scopeRovingFocusGroup,children:jsx_runtime.jsx(RovingFocusGroupImpl,{...props,ref:forwardedRef})})})});RovingFocusGroup.displayName=GROUP_NAME;var RovingFocusGroupImpl=import_react.forwardRef((props,forwardedRef)=>{let{__scopeRovingFocusGroup,orientation,loop=!1,dir,currentTabStopId:currentTabStopIdProp,defaultCurrentTabStopId,onCurrentTabStopIdChange,onEntryFocus,preventScrollOnEntryFocus=!1,...groupProps}=props,ref=import_react.useRef(null),composedRefs=import_compose_refs.useComposedRefs(forwardedRef,ref),direction=import_use_direction.useDirection(dir),[currentTabStopId,setCurrentTabStopId]=import_use_controllable_state.useControllableState({caller:GROUP_NAME,defaultProp:defaultCurrentTabStopId??null,onChange:onCurrentTabStopIdChange,prop:currentTabStopIdProp}),[isTabbingBackOut,setIsTabbingBackOut]=import_react.useState(!1),handleEntryFocus=import_use_callback_ref.useCallbackRef(onEntryFocus),getItems=useCollection(__scopeRovingFocusGroup),isClickFocusRef=import_react.useRef(!1),[focusableItemsCount,setFocusableItemsCount]=import_react.useState(0);return import_react.useEffect(()=>{let node=ref.current;if(node)return node.addEventListener(ENTRY_FOCUS,handleEntryFocus),()=>node.removeEventListener(ENTRY_FOCUS,handleEntryFocus)},[handleEntryFocus]),jsx_runtime.jsx(RovingFocusProvider,{currentTabStopId,dir:direction,loop,onFocusableItemAdd:import_react.useCallback(()=>setFocusableItemsCount((prevCount)=>prevCount+1),[]),onFocusableItemRemove:import_react.useCallback(()=>setFocusableItemsCount((prevCount)=>prevCount-1),[]),onItemFocus:import_react.useCallback((tabStopId)=>setCurrentTabStopId(tabStopId),[setCurrentTabStopId]),onItemShiftTab:import_react.useCallback(()=>setIsTabbingBackOut(!0),[]),orientation,scope:__scopeRovingFocusGroup,children:jsx_runtime.jsx(import_primitive.Primitive.div,{"data-orientation":orientation,tabIndex:isTabbingBackOut||focusableItemsCount===0?-1:0,...groupProps,onBlur:import_compose_events.composeEventHandlers(props.onBlur,()=>setIsTabbingBackOut(!1)),onFocus:import_compose_events.composeEventHandlers(props.onFocus,(event)=>{let isKeyboardFocus=!isClickFocusRef.current;if(event.target===event.currentTarget&&isKeyboardFocus&&!isTabbingBackOut){let entryFocusEvent=new CustomEvent(ENTRY_FOCUS,EVENT_OPTIONS);if(event.currentTarget.dispatchEvent(entryFocusEvent),!entryFocusEvent.defaultPrevented){let items=getItems().filter((item)=>item.focusable),activeItem=items.find((item)=>item.active),currentItem=items.find((item)=>item.id===currentTabStopId),candidateNodes=[activeItem,currentItem,...items].filter(Boolean).map((item)=>item.ref.current).filter((node)=>node!==null);focusFirst(candidateNodes,preventScrollOnEntryFocus)}}isClickFocusRef.current=!1}),onMouseDown:import_compose_events.composeEventHandlers(props.onMouseDown,()=>{isClickFocusRef.current=!0}),ref:composedRefs,style:{outline:"none",...props.style}})})}),ITEM_NAME="RovingFocusGroupItem",RovingFocusGroupItem=import_react.forwardRef((props,forwardedRef)=>{let{__scopeRovingFocusGroup,focusable=!0,active=!1,tabStopId,children,...itemProps}=props,autoId=import_use_id.useId(),id=tabStopId||autoId,context=useRovingFocusContext(ITEM_NAME,__scopeRovingFocusGroup),isCurrentTabStop=context.currentTabStopId===id,getItems=useCollection(__scopeRovingFocusGroup),{onFocusableItemAdd,onFocusableItemRemove,currentTabStopId}=context;return import_react.useEffect(()=>{if(focusable)return onFocusableItemAdd(),()=>onFocusableItemRemove()},[focusable,onFocusableItemAdd,onFocusableItemRemove]),jsx_runtime.jsx(Collection.ItemSlot,{active,focusable,id,scope:__scopeRovingFocusGroup,children:jsx_runtime.jsx(import_primitive.Primitive.span,{"data-orientation":context.orientation,tabIndex:isCurrentTabStop?0:-1,...itemProps,onFocus:import_compose_events.composeEventHandlers(props.onFocus,()=>context.onItemFocus(id)),onKeyDown:import_compose_events.composeEventHandlers(props.onKeyDown,(event)=>{if(event.key==="Tab"&&event.shiftKey){context.onItemShiftTab();return}if(event.target!==event.currentTarget)return;let focusIntent=getFocusIntent(event,context.orientation,context.dir);if(focusIntent!==void 0){if(event.metaKey||event.ctrlKey||event.altKey||event.shiftKey)return;event.preventDefault();let candidateNodes=getItems().filter((item)=>item.focusable).map((item)=>item.ref.current).filter((node)=>node!==null);if(focusIntent==="last")candidateNodes.reverse();else if(focusIntent==="prev"||focusIntent==="next"){if(focusIntent==="prev")candidateNodes.reverse();let currentIndex=candidateNodes.indexOf(event.currentTarget);candidateNodes=context.loop?wrapArray(candidateNodes,currentIndex+1):candidateNodes.slice(currentIndex+1)}setTimeout(()=>focusFirst(candidateNodes))}}),onMouseDown:import_compose_events.composeEventHandlers(props.onMouseDown,(event)=>{if(focusable)context.onItemFocus(id);else event.preventDefault()}),ref:forwardedRef,children:typeof children==="function"?children({hasTabStop:currentTabStopId!=null,isCurrentTabStop}):children})})});RovingFocusGroupItem.displayName=ITEM_NAME;var MAP_KEY_TO_FOCUS_INTENT={ArrowDown:"next",ArrowLeft:"prev",ArrowRight:"next",ArrowUp:"prev",End:"last",Home:"first",PageDown:"last",PageUp:"first"};function getDirectionAwareKey(key,dir){if(dir!=="rtl")return key;if(key==="ArrowLeft")return"ArrowRight";if(key==="ArrowRight")return"ArrowLeft";return key}function getFocusIntent(event,orientation,dir){let key=getDirectionAwareKey(event.key,dir);if(orientation==="vertical"&&["ArrowLeft","ArrowRight"].includes(key))return;if(orientation==="horizontal"&&["ArrowUp","ArrowDown"].includes(key))return;return MAP_KEY_TO_FOCUS_INTENT[key]}function focusFirst(candidates,preventScroll=!1){let PREVIOUSLY_FOCUSED_ELEMENT=document.activeElement;for(let candidate of candidates){if(candidate===PREVIOUSLY_FOCUSED_ELEMENT)return;if(candidate.focus({preventScroll}),document.activeElement!==PREVIOUSLY_FOCUSED_ELEMENT)return}}function wrapArray(array,startIndex){return array.map((_,index)=>array[(startIndex+index)%array.length])}var Root=RovingFocusGroup,Item=RovingFocusGroupItem;