@konstructio/ui
Version:
A set of reusable and customizable React components built for konstruct.io
71 lines (70 loc) • 1.79 kB
JavaScript
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
};