@konstructio/ui
Version:
A set of reusable and customizable React components built for konstruct.io
68 lines (67 loc) • 2.33 kB
JavaScript
import { useSelectContext as b } from "../contexts/select.hook.js";
import { useCallback as w, useEffect as c, useRef as m } from "react";
var h = ({ ulRef: f, inputRef: r, disabled: E, internalValue: u, onBlur: g }) => {
const t = m(null), a = m(null), { value: i, setSearchTerm: v, setCanFilter: d, toggleOpen: n } = b();
return c(() => {
const e = new AbortController(), s = (l) => {
l.key === "Escape" && n(!1);
}, o = (l) => {
t.current?.contains(l.target) || n(!1);
};
return document.addEventListener("keydown", s, { signal: e.signal }), document.addEventListener("mousedown", o, { signal: e.signal }), document.addEventListener("visibilitychange", () => {
document.hidden && n(!1);
}, { signal: e.signal }), a.current?.addEventListener("focusin", (l) => {
!E && l.target?.matches(":focus-visible") && n(!0);
}, { signal: e.signal }), () => {
e.abort();
};
}, [n, t]), c(() => {
const e = new AbortController();
return a.current?.addEventListener("keydown", (s) => {
if (s.key === "ArrowDown") {
const o = f.current?.querySelector("li");
o && o.focus();
}
}, { signal: e.signal }), () => {
e.abort();
};
}, [a, f]), c(() => {
const e = new AbortController();
return r?.current?.addEventListener("focusin", () => {
v(u?.value ?? ""), d(!1);
}, { signal: e.signal }), r?.current?.addEventListener("focusout", () => {
d(!0);
}, { signal: e.signal }), a.current?.addEventListener("focus", () => {
d(!1);
}, { signal: e.signal }), t.current?.addEventListener("focusout", (s) => {
t.current?.contains(s.relatedTarget) || n(!1);
}, { signal: e.signal }), () => {
e.abort();
};
}, [i]), c(() => {
r?.current && (r.current.value = i && u?.value || "");
}, [u, i]), c(() => {
const e = new AbortController();
return t.current?.addEventListener("focusout", (s) => {
const o = s.relatedTarget;
(!o || !t.current?.contains(o)) && (r?.current?.value || g?.());
}), () => {
e.abort();
};
}, [
n,
t,
v,
g,
i
]), {
wrapperRef: t,
wrapperInputRef: a,
handleOpen: w(() => {
n(!0), requestAnimationFrame(() => r?.current?.focus());
}, [r, n])
};
};
export {
h as useSelect
};