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