{"version":3,"file":"roving-focus.mjs","sources":["../src/roving-focus/utils.ts","../src/roving-focus/RovingFocusGroupRoot.ts","../src/roving-focus/RovingFocusGroupItem.ts"],"sourcesContent":["import type { Direction } from '../direction/index.ts'\n\nexport type Orientation = 'horizontal' | 'vertical'\n\nexport const ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus'\nexport const EVENT_OPTIONS: { bubbles: boolean, cancelable: boolean } = { bubbles: false, cancelable: true }\n\nexport const MAP_KEY_TO_FOCUS_INTENT: Record<string, FocusIntent> = {\n  ArrowLeft: 'prev',\n  ArrowUp: 'prev',\n  ArrowRight: 'next',\n  ArrowDown: 'next',\n  PageUp: 'first',\n  Home: 'first',\n  PageDown: 'last',\n  End: 'last',\n}\n\nexport function getDirectionAwareKey(key: string, dir?: Direction): string {\n  if (dir !== 'rtl')\n    return key\n\n  return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key\n}\n\ntype FocusIntent = 'first' | 'last' | 'prev' | 'next'\n\nexport function getFocusIntent(event: KeyboardEvent, orientation?: Orientation, dir?: Direction): FocusIntent | undefined {\n  const key = getDirectionAwareKey(event.key, dir)\n  if (orientation === 'vertical' && ['ArrowLeft', 'ArrowRight'].includes(key))\n    return undefined\n\n  if (orientation === 'horizontal' && ['ArrowUp', 'ArrowDown'].includes(key))\n    return undefined\n\n  return MAP_KEY_TO_FOCUS_INTENT[key]\n}\n","import { type AriaAttributes, computed, type MaybeRefOrGetter, type Ref, shallowRef } from 'vue'\nimport { createCollection } from '../collection/index.ts'\nimport { type Direction, useDirection } from '../direction/index.ts'\nimport { createContext, type MutableRefObject, useRef } from '../hooks/index.ts'\nimport { useControllableStateV2 } from '../hooks/index.ts'\nimport { type EmitsToHookProps, focusFirst, mergePrimitiveAttrs, type PrimitiveDefaultProps, type RadixPrimitiveReturns } from '../shared/index.ts'\nimport { ENTRY_FOCUS, EVENT_OPTIONS } from './utils.ts'\n\ntype Orientation = AriaAttributes['aria-orientation']\n\nexport interface RovingFocusGroupRootProps {\n  /**\n   * The orientation of the group.\n   * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n   */\n  orientation?: Orientation\n  /**\n   * The direction of navigation between items.\n   */\n  dir?: Direction\n  /**\n   * Whether keyboard navigation should loop around\n   * @defaultValue false\n   */\n  loop?: boolean\n\n  currentTabStopId?: string | undefined\n  defaultCurrentTabStopId?: string\n  preventScrollOnEntryFocus?: boolean\n}\n\nexport const DEFAULT_ROVING_FOCUS_GROUP_ROOT_PROPS = {\n  loop: undefined,\n  preventScrollOnEntryFocus: undefined,\n} satisfies PrimitiveDefaultProps<RovingFocusGroupRootProps>\n\nexport type RovingFocusGroupRootEmits = {\n  'update:currentTabStopId': [tabStopId: string | undefined]\n  'entryFocus': [event: Event]\n}\n\nexport interface ItemData {\n  $rfg: {\n    id: string\n    focusable: boolean\n    active: boolean\n  }\n}\n\nexport const [Collection, useCollection] = createCollection<HTMLElement, ItemData>('RovingFocusGroup')\n\nexport interface RovingContext {\n  /**\n   * The orientation of the group.\n   * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n   */\n  orientation?: Orientation\n  /**\n   * The direction of navigation between items.\n   */\n  dir: Ref<Direction>\n  /**\n   * Whether keyboard navigation should loop around\n   * @defaultValue false\n   */\n  loop: boolean\n  currentTabStopId: Ref<string | null>\n  onItemFocus: (tabStopId: string) => void\n  onItemShiftTab: () => void\n  onFocusableItemAdd: () => void\n  onFocusableItemRemove: () => void\n}\n\nexport const [provideRovingFocusContext, useRovingFocusContext] = createContext<RovingContext>('RovingFocusGroup')\n\nexport interface UseRovingFocusGroupRootProps extends EmitsToHookProps<RovingFocusGroupRootEmits> {\n  elRef?: MutableRefObject<HTMLElement | undefined>\n  currentTabStopId?: () => string | undefined\n  defaultCurrentTabStopId?: string\n  orientation?: Orientation\n  loop?: boolean\n  dir?: MaybeRefOrGetter<Direction | undefined>\n  preventScrollOnEntryFocus?: boolean\n}\n\nexport function useRovingFocusGroupRoot(props: UseRovingFocusGroupRootProps): RadixPrimitiveReturns {\n  const {\n    loop = false,\n  } = props\n  const elRef = props.elRef || useRef<HTMLElement>()\n  const setElRef = props.elRef ? undefined : (value: HTMLElement | undefined) => elRef.value = value\n\n  const dir = useDirection(props.dir)\n\n  const currentTabStopId = useControllableStateV2(props.currentTabStopId, props.onUpdateCurrentTabStopId, props.defaultCurrentTabStopId)\n\n  const collectionContext = Collection.provideCollectionContext(elRef)\n  const getItems = useCollection(collectionContext)\n  const isTabbingBackOut = shallowRef(false)\n  let isClickFocus = false\n  const focusableItemsCount = shallowRef(0)\n\n  function onMousedown(event: MouseEvent) {\n    if (event.defaultPrevented)\n      return\n    isClickFocus = true\n  }\n\n  function onFocusin(event: FocusEvent) {\n    if (event.defaultPrevented)\n      return\n\n    // We normally wouldn't need this check, because we already check\n    // that the focus is on the current target and not bubbling to it.\n    // We do this because Safari doesn't focus buttons when clicked, and\n    // instead, the wrapper will get focused and not through a bubbling event.\n    const isKeyboardFocus = !isClickFocus\n\n    if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut.value) {\n      const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS)\n      // event.currentTarget!.dispatchEvent(entryFocusEvent)\n      props.onEntryFocus?.(entryFocusEvent)\n\n      if (!entryFocusEvent.defaultPrevented) {\n        const items = getItems().filter(item => item.$$rcid.$rfg.focusable)\n        const activeItem = items.find(item => item.$$rcid.$rfg.active)\n        const _currentTabStopId = currentTabStopId.value\n        const currentItem = items.find(item => item.$$rcid.$rfg.id === _currentTabStopId)\n        const candidateItems = [activeItem, currentItem, ...items].filter(Boolean) as typeof items\n        focusFirst(candidateItems, props.preventScrollOnEntryFocus ?? false)\n      }\n    }\n\n    isClickFocus = false\n  }\n\n  function onFocusout(event: FocusEvent) {\n    if (event.defaultPrevented)\n      return\n    isTabbingBackOut.value = false\n  }\n\n  provideRovingFocusContext({\n    orientation: props.orientation,\n    dir,\n    loop,\n    currentTabStopId,\n    onItemFocus(tabStopId) {\n      currentTabStopId.value = tabStopId\n    },\n    onItemShiftTab() {\n      isTabbingBackOut.value = true\n    },\n    onFocusableItemAdd() {\n      focusableItemsCount.value += 1\n    },\n    onFocusableItemRemove() {\n      focusableItemsCount.value -= 1\n    },\n  })\n\n  const tabindex = computed(() => isTabbingBackOut.value || focusableItemsCount.value === 0 ? -1 : 0)\n\n  const style = { outline: 'none' }\n\n  return {\n    attrs(extraAttrs) {\n      const attrs = {\n        'elRef': setElRef,\n        'dir': dir.value,\n        'tabindex': tabindex.value,\n        'data-orientation': props.orientation,\n        'style': style,\n        onMousedown,\n        onFocusin,\n        onFocusout,\n      }\n\n      if (extraAttrs && extraAttrs.length > 0) {\n        mergePrimitiveAttrs(attrs, extraAttrs)\n      }\n\n      return attrs\n    },\n  }\n}\n","import type { PrimitiveProps } from '../primitive/index.ts'\nimport { computed, onWatcherCleanup, watch, watchEffect } from 'vue'\nimport { DATA_COLLECTION_ITEM } from '../collection/index.ts'\nimport { useId } from '../hooks/index.ts'\nimport { focusFirst, mergePrimitiveAttrs, type PrimitiveDefaultProps, type RadixPrimitiveReturns, wrapArray } from '../shared/index.ts'\nimport { Collection, type ItemData, useCollection, useRovingFocusContext } from './RovingFocusGroupRoot.ts'\nimport { getFocusIntent } from './utils.ts'\n\nexport interface RovingFocusGroupItemProps {\n  as?: PrimitiveProps['as']\n  tabStopId?: string\n  focusable?: boolean\n  active?: boolean\n}\n\nexport const DEFAULT_ROVING_FOCUS_GROUP_ITEM_PROPS = {\n  as: 'span',\n  focusable: true,\n  active: false,\n} satisfies PrimitiveDefaultProps<RovingFocusGroupItemProps, 'focusable' | 'active'>\n\nexport interface UseRovingFocusGroupItemProps {\n  tabStopId?: () => string | undefined\n  focusable?: () => boolean\n  active?: () => boolean\n}\n\nexport function useRovingFocusGroupItem(props: UseRovingFocusGroupItemProps = {}): RadixPrimitiveReturns {\n  const {\n    focusable = () => true,\n    active = () => false,\n  } = props\n\n  const _id = useId()\n\n  const id = computed(() => props.tabStopId?.() ?? _id)\n  const context = useRovingFocusContext('RovingFocusGroupItem')\n  const isCurrentTabStop = computed(() => context.currentTabStopId.value === id.value)\n\n  const getItems = useCollection()\n\n  watch(focusable, (value) => {\n    if (value) {\n      context.onFocusableItemAdd()\n      onWatcherCleanup(context.onFocusableItemRemove)\n    }\n  }, { immediate: true })\n\n  const itemData: ItemData['$rfg'] = { id: id.value, focusable: focusable(), active: active() }\n\n  watchEffect(() => {\n    itemData.active = active()\n    // TODO: remove focusable\n    itemData.focusable = focusable()\n    itemData.id = id.value\n  })\n\n  function onMousedown(event: MouseEvent) {\n    if (event.defaultPrevented)\n      return\n    // We prevent focusing non-focusable items on `mousedown`.\n    // Even though the item has tabIndex={-1}, that only means take it out of the tab order.\n    if (!focusable())\n      event.preventDefault()\n    // Safari doesn't focus a button when clicked so we run our logic on mousedown also\n    else context.onItemFocus(id.value)\n  }\n\n  function onFocus(event: FocusEvent) {\n    if (event.defaultPrevented)\n      return\n    context.onItemFocus(id.value)\n  }\n\n  // TODO: wip onKeydown on RovingFocusGroupRoot\n\n  function onKeydown(event: KeyboardEvent) {\n    if (event.defaultPrevented)\n      return\n    if (event.key === 'Tab' && event.shiftKey) {\n      context.onItemShiftTab()\n      return\n    }\n\n    if (event.target !== event.currentTarget)\n      return\n\n    if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey)\n      return\n\n    const focusIntent = getFocusIntent(event, context.orientation, context.dir.value)\n\n    if (!focusIntent)\n      return\n\n    event.preventDefault()\n    let candidateNodes = getItems().filter(item => item.$$rcid.$rfg.focusable)\n\n    if (focusIntent === 'last') {\n      candidateNodes.reverse()\n    }\n    else if (focusIntent === 'prev' || focusIntent === 'next') {\n      if (focusIntent === 'prev') {\n        candidateNodes.reverse()\n      }\n      const currentIndex = (candidateNodes as HTMLElement[]).indexOf(event.currentTarget as HTMLElement)\n      candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1)\n    }\n\n    // TODO: wip\n    /**\n     * Imperative focus during keydown is risky so we prevent React's batching updates\n     * to avoid potential bugs. See: https://github.com/facebook/react/issues/20332\n     */\n    setTimeout(() => {\n      focusFirst(candidateNodes)\n    })\n  }\n\n  function setElRef(templateEl: HTMLElement | undefined) {\n    Collection.useCollectionItem(templateEl, itemData, '$rfg')\n  }\n\n  return {\n    attrs(extraAttrs) {\n      const attrs = {\n        'elRef': setElRef,\n        [DATA_COLLECTION_ITEM]: true,\n        'tabindex': isCurrentTabStop.value ? 0 : -1,\n        'data-orientation': context.orientation,\n        onFocus,\n        onMousedown,\n        onKeydown,\n      }\n\n      if (extraAttrs && extraAttrs.length > 0) {\n        mergePrimitiveAttrs(attrs, extraAttrs)\n      }\n\n      return attrs\n    },\n  }\n}\n"],"names":[],"mappings":"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"}