@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
47 lines (46 loc) • 2.08 kB
JavaScript
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