{"version":3,"file":"useScopeSwitcher.mjs","names":[],"sources":["../../../src/base-ui/FocusScope/useScopeSwitcher.ts"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { hasModifier, hasSize, isItemVisible, isTextInputTarget } from './domUtils';\nimport { getActiveScopeId, getLastFocusedItem, setActiveScope } from './store';\nimport { focusScopeItem } from './useScopeArrowNav';\n\nexport interface UseScopeSwitcherOptions {\n  enabled?: boolean;\n  vimKeys?: boolean;\n}\n\nconst getOrderedScopes = () => {\n  const seen = new Set<string>();\n  const out: HTMLElement[] = [];\n  for (const el of document.querySelectorAll<HTMLElement>('[data-focus-scope]')) {\n    const id = el.dataset.focusScope;\n    if (!id || seen.has(id) || !isItemVisible(el) || !hasSize(el)) continue;\n    seen.add(id);\n    out.push(el);\n  }\n  return out;\n};\n\nconst focusInto = (scope: HTMLElement) => {\n  const id = scope.dataset.focusScope!;\n  setActiveScope(id);\n  const lastId = getLastFocusedItem(id);\n  const last =\n    lastId &&\n    [...scope.querySelectorAll<HTMLElement>('[data-scope-item]')].find(\n      (el) => el.dataset.id === lastId && isItemVisible(el),\n    );\n  const target =\n    last ||\n    [...scope.querySelectorAll<HTMLElement>('[data-scope-item]')].find(isItemVisible) ||\n    scope;\n  focusScopeItem(id, target);\n};\n\nexport const useScopeSwitcher = ({ enabled = true, vimKeys = false }: UseScopeSwitcherOptions = {}) => {\n  useEffect(() => {\n    if (!enabled || typeof window === 'undefined') return;\n\n    const onKeyDown = (event: KeyboardEvent) => {\n      if (event.defaultPrevented || hasModifier(event) || isTextInputTarget(event.target)) return;\n      const direction =\n        event.key === 'ArrowRight' || (vimKeys && event.key === 'l')\n          ? 1\n          : event.key === 'ArrowLeft' || (vimKeys && event.key === 'h')\n            ? -1\n            : 0;\n      if (!direction) return;\n\n      const scopes = getOrderedScopes();\n      if (scopes.length === 0) return;\n      const activeId = getActiveScopeId();\n      const index = scopes.findIndex((el) => el.dataset.focusScope === activeId);\n      const next = index === -1 ? (direction === 1 ? scopes[0] : scopes.at(-1)!) : scopes[index + direction];\n      if (!next) return;\n      event.preventDefault();\n      focusInto(next);\n    };\n\n    window.addEventListener('keydown', onKeyDown);\n    return () => window.removeEventListener('keydown', onKeyDown);\n  }, [enabled, vimKeys]);\n};\n"],"mappings":";;;;;AAWA,MAAM,yBAAyB;CAC7B,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,MAAqB,CAAC;CAC5B,KAAK,MAAM,MAAM,SAAS,iBAA8B,oBAAoB,GAAG;EAC7E,MAAM,KAAK,GAAG,QAAQ;EACtB,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG;EAC/D,KAAK,IAAI,EAAE;EACX,IAAI,KAAK,EAAE;CACb;CACA,OAAO;AACT;AAEA,MAAM,aAAa,UAAuB;CACxC,MAAM,KAAK,MAAM,QAAQ;CACzB,eAAe,EAAE;CACjB,MAAM,SAAS,mBAAmB,EAAE;CAMpC,MAAM,SAJJ,UACA,CAAC,GAAG,MAAM,iBAA8B,mBAAmB,CAAC,CAAC,CAAC,MAC3D,OAAO,GAAG,QAAQ,OAAO,UAAU,cAAc,EAAE,CACtD,KAGA,CAAC,GAAG,MAAM,iBAA8B,mBAAmB,CAAC,CAAC,CAAC,KAAK,aAAa,KAChF;CACF,eAAe,IAAI,MAAM;AAC3B;AAEA,MAAa,oBAAoB,EAAE,UAAU,MAAM,UAAU,UAAmC,CAAC,MAAM;CACrG,gBAAgB;EACd,IAAI,CAAC,WAAW,OAAO,WAAW,aAAa;EAE/C,MAAM,aAAa,UAAyB;GAC1C,IAAI,MAAM,oBAAoB,YAAY,KAAK,KAAK,kBAAkB,MAAM,MAAM,GAAG;GACrF,MAAM,YACJ,MAAM,QAAQ,gBAAiB,WAAW,MAAM,QAAQ,MACpD,IACA,MAAM,QAAQ,eAAgB,WAAW,MAAM,QAAQ,MACrD,KACA;GACR,IAAI,CAAC,WAAW;GAEhB,MAAM,SAAS,iBAAiB;GAChC,IAAI,OAAO,WAAW,GAAG;GACzB,MAAM,WAAW,iBAAiB;GAClC,MAAM,QAAQ,OAAO,WAAW,OAAO,GAAG,QAAQ,eAAe,QAAQ;GACzE,MAAM,OAAO,UAAU,KAAM,cAAc,IAAI,OAAO,KAAK,OAAO,GAAG,EAAE,IAAM,OAAO,QAAQ;GAC5F,IAAI,CAAC,MAAM;GACX,MAAM,eAAe;GACrB,UAAU,IAAI;EAChB;EAEA,OAAO,iBAAiB,WAAW,SAAS;EAC5C,aAAa,OAAO,oBAAoB,WAAW,SAAS;CAC9D,GAAG,CAAC,SAAS,OAAO,CAAC;AACvB"}