@payfit/unity-components
Version:
182 lines (181 loc) • 5.23 kB
JavaScript
import { useCallback as e, useRef as t, useState as n } from "react";
//#region src/components/table/hooks/useTableKeyboardNavigation.ts
var r = "input, button, select, textarea, a[href], [tabindex]:not([tabindex=\"-1\"])";
function i() {
let [i, a] = n({
rowIndex: 0,
colIndex: 0
}), o = t(null), s = e((e, t, n) => {
let i = e.querySelectorAll(r);
if (i.length > 0) {
let e = i[0];
return a({
rowIndex: t,
colIndex: n
}), requestAnimationFrame(() => {
e.focus({ preventScroll: !1 });
}), !0;
}
return !1;
}, [a]), c = e((e, t, n) => {
if (!o.current) return null;
let r = Array.from(o.current.querySelectorAll("tr"));
if (e < 0 || e >= r.length) return null;
let i = r[e];
if (!i) return null;
let a = Array.from(i.querySelectorAll("td, th"));
if (n === "right") {
for (let n = t + 1; n < a.length; n++) if (a[n].dataset.focusable !== "false") return {
rowIndex: e,
colIndex: n
};
} else for (let n = t - 1; n >= 0; n--) if (a[n].dataset.focusable !== "false") return {
rowIndex: e,
colIndex: n
};
return null;
}, []), l = e((e, t, n) => {
if (!o.current) return;
let r = Array.from(o.current.querySelectorAll("tr"));
if (e < 0 || e >= r.length) return;
let i = r[e];
if (!i) return;
let u = Array.from(i.querySelectorAll("td, th"));
if (t < 0 || t >= u.length) return;
let d = u[t];
if (d.dataset.focusable === "false") {
if (s(d, e, t)) return;
if (n) {
let r = c(e, t, n);
if (r) {
l(r.rowIndex, r.colIndex);
return;
}
}
return;
}
a({
rowIndex: e,
colIndex: t
}), requestAnimationFrame(() => {
document.activeElement !== d && d.focus({ preventScroll: !1 });
});
}, [
a,
s,
c
]), u = e((e) => {
if (!o.current) return;
let t = Array.from(o.current.querySelectorAll("tr"));
e < 0 || e >= t.length || t[e] && l(e, 0);
}, [l]), d = e((e) => {
e.target === e.currentTarget && (e.preventDefault(), requestAnimationFrame(() => {
l(0, 0);
}));
}, [l]), f = e((e) => {
let t = e.target;
if (t !== e.currentTarget) return;
let n = t.closest("tr");
if (!n || !o.current) return;
let r = Array.from(o.current.querySelectorAll("tr")).indexOf(n), i = Array.from(n.querySelectorAll("td, th")).indexOf(t);
r >= 0 && i >= 0 && (a({
rowIndex: r,
colIndex: i
}), requestAnimationFrame(() => {
o.current && (o.current.querySelectorAll("td, th").forEach((e) => {
e.setAttribute("tabindex", "-1");
}), t.setAttribute("tabindex", "0"));
}));
}, [a]), p = e((e, t) => i.rowIndex === e && i.colIndex === t, [i]), m = e((e) => {
if (e.key !== "Tab" && e.target === e.currentTarget && o.current) switch (e.key) {
case "ArrowDown":
case "ArrowRight":
e.preventDefault(), l(0, 0);
break;
case "Home":
e.preventDefault(), l(0, 0);
break;
case "End":
e.preventDefault();
let t = Array.from(o.current.querySelectorAll("tr")), n = t.length - 1;
if (n >= 0) {
let e = t[n];
if (!e) break;
l(n, Array.from(e.querySelectorAll("td, th")).length - 1);
}
break;
}
}, [l]);
return {
focusedCell: i,
setFocusedCell: a,
isCellFocused: p,
handleCellKeyDown: e((e) => {
if (e.key === "RawTab" || !o.current) return;
let t = e.currentTarget, n = e.target;
if (n !== t) {
let e = n.closest("td, th");
e && (t = e);
}
let r = t.closest("tr");
if (!r) return;
let i = Array.from(o.current.querySelectorAll("tr")), a = i.indexOf(r), s = Array.from(r.querySelectorAll("td, th")), c = s.indexOf(t);
switch (e.key) {
case "ArrowRight":
e.preventDefault(), c < s.length - 1 ? l(a, c + 1, "right") : l(a, 0, "right");
break;
case "ArrowLeft":
e.preventDefault(), c > 0 ? l(a, c - 1, "left") : l(a, s.length - 1, "left");
break;
case "ArrowDown":
if (e.preventDefault(), a < i.length - 1) {
let e = i[a + 1];
if (!e) break;
let t = Array.from(e.querySelectorAll("td, th")), n = Math.min(c, t.length - 1);
l(a + 1, n);
}
break;
case "ArrowUp":
if (e.preventDefault(), a > 0) {
let e = i[a - 1];
if (!e) break;
let t = Array.from(e.querySelectorAll("td, th")), n = Math.min(c, t.length - 1);
l(a - 1, n);
}
break;
case "Home":
e.preventDefault(), e.ctrlKey ? l(0, 0) : l(a, 0);
break;
case "End":
if (e.preventDefault(), e.ctrlKey) {
let e = i.length - 1, t = i[e];
if (!t) break;
l(e, Array.from(t.querySelectorAll("td, th")).length - 1);
} else l(a, s.length - 1);
break;
case "PageUp":
e.preventDefault();
let t = Math.max(0, a - 5), n = i[t];
if (!n) break;
let r = Array.from(n.querySelectorAll("td, th"));
l(t, Math.min(c, r.length - 1));
break;
case "PageDown":
e.preventDefault();
let o = Math.min(i.length - 1, a + 5), u = i[o];
if (!u) break;
let d = Array.from(u.querySelectorAll("td, th"));
l(o, Math.min(c, d.length - 1));
break;
}
}, [l]),
handleTableKeyDown: m,
handleTableFocus: d,
handleCellFocus: f,
tableRef: o,
focusCell: l,
focusRow: u
};
}
//#endregion
export { i as useTableKeyboardNavigation };