UNPKG

@payfit/unity-components

Version:

182 lines (181 loc) 5.23 kB
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 };