@progress/kendo-react-pivotgrid
Version:
React PivotGrid (also called Pivot Table) can be data-bound to an OLAP service and customized extensively. KendoReact PivotGrid package
286 lines (285 loc) • 10.7 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
*-------------------------------------------------------------------------------------------
*/
import * as t from "react";
import { validatePackage as ke, useCustomComponent as y, useIsomorphicLayoutEffect as Se, setScrollbarWidth as X, classNames as xe, WatermarkOverlay as Ae } from "@progress/kendo-react-common";
import { packageMetadata as Pe } from "./package-metadata.mjs";
import { useLocalization as Ne } from "@progress/kendo-react-intl";
import { emptyCellAriaLabel as j, messages as Te } from "./messages/index.mjs";
import { PivotGridRow as De } from "./components/Row.mjs";
import { PivotGridCell as ze } from "./components/Cell.mjs";
import { useHeaders as $ } from "./hooks/useHeaders.mjs";
import { PivotGridHeaderCell as Le } from "./components/HeaderCell.mjs";
import { useHorizontalScrollSync as Oe } from "./hooks/useHorizontalScrollSync.mjs";
import { useVerticalScrollSync as Ge } from "./hooks/useVerticalScrollSync.mjs";
import { PivotGridColumn as Ie } from "./components/Column.mjs";
import { generateKey as f, generateDataKey as Be } from "./utils/index.mjs";
import { toTree as M, toRows as Ve, toColumns as We, toData as qe, PivotGridNavigation as Fe, HEADERS_ACTION as _ } from "@progress/kendo-pivotgrid-common";
const Ke = t.forwardRef((n, J) => {
const Q = !ke(Pe, { component: "PivotGrid" }), {
rows: U,
rowAxes: Y,
columns: Z,
columnAxes: ee,
data: te
} = { ...C, ...n }, s = t.useRef(null), w = t.useRef(null), i = t.useRef(null), h = t.useRef(null), P = t.useRef(null), N = t.useRef(null), E = t.useRef(null), ae = Ne(), oe = (e, r) => {
n.onRowAxesChange && n.onRowAxesChange({
value: e,
target: w.current,
syntheticEvent: r
});
}, ne = (e, r) => {
n.onColumnAxesChange && n.onColumnAxesChange({
value: e,
target: w.current,
syntheticEvent: r
});
}, T = M((U || []).slice()), [, re] = $((Y || []).slice(), T, oe), [D, c, le, z] = Ve(T), L = M((Z || []).slice()), [, se] = $((ee || []).slice(), L, ne), [g, m, , O] = We(L), R = qe(
(te || []).slice(),
m,
c,
O,
le
);
t.useImperativeHandle(w, () => ({
props: n,
element: s.current,
columnHeaderRows: g,
rowHeaderRows: D,
dataCells: R,
rowHeaderBreadth: z,
columnHeaderBreadth: O
})), t.useImperativeHandle(J, () => w.current);
const G = [], I = [], B = [], [H, k] = y(n.row || C.row), [S, x] = y(
n.column || C.column
), [me, ie] = y(n.cell || C.cell), [V, W] = y(
n.headerCell || C.headerCell
), ce = n.columnHeadersRow || H, de = n.columnHeadersColumn || S, ue = n.columnHeadersCell || V, pe = n.rowHeadersRow || H, he = n.rowHeadersColumn || S, fe = n.rowHeadersCell || V, Ce = n.dataRow || H, we = n.dataColumn || S;
for (let e = 0; e < m.length; e++)
G.push(
/* @__PURE__ */ t.createElement(
we,
{
key: String(m[e].path),
...x,
path: m[e].path
}
)
), B.push(
/* @__PURE__ */ t.createElement(
de,
{
key: String(m[e].path),
...x,
path: m[e].path
}
)
);
for (let e = 0; e < z; e++)
I.push(/* @__PURE__ */ t.createElement(he, { key: e, ...x }));
const ge = (e) => {
e.target.props.expandable && se(
{
type: _.toggle,
payload: e.target.props.dataItem.path
},
e.syntheticEvent
);
}, be = (e) => {
e.target.props.expandable && re(
{
type: _.toggle,
payload: e.target.props.dataItem.path
},
e.syntheticEvent
);
}, q = Oe(E, N), ve = Ge(E, P), ye = (e) => {
q(e), ve(e);
}, F = t.useCallback(() => {
s.current && h.current && (s.current.style.gridTemplateRows = "", s.current.style.gridTemplateRows = `${h.current.offsetHeight}px 1fr`);
}, []), K = t.useCallback(() => {
s.current && i.current && (s.current.style.gridTemplateColumns = "", s.current.style.gridTemplateColumns = `${i.current.offsetWidth}px 1fr`);
}, []), d = t.useRef(new Fe({ tabIndex: n.tabIndex || 0 }));
t.useEffect(() => {
if (s.current) {
const e = n.tabIndex || 0;
if (d.current.stop(), d.current.tabIndex = e, n.navigatable) {
d.current.start(s.current);
const r = d.current.first;
r && r.setAttribute("tabindex", String(e));
}
}
return () => {
d.current.stop();
};
}, [n.tabIndex, n.navigatable]), t.useEffect(() => {
d.current.update();
}), t.useEffect(() => {
if (h.current) {
const e = new window.ResizeObserver(() => {
window.requestAnimationFrame(() => {
F();
});
});
return e.observe(h.current), () => {
e.disconnect();
};
}
}, [F]), t.useEffect(() => {
if (i.current) {
const e = new window.ResizeObserver(() => {
window.requestAnimationFrame(() => {
K();
});
});
return e.observe(i.current), () => {
e.disconnect();
};
}
}, [K]), Se(() => {
if (X(), i.current) {
const e = new window.ResizeObserver(
() => window.requestAnimationFrame(() => {
X();
})
);
return e.observe(i.current), () => {
e.disconnect();
};
}
}, []);
const u = new Array(g.length).fill([]).map(() => new Array(m.length));
g.forEach((e, r) => {
let a = 0;
Array.from(e.cells).forEach((o) => {
const l = !!(o && o.children && o.children.length), A = (o ? f(o.normalizedPath) + (o.total ? "|[TOTAL]" : "") + (l ? "|[EXPANDED]" : "") : "").replace(/\s/g, "-");
if (o)
for (let v = 0; v < (o.colSpan || 1); v++) {
for (let p = 0; p < (o.rowSpan || 1); p++) {
const Ee = u[r + p].findIndex(
(Re, He) => He >= a && !Re
);
u[r + p][Ee] = A;
}
a++;
}
});
});
const b = R.map((e) => e.cells.map(
(r) => Be(r.rowTuple.members, r.columnTuple.members).replace(/\s/g, "-")
));
return /* @__PURE__ */ t.createElement(
"div",
{
ref: s,
id: n.id,
style: n.style,
tabIndex: n.navigatable ? void 0 : n.tabIndex,
className: xe("k-pivotgrid", n.className),
role: "grid"
},
Q && /* @__PURE__ */ t.createElement(Ae, null),
/* @__PURE__ */ t.createElement("span", { className: "k-pivotgrid-empty-cell" }, /* @__PURE__ */ t.createElement("span", { className: "k-sr-only" }, ae.toLanguageString(j, Te[j]))),
/* @__PURE__ */ t.createElement("div", { ref: N, className: "k-pivotgrid-column-headers", onScroll: q }, /* @__PURE__ */ t.createElement("table", { ref: h, className: "k-pivotgrid-table", role: "none" }, /* @__PURE__ */ t.createElement("colgroup", null, B), /* @__PURE__ */ t.createElement("tbody", { className: "k-pivotgrid-tbody", role: "rowgroup" }, g.map((e, r) => {
let a = !1;
return /* @__PURE__ */ t.createElement(ce, { key: e.name, role: "row", ...k }, e.cells.map((o, l) => {
const A = l !== 0 && !a;
o && (a = !0);
const v = o && !!(o.children && o.children.length), p = o && o.hasChildren && (!o.total || o.total && o.parent.total);
return o ? /* @__PURE__ */ t.createElement(
ue,
{
...W,
key: u[r][l],
"data-key": u[r][l],
id: u[r][l],
columnPath: o.normalizedPath,
rowSpan: o.rowSpan || void 0,
colSpan: o.colSpan || void 0,
onIconClick: ge,
dataItem: o,
expanded: v,
expandable: p,
total: o.total,
first: A,
root: o.levelNum === 0,
role: "columnheader"
},
o.caption
) : null;
}));
})))),
/* @__PURE__ */ t.createElement("div", { ref: P, className: "k-pivotgrid-row-headers" }, /* @__PURE__ */ t.createElement("table", { ref: i, className: "k-pivotgrid-table", role: "none" }, /* @__PURE__ */ t.createElement("colgroup", null, I), /* @__PURE__ */ t.createElement("tbody", { className: "k-pivotgrid-tbody", role: "rowgroup" }, D.map((e, r) => /* @__PURE__ */ t.createElement(
pe,
{
key: f(c[r].path),
...k,
path: c[r].path,
role: "row",
ariaOwns: b[r].join(" ")
},
e.cells.filter(Boolean).map(
(a) => a ? /* @__PURE__ */ t.createElement(
fe,
{
...W,
key: f(a.normalizedPath) + (a.total ? "|[TOTAL]" : "") + (a.children && a.children.length ? "|[EXPANDED]" : ""),
"data-key": f(a.normalizedPath) + (a.total ? "|[TOTAL]" : "") + (a.children && a.children.length ? "|[EXPANDED]" : ""),
rowPath: a.normalizedPath,
rowSpan: a.rowSpan || void 0,
colSpan: a.colSpan || void 0,
dataItem: a,
expanded: !!(a.children && a.children.length),
expandable: a.hasChildren && !a.total,
total: a.total,
onIconClick: be,
root: a.levelNum === 0,
role: "rowheader"
},
a.caption
) : null
)
))))),
/* @__PURE__ */ t.createElement("div", { ref: E, className: "k-pivotgrid-values", onScroll: ye }, /* @__PURE__ */ t.createElement("table", { className: "k-pivotgrid-table", role: "none" }, /* @__PURE__ */ t.createElement("colgroup", null, G), /* @__PURE__ */ t.createElement("tbody", { className: "k-pivotgrid-tbody", role: "none" }, R.map((e, r) => /* @__PURE__ */ t.createElement(
Ce,
{
key: f(c[r].path),
...k,
path: c[r].path,
role: "none"
},
e.cells.map((a, o) => /* @__PURE__ */ t.createElement(
me,
{
key: b[r][o],
"data-key": b[r][o],
id: b[r][o],
...ie,
rowPath: a.rowTuple.members.map((l) => l.name),
columnPath: a.columnTuple.members.map((l) => l.name),
dataItem: a,
total: c[r].total || m[o].total,
role: "gridcell",
ariaDescribedby: u.map((l) => l[o]).join(" ")
},
a && a.data && a.data.fmtValue ? a.data.fmtValue : " "
))
)))))
);
}), C = {
rowAxes: [],
columnAxes: [],
data: [],
row: De,
column: Ie,
cell: ze,
headerCell: Le
};
Ke.displayName = "KendoReactPivotGrid";
export {
Ke as PivotGrid
};