UNPKG

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