@progress/kendo-react-data-tools
Version:
Includes React Pager & React Filter component, an intuitive interface to create complex filter descriptions. KendoReact Data Tools package
277 lines (276 loc) • 11.2 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2026 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
"use client";
import { guid as U, getActiveElement as V, enableNavigatableContainer as L, Keys as c, disableNavigatableContainer as W, keepFocusInContainer as _, TABBABLE_ELEMENTS as q } from "@progress/kendo-react-common";
import { focusFirstDataElement as w, getFirstDataCell as P, tableKeyboardNavigationTools as t, getCurrentIdIndexes as $, getFirstRowDataCell as j, getLastRowDataCell as z, getLastDataCell as J, getHeaderElement as Q, getBodyElement as X, getNoRecordsElement as Y, getNavigatableId as Z, focusFirstEditor as ee, findNextIdByRowIndex as M, findNextIdByCellIndex as te } from "./utils.mjs";
import { NavigatableMode as D } from "./NavigatableSettings.mjs";
const H = (e) => {
const { navigatable: l, contextStateRef: i, navigationStateRef: a, idPrefix: r } = e;
l && (i.current = {
activeId: "",
level: 0
}, a.current = {
activeElementIsFocused: !1,
prevNavigationIndexes: void 0,
idPrefix: r || U(),
navigationMatrix: [],
lastHeaderIndex: -1
});
}, O = (e) => {
const { scope: l, contextStateRef: i, navigationStateRef: a } = e;
if (i.current && a.current && l) {
A(e);
const r = P(a.current.navigationMatrix);
if (r) {
const f = t.getActiveNavDataElement(l, r);
f && (i.current.activeId = r, f.setAttribute("tabIndex", "0"));
}
}
}, ae = (e) => {
const { contextStateRef: l, navigationStateRef: i, document: a } = e;
if (l.current && i.current && a) {
const r = V(a), f = t.getNavigatableId(r);
f && f === l.current.activeId && (i.current.activeElementIsFocused = !0);
}
}, K = (e, l, i) => {
if (l) {
e();
return;
}
const a = document.activeElement;
a && a !== document.body && i && !i.contains(a) || e();
}, ne = (e) => {
const {
scope: l,
contextStateRef: i,
navigationStateRef: a,
focusFirst: r,
newEditableRow: f,
singleEditRow: s,
lastActiveElement: m,
navigatable: n,
userInitiatedEdit: u
} = e;
if (r && (H(e), O(e), w(e)), (!n || n && n.mode === D.inline) && (f && !s || f && s && !m) ? K(() => ee(f), u, l) : n && n.mode === D.inline && f && s && m && K(() => m.focus(), u, l), A(e), i.current && a.current && l) {
if (!t.getActiveNavDataElement(l, i.current.activeId)) {
const v = l.className.indexOf("k-treelist") === -1 ? P(a.current.navigationMatrix) : a.current.navigationMatrix[0][0], C = t.getActiveNavDataElement(l, v);
v && C && (i.current.activeId = v, C.setAttribute("tabIndex", "0"), a.current.activeElementIsFocused && C.focus());
}
a.current.activeElementIsFocused = !1;
}
}, oe = (e, l) => {
const { contextStateRef: i } = l;
if (e.isDefaultPrevented() || !i.current)
return;
const a = e.target, r = t.getNavigatableId(a);
if (r && r !== i.current.activeId) {
const f = t.getClosestScope(a);
if (!f)
return;
const s = t.getActiveNavDataElement(f, i.current.activeId);
s && !e.target.classList.contains("k-table-td") && !e.target.classList.contains("k-detail-cell") && s.setAttribute("tabIndex", "-1"), a.setAttribute("tabIndex", "0"), i.current.activeId = r;
} else if (a.closest(".k-filtercell") && l.navigatable) {
const f = a.closest(".k-table-td");
L(f);
}
}, ie = async (e, l) => {
var R, h, F, B, S;
const { contextStateRef: i, navigationStateRef: a, onNavigationAction: r, columns: f } = l;
if (e.isDefaultPrevented() || !i.current || !a.current)
return;
let s;
if (e.keyCode === c.esc && !l.navigatable.mode) {
s = t.getClosestNavigatableElement(e.target), t.focusElement({ elementForFocus: s, event: e, contextStateRef: i }), e.target.closest(".k-filtercell") && s && l.navigatable && W(s);
return;
}
const m = e.target, n = m.className.indexOf("k-checkbox") === -1 ? m : t.getClosestNavigatableElement(m), u = t.getNavigatableId(n) || ((R = t.getParentCell(n)) == null ? void 0 : R.getAttribute("data-keyboardnavid")), y = u == null ? void 0 : u.endsWith("column"), v = u == null ? void 0 : u.endsWith("column_filter"), C = t.getNavigatableLevel(n), I = t.getClosestScope(n), k = a.current.navigationMatrix, E = e.metaKey || e.ctrlKey, d = $(a, k, u), p = n.closest(".k-table-td"), x = (h = n.closest(".k-table-td")) == null ? void 0 : h.classList.contains("k-grid-edit-cell");
if (l.navigatable && l.navigatable.mode === D.inline) {
if (e.keyCode === c.enter) {
const o = n.classList.contains("k-grid-remove-command"), g = n.classList.contains("k-grid-cancel-command"), b = t.getRowAriaRowIndex(n);
if (o) {
setTimeout(() => {
const N = t.getRemoveButtonByAriaRowIndex(b.current) || t.getRemoveButtonByAriaRowIndex(b.prev);
N && N.focus();
});
return;
} else if (g && n.parentElement) {
const N = (F = t.getClosestNavigatableElement(n)) == null ? void 0 : F.getAttribute("data-keyboardnavid");
setTimeout(() => {
N && t.getTableCellByKeyboardNavId(N).focus();
});
return;
}
}
if (e.keyCode === c.esc) {
const o = t.getClosestCancelButton(n);
o && o.click();
const g = await t.getClosestEditButton(n);
g && g.focus();
return;
}
} else if (l.navigatable && l.navigatable.mode === D.incell) {
if (e.keyCode === c.esc) {
n.focus(), n.blur();
const o = ((B = m == null ? void 0 : m.parentElement) == null ? void 0 : B.closest(".k-grid-edit-row")) || null, g = t.getClosestCellNavId(n), b = await t.waitForElementToBeVisible(
`[data-keyboardnavid='${g}']:not(.k-grid-edit-cell)`,
o
);
b && b.focus();
} else if (e.keyCode === c.enter) {
let o;
if (d) {
const [g, b] = d;
o = M(g, b, u, k, !1);
}
if (!x)
(S = t.getParentCell(n)) == null || S.click();
else if (x && o) {
const g = o && o[0] && t.getTableCellByKeyboardNavId(o[0]);
g && g.click();
}
} else if (e.keyCode === c.left || e.keyCode === c.right || e.keyCode === c.up || e.keyCode === c.down) {
if (x)
return;
} else if (e.key === "Tab" && x) {
if (e.shiftKey) {
const o = d && f && t.getPrevEditableCell(d, f, u, k);
if (o && o.prevCell && o.prevCell.click(), o && o.elementToFocus !== "gridcell") {
n.blur();
const g = t.getClosestCellNavId(n);
setTimeout(() => {
g && t.getTableCellByKeyboardNavId(g).focus();
});
}
e.preventDefault();
} else {
const o = d && f && t.getNextEditableCell(d, f, u, k);
if (o && o.nextCell && o.elementToFocus === "gridcell" && o.nextCell.click(), o && o.elementToFocus !== "gridcell") {
n.blur();
const g = t.getClosestCellNavId(n);
g && t.getTableCellByKeyboardNavId(g).focus();
return;
}
e.preventDefault();
}
e.preventDefault();
}
}
if (n.closest(".k-filtercell") && p && l.navigatable) {
_(e, p, q);
return;
}
if (C !== void 0 && I) {
if (e.keyCode === c.enter) {
const o = t.getNavigatableElement(n, { level: C + 1 });
if (o) {
t.focusElement({
elementForFocus: o,
event: e,
contextStateRef: i,
prevElement: n
});
return;
}
n.querySelector(".k-filtercell") && l.navigatable && L(n), s = t.getFocusableElements(n)[0], t.focusElement({ elementForFocus: s, event: e, contextStateRef: i, prevElement: n });
}
if (e.keyCode === c.home && d)
if (E)
w(
{
scope: I,
navigationStateRef: a,
contextStateRef: i
},
e
);
else {
const o = j(
a.current.navigationMatrix,
d[0]
);
s = t.getActiveNavDataElement(I, o), t.focusElement({ elementForFocus: s, event: e, contextStateRef: i });
}
if (e.keyCode === c.end && d)
if (E) {
const o = J(a.current.navigationMatrix);
s = t.getActiveNavDataElement(I, o), t.focusElement({ elementForFocus: s, event: e, contextStateRef: i });
} else {
const o = z(
a.current.navigationMatrix,
d[0]
);
s = t.getActiveNavDataElement(I, o), t.focusElement({ elementForFocus: s, event: e, contextStateRef: i });
}
if (e.keyCode === c.up || e.keyCode === c.down || e.keyCode === c.left || e.keyCode === c.right) {
const o = e.keyCode === c.up || e.keyCode === c.left, g = e.keyCode === c.up || e.keyCode === c.down;
if (d) {
const [b, N] = d, [T, G] = g ? M(b, N, u, k, o) : te(b, N, u, k, o);
T && (s = t.getActiveNavDataElement(I, T), t.focusElement({ elementForFocus: s, event: e, contextStateRef: i, prevElement: n }), a.current.prevNavigationIndexes = G);
}
}
if (E && e.keyCode === c.left && y) {
r && r({ focusElement: n, event: e, action: "reorderToLeft" }), e.preventDefault();
return;
}
if (E && e.keyCode === c.right && y) {
r && r({ focusElement: n, event: e, action: "reorderToRight" }), e.preventDefault();
return;
}
if (e.keyCode === c.pageUp) {
r && r({ focusElement: s, event: e, action: "moveToNextPage" }), e.preventDefault();
return;
}
if (e.keyCode === c.pageDown) {
r && r({ focusElement: s, event: e, action: "moveToPrevPage" }), e.preventDefault();
return;
}
if (!y && !v && !x && (e.keyCode === c.space || e.keyCode === c.enter || e.shiftKey && (e.keyCode === c.up || e.keyCode === c.down || e.keyCode === c.left || e.keyCode === c.right))) {
r && r({ focusElement: s, event: e, action: "select" });
return;
}
r && r({ focusElement: s, event: e });
}
}, A = (e) => {
const { navigationStateRef: l, scope: i } = e;
if (!l.current || !i)
return;
const a = [], r = Q(i), f = X(i), s = Y(i) || { children: [] };
if (!r || !f)
return;
const m = Array.from(r.children), n = Array.from(f.children);
[...m, ...n, s].forEach((u, y) => {
Array.from(u.children).forEach((v) => {
const C = Z(v);
if (!C)
return;
const I = v.rowSpan || 1, k = v.colSpan || 1;
let E;
for (let d = y, p = y + I; d < p; d++) {
if (a[d] || (a[d] = []), E === void 0) {
const x = a[d].findIndex((R) => !R);
E = x > -1 ? x : a[d].length;
}
a[d][E] = C || "";
}
for (let d = E + 1, p = E + k; d < p; d++)
a[y][d] = C || "";
});
}), l.current.navigationMatrix = a.filter((u) => !!u), l.current.lastHeaderIndex = m.length - 1;
}, se = {
onConstructor: H,
onComponentDidMount: O,
onGetSnapshotBeforeUpdate: ae,
onComponentDidUpdate: ne,
onFocus: oe,
onKeyDown: ie,
generateMatrix: A,
focusFirstDataElement: w
};
export {
se as tableKeyboardNavigation
};