UNPKG

@progress/kendo-react-grid

Version:

React Data Grid (Table) provides 100+ ready-to-use data grid features. KendoReact Grid package

649 lines (648 loc) 25.3 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 a from "react"; import { uGrid as xt, validatePackage as Gt, getter as H, classNames as f, WatermarkOverlay as Le } from "@progress/kendo-react-common"; import { process as kt } from "@progress/kendo-data-query"; import { combineFilters as Nt, getDetailExpandableOptions as Ft, getGroupExpandableOptions as Dt, getSelectionOptions as Tt, tableKeyboardNavigationTools as O, Pager as At, tableKeyboardNavigationBodyAttributes as Pt, tableKeyboardNavigationScopeAttributes as _e, tableColumnsVirtualization as Ht } from "@progress/kendo-react-data-tools"; import { GridSelectionCell as Kt } from "./cells/GridSelectionCell.mjs"; import { GridHierarchyCell as Bt } from "./cells/GridHierarchyCell.mjs"; import { GridEditCell as Vt } from "./cells/GridEditCell.mjs"; import { Header as Lt } from "./header/Header.mjs"; import { HeaderRow as _t } from "./header/HeaderRow.mjs"; import { FilterRow as Ot } from "./header/FilterRow.mjs"; import { GroupPanel as zt } from "./header/GroupPanel.mjs"; import { Footer as Mt } from "./footer/Footer.mjs"; import { isRowReorderEnabled as Wt, getRowSpanOptions as Oe, getColumnWidth as re, isSorted as ze, flatData as $t, autoGenerateColumns as jt, mapColumns as Ut, clientColumn as qt, getFlatColumnsState as Jt, getColumnState as ne, getNestedValue as Me, getColSpan as We, resolveCells as Qt, isClientReference as Xt, readColumns as Yt } from "./utils/index.mjs"; import { GridCell as Zt } from "./cells/GridCell.mjs"; import { GridGroupCell as $e } from "./cells/GridGroupCell.mjs"; import { GridRow as pt } from "./rows/GridRow.mjs"; import { GridHeaderSelectionCell as ea } from "./header/GridHeaderSelectionCell.mjs"; import { GridNoRecords as je } from "./components/noRecords/GridNoRecords.mjs"; import { operators as Ue } from "./filterCommon.mjs"; import { FooterRow as ta } from "./footer/FooterRow.mjs"; import { normalize as aa } from "./paging/GridPagerSettings.mjs"; import { packageMetadata as la } from "./package-metadata.mjs"; import { GridDetailCell as ra } from "./cells/GridDetailCell.mjs"; import { GridDetailHierarchyCell as na } from "./cells/GridDetailHierarchyCell.mjs"; import { GridNoRecordsContainer as qe } from "./components/noRecords/GridNoRecordsContainer.mjs"; import { GridClientWrapper as Je } from "./GridClientWrapper.mjs"; import { GridColGroup as ia } from "./components/colGroup/GridColGroup.mjs"; import { GridTable as oa } from "./components/table/GridTable.mjs"; import { GridDropClue as Qe } from "./components/GridDropClue.mjs"; import { GridDragClue as Xe } from "./components/GridDragClue.mjs"; import { GridTableBody as Ye } from "./components/table/GridTableBody.mjs"; import { PagerContainer as da } from "./components/PagerContainer.mjs"; import { GridTableScrollable as ca } from "./components/table/GridTableScrollable.mjs"; import { GridElementContainer as Ze } from "./components/GridElementContainer.mjs"; import { GridContainerElementContainer as sa } from "./components/GridContainerElementContainer.mjs"; import { VirtualScrollHeightContainer as ma } from "./components/VirtualScrollHeightContainer.mjs"; import { gridAriaLabel as pe, messages as ua } from "./messages/index.mjs"; import { VirtualScrollFixed as q } from "./VirtualScrollFixed.mjs"; import { VirtualScroll as fa } from "./VirtualScroll.mjs"; import { GridCustomCellClientContainer as ga } from "./components/GridCustomCellClientContainer.mjs"; import { GridReorderableRowsContainer as ba } from "./components/GridDraggableRowsContainer.mjs"; import { GridRowReorderCell as ha } from "./cells/GridRowReorderCell.mjs"; import { GridHeaderRowReorderCell as ya } from "./header/client/GridHeaderRowReorderCell.mjs"; import { GridLoader as et } from "./components/GridLoader.mjs"; import { gridPremiumFeatures as Ca } from "./utils/premium.mjs"; import { LocalizationService as wa, IntlService as Ea } from "@progress/kendo-react-intl"; const Sa = a.forwardRef((e, ie) => { var Ge, ke, Ne, Fe, De, Te, Ae, Pe; const x = e.id + "-role-element-id", G = e.navigatable ? x : ""; let E = e.columnsState || []; const tt = (t, n, d, i, o, s, l) => { const c = [], g = $t( c, C, t, { index: n }, d !== void 0, i, o, s, ft.defaultExpand, l ); return { flattedData: c, resolvedGroupsCount: g }; }, at = (t) => { const n = t.filter( (d) => d && d.type && d.type.displayName === "KendoReactGridColumn" ); return Yt(n, E, { prevId: 0, idPrefix: G }); }, lt = () => { const t = [], n = (d, i) => d == null ? void 0 : d.forEach((o) => { const s = o.hidden || i; t.push({ ...o, hidden: s }), n(o.children, s); }); return n(E, !1), t; }, rt = (t) => { const n = lt(); return t.filter((d) => { var i; return !d.hidden && !((i = n.find((o) => o.id === d.id)) != null && i.hidden); }); }, nt = (t, n) => { var d; m = at(t), m.filter((i) => !i.hidden).length === 0 && (m = jt( C, e.group, { column: (d = B.column) != null ? d : e.expandField }, { prevId: 0, idPrefix: G } )), ot(m, n), m = rt(m), k = Ut(m, !0), oe = m.map(qt); }, it = (t, n) => { const d = (i) => { var s; const o = n.find((l) => l.id === i.id); return o ? (o.children = (s = i.children) == null ? void 0 : s.map(d), o) : ne(i); }; E = t.filter((i) => i.parentIndex === -1).map(d); }, ot = (t, n) => { var s; t.filter((l) => e.selectedField && l.field === e.selectedField || l.columnType === "checkbox").forEach((l) => { l.width = l.width || "50px", l.cell = l.cell || Kt, l._type = "edit", l.headerCell = l.headerCell || ea; }), F !== void 0 && t.filter((l) => l.columnType === "reorder").forEach((l) => { l.width = l.width || "50px", l.cell = l.cell || ha, l.headerCell = l.headerCell || ya, l.sortable = !1, l.filterable = !1, l.editable = !1; }); const d = Jt(E); it(t, d); const i = { id: "", resizable: !0, width: "32px", title: " ", declarationIndex: -1, orderIndex: -1, children: [], parentIndex: -1, depth: 0, colSpan: 0, headerColSpan: 0, rowSpan: 0, left: 0, right: 0, index: 0, rightBorder: !1, ariaColumnIndex: 0, isAccessible: !0 }; let o = 0; if ((e.expandField || B.enabled) && e.detail) { const l = { ...i, _type: "expand", id: O.generateNavigatableId(`${o++}`, "expand", "column"), cell: Bt, field: (s = B.column) != null ? s : e.expandField, headerClassName: f(u.hierarchyCell({})) }; t.unshift(l), E.unshift(d.find((c) => c.id === l.id) || ne(l)); } for (let l = 0; l < n; l++) { const c = { ...i, isAccessible: !1, cell: $e, id: O.generateNavigatableId(`${o++}`, "group", "column"), field: "value", locked: e.lockGroups }; t.unshift(c), E.unshift(d.find((g) => g.id === c.id) || ne(c)); } t.slice(o).forEach((l) => { l.parentIndex >= 0 && (l.parentIndex += o), l.rowSpannable = l.rowSpannable !== void 0 ? Oe(l.rowSpannable) : ce; }); }, z = () => { var t; return Array.isArray(e.data) ? C.length === e.total : C ? e.total === ((t = e.data) == null ? void 0 : t.total) : !1; }, dt = () => { const { rowHeight: t, detailRowHeight: n, detail: d, expandField: i } = e, o = z(), s = t !== void 0 && t > 0, l = n !== void 0 && n > 0; return !s || K && !o || !!(d && i) && (!l || !o) ? fa : q; }, J = () => e.isClient ? m : oe, ct = (t, n, d, i, o, s) => { let l = We(t, n); if (e.columnVirtualization && t.colSpan === 1) return { colSpan: s, colsToSkip: o }; let c = d.length - 1 === i, g = d.length - i; return e.columnVirtualization && (c = h.length - 1 === i, g = h.length - i), l > 1 && !c ? o = l - 1 : l = 1, g <= l && !c && (l = g), { colSpan: l, colsToSkip: o }; }; let Q, b = [], M, m = [], oe = [], k = [[]]; const st = e.scrollLeftRef || { current: 0 }, W = e.localization || new wa(e.language), mt = e.intl || new Ea((Ge = e.locale) != null ? Ge : "en"), N = e.unstyled, u = N && N.uGrid ? N.uGrid : xt, F = Wt(e.rowReorderable), D = e.autoProcessData === !0 ? { group: !0, sort: !0, filter: !0, search: !0, page: !0 } : e.autoProcessData; let C, R; if (Array.isArray(e.data) ? (C = e.data, R = (ke = e.total) != null ? ke : C.length) : (C = ((Ne = e.data) == null ? void 0 : Ne.data) || [], R = (Te = (De = e.total) != null ? De : (Fe = e.data) == null ? void 0 : Fe.total) != null ? Te : C.length), D) { const { data: t, total: n } = kt(C, { group: D.group ? e.group : void 0, sort: D.sort ? e.sort : void 0, filter: Nt( D.filter ? e.filter : void 0, D.search ? e.search : void 0 ), ...D.page ? { take: e.take, skip: e.skip } : {} }); C = t, R = (Ae = e.total) != null ? Ae : n; } const { size: S = "medium" } = e, ut = typeof e.groupable == "object" && e.groupable.footer || "none", T = e.scrollable === "virtual", K = e.groupable === !0 || typeof e.groupable == "object" && e.groupable.enabled !== !1, B = Ft(!!e.detail), ft = Dt( typeof e.groupable == "object" && e.groupable.enabled !== !1 ? e.groupable.expandable : e.groupable ), { resolvedGroupsCount: gt, flattedData: bt } = tt( ut, e.skip || 0, e.group, e.expandField, e.detailExpand, e.groupExpand, e.dataItemKey ); b = bt; const X = dt(); X === q && z() && (M = b.slice( e.skip || 0, (e.skip || 0) + ((e.take !== void 0 ? e.take : e.pageSize) || 0) )); const de = Tt(e.selectable || !!e.selectedField), ce = Oe(e.rowSpannable), ht = de && de.drag ? "none" : void 0, $ = a.useMemo(() => a.Children.toArray(e.children), [e.children]); nt($, gt); const Y = a.useMemo(() => { const t = Ca(e, m); return { premium: t.length > 0, features: t }; }, [e, m]), se = a.useMemo(() => Y.premium ? !Gt(la, { component: "Grid", features: Y.features }) : !1, [Y.premium]), me = $.map((t) => t && t.type && t.type.displayName === "KendoReactGridToolbar" ? a.cloneElement(t, { ...t.props, ariaControls: x }) : null), j = $.filter((t) => t && t.type && t.type.displayName === "KendoReactGridNoRecords"), ue = $.filter( (t) => t && t.type && t.type.displayName === "KendoReactGridStatusBar" ), h = m.filter((t) => t.children.length === 0), fe = K && /* @__PURE__ */ a.createElement(zt, { columns: J(), group: e.group || [], ariaControls: x }), ge = /* @__PURE__ */ a.createElement( Lt, { size: S, staticHeaders: e.scrollable !== "none", draggable: e.reorderable || K, headerRow: /* @__PURE__ */ a.createElement( _t, { cells: e.cells, sort: e.sort, sortable: e.sortable, group: e.group || [], groupable: K, filter: e.filter, filterable: e.filterable, filterOperators: e.filterOperators || Ue, columnMenu: e.columnMenu, columnMenuIcon: e.columnMenuIcon, columns: m, columnsMap: k, cellRender: e.headerCellRender, navigatable: !!e.navigatable, localization: W, unstyled: N, headerSelectionValue: !!(e.select && b.filter((t) => t.rowType === "data").every( (t) => e.select && e.dataItemKey && H(e.dataItemKey)(t.dataItem) !== void 0 ? e.select[H(e.dataItemKey)(t.dataItem)] : void 0 )) } ), filterRow: e.filterable && /* @__PURE__ */ a.createElement( Ot, { cells: e.cells, size: S, columns: m, filter: e.filter, filterOperators: e.filterOperators || Ue, sort: e.sort, cellRender: e.filterCellRender, navigatable: !!e.navigatable, ariaRowIndex: k.length + 1, localization: W } ) || void 0, cols: h.map((t, n) => /* @__PURE__ */ a.createElement("col", { key: n.toString(), width: re(t) })) } ), yt = st.current || 0, Ct = parseFloat(((e.style || {}).width || "").toString()), wt = (t, n, d, i, o) => { let s = !1; const l = e.selectedField ? Me(e.selectedField, t.dataItem) : e.select && e.dataItemKey && H(e.dataItemKey)(t.dataItem) !== void 0 ? e.select[H(e.dataItemKey)(t.dataItem)] : void 0; let c = 0; const { colSpans: g, hiddenColumns: A } = Ht({ enabled: e.columnVirtualization, columns: h, tableViewPortWidth: Ct, scrollLeft: yt, getColSpan: We, dataItem: t.dataItem }), I = h.filter((r, y) => !A[y]); return { row: h.map((r, y) => { var He, Ke, Be, Ve; if (A[y]) return null; if (c > 0) return c--, null; let w; if ((He = r.rowSpannable) != null && He.enabled && t.rowType === "data" && r.field && o) { const v = r.field ? (Be = (Ke = r.rowSpannable).valueGetter) == null ? void 0 : Be.call(Ke, t.dataItem, r.field) : null; w = { value: v, count: 1 }, o[r.field] && ((Ve = o[r.field]) == null ? void 0 : Ve.value) === v && o[r.field] !== null ? (o[r.field].count++, w.count = null) : o[r.field] = w; } const { colSpan: L, colsToSkip: ee } = ct( r, t.dataItem, I, y, c, g[y] ); c = ee; const _ = r.id ? r.id : y, It = f(u.contentSticky({ locked: r.locked }), r.className), vt = r.left !== void 0 ? { left: r.left, right: r.right } : {}; let te = !1; if (r.editable && (e.editable || e.editField)) { const v = e.editField ? Me(e.editField, t.dataItem) : e.edit && e.dataItemKey ? e.edit[H(e.dataItemKey)(t.dataItem)] : void 0, le = typeof v == "boolean" ? v : Array.isArray(v) ? v.indexOf(r.field) > -1 : r.field !== void 0 && v === r.field; le && r.columnType === "data" && (le === !0 || le === r.field) && (s = !0, te = !0); } const ae = r.cell || te && Vt || Zt, Rt = e.expandField && e.detail && r.field === e.expandField || r._type === "expand", P = { locked: e.lockGroups, id: O.generateNavigatableId( `${n}-${String(y)}`, G, Rt || t.rowType === "groupHeader" || t.rowType === "groupFooter" || r.field === "value" ? "nodata" : "cell" ), colSpan: L, dataItem: t.dataItem, field: r.field, editor: r.editor, format: r.format, columnType: r.columnType, rowReorderable: F, className: It, render: e.cellRender, cells: Qt(e.cells, r.cells), columnIndex: y, columnsCount: h.length, rowType: t.rowType, level: t.level, expanded: t.expanded, dataIndex: t.dataIndex, rowDataIndex: d, columnPosition: vt, style: {}, ariaColumnIndex: r.ariaColumnIndex, isSelected: (r == null ? void 0 : r._type) === "edit" ? l : Array.isArray(l) && l.indexOf(y) > -1, isSorted: !!ze(r.field, e.sort), isInEdit: te, isAlt: i, unstyled: N, group: t.group, localization: W, intl: mt, _rowSpan: w }; return r.cell ? /* @__PURE__ */ a.createElement( ga, { key: _, isClient: Xt(ae), dataItem: P.dataItem, rowDataIndex: P.rowDataIndex, columnIndex: P.columnIndex, columnPosition: P.columnPosition }, /* @__PURE__ */ a.createElement(ae, { ...P }) ) : /* @__PURE__ */ a.createElement(ae, { key: _, ...P }); }), isInEdit: s, isSelected: typeof l == "boolean" && l }; }; let be = 0; if (T && Q) for (let t = 0; t < Q.topCacheCount + Q.attendedSkip - (e.skip || 0); t++) { const n = b.shift(); if (n) b.push(n), be++, n.rowType === "groupHeader" && t--; else break; } const he = (t) => t >= b.length - be; let ye = e.skip || 0; const Z = [], Ce = !b.length, we = k.length + (e.filterable ? 1 : 0) + 1; let V = 0; if (b.length) { let t = -1, n = 0; const d = ce.enabled ? {} : void 0; (M || b).forEach((i, o) => { i.rowType === "data" && (ye++, t++); const s = ye % 2 === 0, l = e.dataItemKey && H(e.dataItemKey)(i.dataItem), c = o + (e.skip || 0), g = l || "ai" + c, A = g + "_1", I = wt(i, g, t, s, d); if (V = c + we + n, Z.push( /* @__PURE__ */ a.createElement( pt, { key: g, dataItem: i.dataItem, isAltRow: s, isInEdit: I.isInEdit, rowType: i.rowType, isRowReorderable: F, isHidden: he(o), onClick: null, onDoubleClick: null, selectedField: e.selectedField, rowHeight: e.rowHeight, render: e.rowRender, ariaRowIndex: V, absoluteRowIndex: c, dataIndex: T && !e.groupable ? c : t, isSelected: I.isSelected, rows: e.rows }, I.row ) ), e.detail && i.rowType === "data" && i.expanded) { const r = h.length - (e.expandField || B.enabled ? 1 : 0) - (e.group ? e.group.length : 0) || 1; n++, V = c + we + n, Z.push( /* @__PURE__ */ a.createElement( "tr", { key: A, className: f(u.detailTr({ isAlt: s })), style: { visibility: he(o) ? "hidden" : "", height: e.detailRowHeight }, role: "row", "aria-rowindex": V }, e.group && e.group.map((y, w) => { var _; const L = (_ = I == null ? void 0 : I.row[w]) == null ? void 0 : _.props.style, ee = L ? { left: L.left, right: L.right } : {}; return /* @__PURE__ */ a.createElement( $e, { id: "", dataIndex: i.dataIndex, field: y.field, dataItem: i.dataItem, key: w, columnPosition: ee, style: {}, ariaColumnIndex: 1 + w, isSelected: !1, locked: e.lockGroups, cells: e.cells, group: i.group } ); }), (e.expandField || B.enabled) && /* @__PURE__ */ a.createElement( na, { unstyled: N, id: O.generateNavigatableId(`${A}-dhcell`, G) } ), /* @__PURE__ */ a.createElement( ra, { dataItem: i.dataItem, dataIndex: i.dataIndex, colSpan: r, ariaColIndex: 2 + (e.group ? e.group.length : 0), detail: e.detail, id: O.generateNavigatableId(`${A}-dcell`, G) } ) ) ); } }); } const Ee = { size: S, total: R, skip: e.skip || 0, take: (e.take !== void 0 ? e.take : e.pageSize) || 10, ...aa(e.pageable || {}) }, Se = /* @__PURE__ */ a.createElement(da, null, e.pager ? /* @__PURE__ */ a.createElement(e.pager, { ...Ee }) : /* @__PURE__ */ a.createElement(At, { className: f(u.pager({})), ...Ee })), Et = (t, n) => /* @__PURE__ */ a.createElement("col", { key: n.toString(), width: re(t) }), St = (Pe = e.cells) != null && Pe.footerCell || m.some((t) => { var n; return !!(t.footerCell || (n = t.cells) != null && n.footerCell); }) ? /* @__PURE__ */ a.createElement( Mt, { size: S, staticHeaders: e.scrollable !== "none", row: /* @__PURE__ */ a.createElement( ta, { cells: e.cells, idPrefix: G, columns: m, ariaRowIndex: V + 1 } ), cols: h.map(Et) } ) : null, Ie = /* @__PURE__ */ a.createElement(ia, null, h.map((t, n) => /* @__PURE__ */ a.createElement( "col", { key: n.toString(), className: ze(t.field, e.sort) ? f(u.sorted({})) : void 0, width: re(t) } ))), ve = e.reorderable || K, { detail: Ia, cells: va, rows: Ra, ...Re } = e, xe = /* @__PURE__ */ a.createElement( "tbody", { role: "rowgroup", className: f(u.tbody({})), ...Pt }, Z ); let p = xe; if (F && (p = /* @__PURE__ */ a.createElement( ba, { unstyled: u, columns: m, rowReorderSettings: e.rowReorderable }, xe )), e.scrollable === "none") return /* @__PURE__ */ a.createElement( Je, { gridRef: ie, gridProps: Re, columnsRef: J(), columnsMapRef: k, columnsState: E, dataRef: b, slicedData: M, isFixedVirtualScroll: X === q, id: x, total: R, isAllData: z(), detailExpandable: !!e.detail }, /* @__PURE__ */ a.createElement(Ze, null, /* @__PURE__ */ a.createElement( "div", { id: e.id, style: e.style, className: f(u.wrapper({ size: S }), e.className), "aria-label": e.ariaLabel, ..._e }, me, fe, /* @__PURE__ */ a.createElement( oa, { selectable: e.selectable, className: f(u.table({ size: S })) }, Ie, ge, /* @__PURE__ */ a.createElement(Ye, { rowReorderable: F }, p) ), Ce && /* @__PURE__ */ a.createElement(qe, null, j.length ? j : /* @__PURE__ */ a.createElement(je, null)), ve && /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(Qe, null), /* @__PURE__ */ a.createElement(Xe, null)) )), ue, e.pageable && Se, /* @__PURE__ */ a.createElement(et, { loader: e.loader, showLoader: e.showLoader }), se && /* @__PURE__ */ a.createElement(Le, null) ); let U = e.style || {}; return T && (U.height || (U = Object.assign({}, U, { height: "450px" }))), /* @__PURE__ */ a.createElement( Je, { gridRef: ie, gridProps: Re, columnsRef: J(), columnsMapRef: k, columnsState: E, dataRef: b, slicedData: M, isFixedVirtualScroll: X === q, id: x, total: R, isAllData: z(), detailExpandable: !!e.detail }, /* @__PURE__ */ a.createElement(Ze, null, /* @__PURE__ */ a.createElement( "div", { id: e.id, style: U, className: f( u.wrapper({ size: S, virtual: T }), e.className ), "aria-label": e.ariaLabel, ..._e }, me, fe, /* @__PURE__ */ a.createElement( "div", { className: f(u.ariaRoot({})), role: "grid", "aria-colcount": h.length, "aria-rowcount": R, id: x, "aria-label": W.toLanguageString(pe, ua[pe]) }, ge, /* @__PURE__ */ a.createElement("div", { className: f(u.container({})), role: "presentation" }, /* @__PURE__ */ a.createElement(sa, null, /* @__PURE__ */ a.createElement("div", { className: f(u.content({})), role: "presentation" }, /* @__PURE__ */ a.createElement("div", { className: f(u.tableWrap({})), role: "presentation" }, /* @__PURE__ */ a.createElement( ca, { selectable: e.selectable, tableClassName: f( u.table({ size: S }) ), tableStyle: { userSelect: ht } }, Ie, /* @__PURE__ */ a.createElement(Ye, { rowReorderable: F }, p) ), Ce && /* @__PURE__ */ a.createElement(qe, null, j.length ? j : /* @__PURE__ */ a.createElement(je, null))), T && /* @__PURE__ */ a.createElement( "div", { className: f(u.heightContainer({})), role: "presentation" }, /* @__PURE__ */ a.createElement(ma, { isVirtualScroll: T }) )))), St, ve && /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement(Qe, null), /* @__PURE__ */ a.createElement(Xe, null)), se && /* @__PURE__ */ a.createElement(Le, null) ), ue, e.pageable && Se, /* @__PURE__ */ a.createElement(et, { loader: e.loader, showLoader: e.showLoader }) )) ); }); Sa.displayName = "KendoReactGridComponent"; export { Sa as GridComponent };