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 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 };