@opencorestack/opengridx 0.1.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +162 -19
  3. package/dist/index.d.ts +60 -41
  4. package/dist/opengridx.es.js +5045 -4549
  5. package/dist/opengridx.es.js.map +1 -1
  6. package/dist/opengridx.umd.js +11 -11
  7. package/dist/opengridx.umd.js.map +1 -1
  8. package/docs/API_REFERENCE.md +17 -7
  9. package/docs/README.md +14 -0
  10. package/docs/components/aggregation-footer.md +48 -0
  11. package/docs/components/datagrid.md +8 -3
  12. package/docs/components/empty-state.md +50 -0
  13. package/docs/components/error-overlay.md +40 -0
  14. package/docs/features/editing-reordering.md +11 -7
  15. package/docs/features/filtering.md +10 -8
  16. package/docs/features/selection.md +2 -1
  17. package/docs/features/sorting-pagination.md +3 -1
  18. package/docs/features/state-persistence.md +1 -2
  19. package/docs/roadmap.md +20 -1
  20. package/lib/components/Cell/Cell.tsx +9 -10
  21. package/lib/components/Cell/GridEditInputCell.tsx +4 -4
  22. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +3 -2
  23. package/lib/components/DataGrid/DataGrid.regression.test.tsx +132 -0
  24. package/lib/components/DataGrid/DataGrid.tsx +336 -1018
  25. package/lib/components/DataGrid/GridAggregationFooter.tsx +68 -0
  26. package/lib/components/DataGrid/GridEmptyState.tsx +16 -0
  27. package/lib/components/DataGrid/GridErrorOverlay.tsx +33 -0
  28. package/lib/components/DataGrid/GridListView.tsx +116 -0
  29. package/lib/components/DataGrid/GridPinnedRows.tsx +98 -0
  30. package/lib/components/DataGrid/GridStandaloneColumnPanel.tsx +124 -0
  31. package/lib/components/DataGrid/GridVirtualRows.tsx +202 -0
  32. package/lib/components/FilterPanel/FilterPanel.tsx +18 -10
  33. package/lib/components/Header/ColumnMenu.tsx +2 -2
  34. package/lib/components/Header/Header.tsx +4 -4
  35. package/lib/components/ListView/ListViewRow.tsx +2 -2
  36. package/lib/components/Row/Row.tsx +10 -10
  37. package/lib/components/SkeletonRow/SkeletonRow.tsx +9 -2
  38. package/lib/components/Toolbar/GridToolbar.tsx +6 -0
  39. package/lib/hooks/core/useDataGrid.regression.test.ts +66 -0
  40. package/lib/hooks/core/useDataGrid.ts +14 -34
  41. package/lib/hooks/core/useGridColumns.tsx +228 -0
  42. package/lib/hooks/core/useGridControlledState.ts +192 -0
  43. package/lib/hooks/core/useGridRowPipeline.ts +109 -0
  44. package/lib/hooks/core/useGridScrollSync.ts +52 -0
  45. package/lib/hooks/core/useGridStateSnapshot.ts +63 -0
  46. package/lib/hooks/core/useGridVirtualization.ts +186 -0
  47. package/lib/hooks/core/useGridVisibleRows.ts +66 -0
  48. package/lib/hooks/core/useLayout.ts +0 -6
  49. package/lib/hooks/features/useAggregation.ts +7 -7
  50. package/lib/hooks/features/useGridDataSource.ts +1 -1
  51. package/lib/hooks/features/useGridEditing.ts +31 -32
  52. package/lib/hooks/features/usePivot.test.ts +202 -0
  53. package/lib/hooks/features/usePivot.ts +0 -0
  54. package/lib/hooks/useColumnReorder.ts +1 -1
  55. package/lib/hooks/useRowGrouping.ts +14 -14
  56. package/lib/hooks/useTreeData.ts +1 -1
  57. package/lib/state/types.ts +1 -1
  58. package/lib/state/useGridStateStorage.ts +1 -1
  59. package/lib/types/index.ts +48 -32
  60. package/lib/utils/export/exportToExcelAdvanced.ts +14 -14
  61. package/lib/utils/export/index.ts +22 -17
  62. package/lib/utils/filtering/index.ts +20 -20
  63. package/lib/utils/sorting/index.ts +1 -1
  64. package/package.json +1 -1
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Regression tests for bugs fixed in the DataGrid render layer.
3
+ *
4
+ * Tests cover:
5
+ * - getVisibleRows() respects pagination (not returning all rows)
6
+ * - Row DOM nodes are not remounted when column widths change
7
+ *
8
+ * Not covered here (require a real browser / ResizeObserver):
9
+ * - translateY offset — depends on computed cumulativeHeights, which requires
10
+ * a real viewport; jsdom reports all dimensions as 0
11
+ * - scroll-ref RAF batching — requires scroll events that jsdom fires but
12
+ * requestAnimationFrame does not execute by default
13
+ */
14
+
15
+ import React from 'react';
16
+ import { describe, it, expect } from 'vitest';
17
+ import { render, act } from '@testing-library/react';
18
+ import { DataGrid } from './DataGrid';
19
+ import { useGridApiRef } from '../../hooks/core/useGridApiRef';
20
+ import type { GridColDef } from '../../types';
21
+
22
+ const COLS: GridColDef[] = [
23
+ { field: 'id', headerName: 'ID', width: 80 },
24
+ { field: 'name', headerName: 'Name', width: 150 },
25
+ { field: 'age', headerName: 'Age', width: 100 },
26
+ ];
27
+
28
+ // 10 rows so pagination actually clips the visible set
29
+ const ROWS = Array.from({ length: 10 }, (_, i) => ({
30
+ id: i + 1,
31
+ name: `User ${i + 1}`,
32
+ age: 20 + i,
33
+ }));
34
+
35
+ // ─────────────────────────────────────────────────────────────────────────────
36
+ // Bug: getVisibleRows() was returning sortedUnpinnedRows (all rows) regardless
37
+ // of whether pagination was active. Fixed: now returns paginatedUnpinnedRows
38
+ // when a paginationModel is set.
39
+ // ─────────────────────────────────────────────────────────────────────────────
40
+
41
+ describe('getVisibleRows respects pagination', () => {
42
+ it('returns only the current page rows, not all rows', () => {
43
+ const assigningRef = React.createRef<import('../../types').GridApi>();
44
+
45
+ function GridWithRef() {
46
+ const ref = useGridApiRef();
47
+ // expose ref to test scope after render
48
+ React.useEffect(() => {
49
+ (assigningRef as React.MutableRefObject<import('../../types').GridApi>).current = ref.current;
50
+ });
51
+ return (
52
+ <DataGrid
53
+ rows={ROWS}
54
+ columns={COLS}
55
+ apiRef={ref}
56
+ pagination
57
+ paginationModel={{ page: 0, pageSize: 3 }}
58
+ />
59
+ );
60
+ }
61
+
62
+ act(() => {
63
+ render(<GridWithRef />);
64
+ });
65
+
66
+ // pageSize=3, total=10 → page 0 should expose 3 rows, not 10.
67
+ const visible = assigningRef.current?.getVisibleRows() ?? [];
68
+ expect(visible.length).toBe(3);
69
+ expect(visible.map(r => r.id)).toEqual([1, 2, 3]);
70
+ });
71
+
72
+ it('returns all rows when no pagination is provided', () => {
73
+ const assigningRef = React.createRef<import('../../types').GridApi>();
74
+
75
+ function GridNoPagination() {
76
+ const ref = useGridApiRef();
77
+ React.useEffect(() => {
78
+ (assigningRef as React.MutableRefObject<import('../../types').GridApi>).current = ref.current;
79
+ });
80
+ return <DataGrid rows={ROWS} columns={COLS} apiRef={ref} />;
81
+ }
82
+
83
+ act(() => {
84
+ render(<GridNoPagination />);
85
+ });
86
+
87
+ const visible = assigningRef.current?.getVisibleRows() ?? [];
88
+ // Without pagination the full sorted set is returned.
89
+ expect(visible.length).toBe(ROWS.length);
90
+ });
91
+ });
92
+
93
+ // ─────────────────────────────────────────────────────────────────────────────
94
+ // Bug: row keys were `${row.id}-${virtualization.totalWidth}`, so every column
95
+ // resize unmounted and remounted every DOM row node.
96
+ // Fixed: key is now simply `row.id`.
97
+ //
98
+ // Test strategy: capture DOM element identity before and after a column prop
99
+ // change. If the key includes totalWidth the elements will be new nodes; if
100
+ // the key is stable they will be the exact same DOM nodes.
101
+ // ─────────────────────────────────────────────────────────────────────────────
102
+
103
+ describe('row DOM nodes are stable across column width changes', () => {
104
+ it('does not remount rows when column widths change', () => {
105
+ const { rerender, container } = render(
106
+ <DataGrid rows={ROWS.slice(0, 3)} columns={COLS} />
107
+ );
108
+
109
+ // Collect the row cell elements before the update.
110
+ const cellsBefore = Array.from(
111
+ container.querySelectorAll('[role="gridcell"]')
112
+ );
113
+ expect(cellsBefore.length).toBeGreaterThan(0);
114
+
115
+ // Update the Name column width — simulates a resize.
116
+ const updatedCols: GridColDef[] = COLS.map(c =>
117
+ c.field === 'name' ? { ...c, width: 250 } : c
118
+ );
119
+
120
+ rerender(<DataGrid rows={ROWS.slice(0, 3)} columns={updatedCols} />);
121
+
122
+ const cellsAfter = Array.from(
123
+ container.querySelectorAll('[role="gridcell"]')
124
+ );
125
+
126
+ // Same number of cells, and critically the same DOM node instances.
127
+ expect(cellsAfter.length).toBe(cellsBefore.length);
128
+ cellsBefore.forEach((node, i) => {
129
+ expect(cellsAfter[i]).toBe(node);
130
+ });
131
+ });
132
+ });