UNPKG

@konstructio/ui

Version:

A set of reusable and customizable React components built for konstruct.io

71 lines (70 loc) 1.79 kB
import { useRef as b, useEffect as l } from "react"; const w = ({ ulRef: t, inputRef: o, wrapperRef: u, options: a }) => { const r = b(0); l(() => { const e = t.current?.querySelectorAll("li") ?? [], c = new AbortController(), n = () => { r.current < e.length - 1 ? (r.current = r.current + 1, e[r.current].focus()) : (r.current = 0, e[0].focus()); }, i = () => { r.current > 0 ? (r.current = r.current - 1, e[r.current].focus()) : (r.current = 0, o.current?.focus()); }; return t.current?.addEventListener( "keydown", (s) => { switch (s.preventDefault(), s.key) { case "ArrowDown": { n(); break; } case "Tab": { s.shiftKey ? i() : n(); break; } case "ArrowUp": { r.current === 0 ? o.current?.focus() : i(); break; } case "Enter": { e[r.current].querySelector("button")?.click(); break; } } }, { signal: c.signal } ), () => { c.abort(); }; }, [o, t, a, r]), l(() => { const e = new AbortController(); return o.current?.addEventListener( "keydown", (c) => { if (c.key === "ArrowDown") { const n = t.current?.querySelector("li"); n && n.focus(); } }, { signal: e.signal } ), () => { e.abort(); }; }, [o, t, a]), l(() => { const e = new AbortController(); return u.current?.addEventListener( "mouseenter", () => { (t.current?.querySelectorAll("li") ?? []).forEach((n) => n.blur()); }, { signal: e.signal } ), () => { e.abort(); }; }, [t, u]); }; export { w as useNavigationUlList };