UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

47 lines (46 loc) • 2.08 kB
import { getActiveScopeId, getLastFocusedItem, setActiveScope } from "./store.mjs"; import { hasModifier, hasSize, isItemVisible, isTextInputTarget } from "./domUtils.mjs"; import { focusScopeItem } from "./useScopeArrowNav.mjs"; import { useEffect } from "react"; //#region src/base-ui/FocusScope/useScopeSwitcher.ts const getOrderedScopes = () => { const seen = /* @__PURE__ */ new Set(); const out = []; for (const el of document.querySelectorAll("[data-focus-scope]")) { const id = el.dataset.focusScope; if (!id || seen.has(id) || !isItemVisible(el) || !hasSize(el)) continue; seen.add(id); out.push(el); } return out; }; const focusInto = (scope) => { const id = scope.dataset.focusScope; setActiveScope(id); const lastId = getLastFocusedItem(id); const target = lastId && [...scope.querySelectorAll("[data-scope-item]")].find((el) => el.dataset.id === lastId && isItemVisible(el)) || [...scope.querySelectorAll("[data-scope-item]")].find(isItemVisible) || scope; focusScopeItem(id, target); }; const useScopeSwitcher = ({ enabled = true, vimKeys = false } = {}) => { useEffect(() => { if (!enabled || typeof window === "undefined") return; const onKeyDown = (event) => { if (event.defaultPrevented || hasModifier(event) || isTextInputTarget(event.target)) return; const direction = event.key === "ArrowRight" || vimKeys && event.key === "l" ? 1 : event.key === "ArrowLeft" || vimKeys && event.key === "h" ? -1 : 0; if (!direction) return; const scopes = getOrderedScopes(); if (scopes.length === 0) return; const activeId = getActiveScopeId(); const index = scopes.findIndex((el) => el.dataset.focusScope === activeId); const next = index === -1 ? direction === 1 ? scopes[0] : scopes.at(-1) : scopes[index + direction]; if (!next) return; event.preventDefault(); focusInto(next); }; window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); }, [enabled, vimKeys]); }; //#endregion export { useScopeSwitcher }; //# sourceMappingURL=useScopeSwitcher.mjs.map