@opencorestack/opengridx 0.1.6 → 0.1.8

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 (130) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/README.md +9 -0
  3. package/dist/index.d.ts +12 -1
  4. package/dist/opengridx.css +1 -1
  5. package/dist/opengridx.es.js +2505 -2450
  6. package/dist/opengridx.es.js.map +1 -1
  7. package/dist/opengridx.umd.js +12 -12
  8. package/dist/opengridx.umd.js.map +1 -1
  9. package/docs/API_REFERENCE.md +177 -0
  10. package/docs/README.md +60 -0
  11. package/docs/components/cell.md +44 -0
  12. package/docs/components/column-group-header.md +57 -0
  13. package/docs/components/column-resize.md +63 -0
  14. package/docs/components/column-visibility.md +61 -0
  15. package/docs/components/datagrid.md +70 -0
  16. package/docs/components/filter-panel.md +26 -0
  17. package/docs/components/header.md +39 -0
  18. package/docs/components/pagination.md +34 -0
  19. package/docs/components/row.md +31 -0
  20. package/docs/components/toolbar.md +40 -0
  21. package/docs/components/tooltip.md +68 -0
  22. package/docs/customization/slots-api.md +227 -0
  23. package/docs/customization/theming.md +293 -0
  24. package/docs/features/aggregation-pivot.md +79 -0
  25. package/docs/features/cell-spanning.md +520 -0
  26. package/docs/features/clipboard.md +76 -0
  27. package/docs/features/custom-pagination.md +143 -0
  28. package/docs/features/data-source.md +72 -0
  29. package/docs/features/editing-reordering.md +99 -0
  30. package/docs/features/export-guide.md +434 -0
  31. package/docs/features/filtering.md +83 -0
  32. package/docs/features/infinite-scroll.md +87 -0
  33. package/docs/features/list-view.md +65 -0
  34. package/docs/features/loading-states.md +68 -0
  35. package/docs/features/master-detail.md +46 -0
  36. package/docs/features/pinning.md +67 -0
  37. package/docs/features/selection.md +70 -0
  38. package/docs/features/sorting-pagination.md +66 -0
  39. package/docs/features/state-persistence.md +67 -0
  40. package/docs/features/tree-data-grouping.md +67 -0
  41. package/docs/features/virtualization.md +188 -0
  42. package/docs/roadmap.md +71 -0
  43. package/lib/components/Cell/Cell.css +119 -0
  44. package/lib/components/Cell/Cell.tsx +264 -0
  45. package/lib/components/Cell/GridEditInputCell.css +62 -0
  46. package/lib/components/Cell/GridEditInputCell.tsx +152 -0
  47. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.css +67 -0
  48. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.tsx +220 -0
  49. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.css +31 -0
  50. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.tsx +85 -0
  51. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.css +137 -0
  52. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +190 -0
  53. package/lib/components/DataGrid/DataGrid.css +224 -0
  54. package/lib/components/DataGrid/DataGrid.tsx +2269 -0
  55. package/lib/components/DetailPanel/DetailPanel.css +36 -0
  56. package/lib/components/DetailPanel/DetailPanel.tsx +34 -0
  57. package/lib/components/FilterPanel/FilterPanel.css +196 -0
  58. package/lib/components/FilterPanel/FilterPanel.tsx +214 -0
  59. package/lib/components/FilterPanel/index.ts +1 -0
  60. package/lib/components/Header/ColumnMenu.css +68 -0
  61. package/lib/components/Header/ColumnMenu.tsx +249 -0
  62. package/lib/components/Header/Header.css +224 -0
  63. package/lib/components/Header/Header.tsx +516 -0
  64. package/lib/components/ListView/ListView.css +112 -0
  65. package/lib/components/ListView/ListViewRow.tsx +63 -0
  66. package/lib/components/Pagination/Pagination.css +91 -0
  67. package/lib/components/Pagination/Pagination.tsx +151 -0
  68. package/lib/components/QuickFilter/QuickFilter.css +23 -0
  69. package/lib/components/QuickFilter/QuickFilter.tsx +79 -0
  70. package/lib/components/Row/Row.css +126 -0
  71. package/lib/components/Row/Row.tsx +377 -0
  72. package/lib/components/Skeleton/Skeleton.css +55 -0
  73. package/lib/components/Skeleton/Skeleton.tsx +22 -0
  74. package/lib/components/SkeletonRow/SkeletonRow.css +32 -0
  75. package/lib/components/SkeletonRow/SkeletonRow.tsx +89 -0
  76. package/lib/components/SkeletonRow/index.ts +1 -0
  77. package/lib/components/Toolbar/GlobalSearch.css +110 -0
  78. package/lib/components/Toolbar/GlobalSearch.tsx +167 -0
  79. package/lib/components/Toolbar/GridToolbar.css +221 -0
  80. package/lib/components/Toolbar/GridToolbar.tsx +658 -0
  81. package/lib/components/Toolbar/PivotPanel.css +212 -0
  82. package/lib/components/Toolbar/PivotPanel.tsx +239 -0
  83. package/lib/components/Tooltip/Tooltip.css +59 -0
  84. package/lib/components/Tooltip/Tooltip.tsx +106 -0
  85. package/lib/components/ui/Button.css +89 -0
  86. package/lib/components/ui/Button.tsx +39 -0
  87. package/lib/components/ui/Checkbox.css +71 -0
  88. package/lib/components/ui/Checkbox.tsx +66 -0
  89. package/lib/components/ui/DragHandleIcon.css +19 -0
  90. package/lib/components/ui/DragHandleIcon.tsx +18 -0
  91. package/lib/components/ui/ExpandIcon.css +38 -0
  92. package/lib/components/ui/ExpandIcon.tsx +75 -0
  93. package/lib/components/ui/Input.css +59 -0
  94. package/lib/components/ui/Input.tsx +45 -0
  95. package/lib/components/ui/index.ts +15 -0
  96. package/lib/hooks/core/useDataGrid.ts +392 -0
  97. package/lib/hooks/core/useGridApiRef.ts +10 -0
  98. package/lib/hooks/features/useAggregation.ts +143 -0
  99. package/lib/hooks/features/useGridClipboard.ts +133 -0
  100. package/lib/hooks/features/useGridDataSource.ts +190 -0
  101. package/lib/hooks/features/useGridEditing.ts +100 -0
  102. package/lib/hooks/features/useGridSpanning.ts +349 -0
  103. package/lib/hooks/features/usePivot.ts +174 -0
  104. package/lib/hooks/useColumnReorder.ts +114 -0
  105. package/lib/hooks/useRowGrouping.ts +302 -0
  106. package/lib/hooks/useRowReorder.ts +83 -0
  107. package/lib/hooks/useTreeData.ts +323 -0
  108. package/lib/index.ts +106 -0
  109. package/lib/state/index.ts +17 -0
  110. package/lib/state/types.ts +48 -0
  111. package/lib/state/useGridStateStorage.ts +113 -0
  112. package/lib/styles/base/reset.css +21 -0
  113. package/lib/styles/base/variables.css +161 -0
  114. package/lib/styles/opengridx.css +27 -0
  115. package/lib/styles/opengridx.css.d.ts +4 -0
  116. package/lib/theme/DataGridThemeProvider.tsx +276 -0
  117. package/lib/theme/defaultStyles.ts +0 -0
  118. package/lib/theme/index.ts +21 -0
  119. package/lib/theme/presets.ts +148 -0
  120. package/lib/theme/types.ts +155 -0
  121. package/lib/types/index.ts +764 -0
  122. package/lib/utils/export/exportToExcelAdvanced.ts +516 -0
  123. package/lib/utils/export/index.ts +550 -0
  124. package/lib/utils/filtering/index.ts +240 -0
  125. package/lib/utils/pinning/index.ts +282 -0
  126. package/lib/utils/sorting/index.ts +55 -0
  127. package/lib/utils/virtualization/index.ts +106 -0
  128. package/lib/vite-env.d.ts +1 -0
  129. package/llms.txt +2 -1
  130. package/package.json +12 -4
@@ -0,0 +1,434 @@
1
+ # Export Functionality Guide
2
+
3
+ The DataGrid provides built-in export utilities for multiple formats. The standard exports (CSV, JSON, Print, basic Excel) have **zero dependencies**. The advanced Excel export uses [ExcelJS](https://github.com/exceljs/exceljs) loaded lazily.
4
+
5
+ ## Available Export Formats
6
+
7
+ | Format | Function | Deps | Description |
8
+ |---|---|---|---|
9
+ | CSV | `exportToCsv` | none | Comma-separated values |
10
+ | Excel (basic) | `exportToExcel` | none | HTML-table `.xls` trick |
11
+ | **Excel (advanced)** | `exportToExcelAdvanced` | ExcelJS (lazy) | Real `.xlsx` with styles, types, multi-sheet |
12
+ | JSON | `exportToJson` | none | Structured JSON |
13
+ | Print | `printGrid` | none | Browser print dialog |
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ ```tsx
20
+ import { exportToCsv, exportToExcel, exportToExcelAdvanced, exportToJson, printGrid } from '@opencorestack/opengridx';
21
+
22
+ // CSV
23
+ exportToCsv(rows, columns, { fileName: 'data.csv' });
24
+
25
+ // Basic Excel (no deps)
26
+ exportToExcel(rows, columns, { fileName: 'data.xlsx' });
27
+
28
+ // Advanced Excel (ExcelJS, lazy-loaded)
29
+ await exportToExcelAdvanced(rows, columns, { fileName: 'data.xlsx' });
30
+
31
+ // JSON
32
+ exportToJson(rows, columns, { fileName: 'data.json', pretty: true });
33
+
34
+ // Print
35
+ printGrid(rows, columns, 'My Report');
36
+ ```
37
+
38
+ ---
39
+
40
+ ## 1. `exportToCsv`
41
+
42
+ ```tsx
43
+ import { exportToCsv } from '@opencorestack/opengridx';
44
+
45
+ exportToCsv(rows, columns, {
46
+ fileName: 'employees.csv',
47
+ includeHeaders: true,
48
+ delimiter: ',',
49
+ selectedRows: [1, 2, 3], // export only these IDs
50
+ aggregationResult: aggResult, // adds SUM/AVG totals row
51
+ aggregationModel: { salary: 'sum' },
52
+ });
53
+ ```
54
+
55
+ **`CsvExportOptions`:**
56
+
57
+ | Option | Type | Default | Description |
58
+ |---|---|---|---|
59
+ | `fileName` | `string` | `'export.csv'` | Output filename |
60
+ | `includeHeaders` | `boolean` | `true` | Include column header row |
61
+ | `delimiter` | `string` | `','` | Field delimiter |
62
+ | `selectedRows` | `(string\|number)[]` | — | Export only these row IDs |
63
+ | `aggregationResult` | `object \| null` | — | Aggregation values row |
64
+ | `aggregationModel` | `object \| null` | — | Labels for aggregation row |
65
+
66
+ ---
67
+
68
+ ## 2. `exportToExcel` (basic)
69
+
70
+ HTML-table approach, no external libraries. Opens reliably in Excel and Numbers but as a legacy `.xls` format.
71
+
72
+ ```tsx
73
+ import { exportToExcel } from '@opencorestack/opengridx';
74
+
75
+ exportToExcel(rows, columns, {
76
+ fileName: 'report.xls',
77
+ sheetName: 'Data',
78
+ includeHeaders: true,
79
+ aggregationResult: aggResult,
80
+ aggregationModel: { salary: 'sum' },
81
+ });
82
+ ```
83
+
84
+ **`ExcelExportOptions`:**
85
+
86
+ | Option | Type | Default | Description |
87
+ |---|---|---|---|
88
+ | `fileName` | `string` | `'export.xlsx'` | Output filename |
89
+ | `sheetName` | `string` | `'Sheet1'` | Sheet tab name |
90
+ | `includeHeaders` | `boolean` | `true` | Include column header row |
91
+ | `selectedRows` | `(string\|number)[]` | — | Export only these row IDs |
92
+ | `aggregationResult` | `object \| null` | — | Aggregation values row |
93
+ | `aggregationModel` | `object \| null` | — | Labels for aggregation row |
94
+
95
+ ---
96
+
97
+ ## 3. `exportToExcelAdvanced` ⭐ (recommended)
98
+
99
+ Generates a **real `.xlsx`** file using ExcelJS, loaded lazily (zero bundle-size impact unless called).
100
+
101
+ ```tsx
102
+ import { exportToExcelAdvanced } from '@opencorestack/opengridx';
103
+
104
+ // Simple — single sheet, all defaults
105
+ await exportToExcelAdvanced(rows, columns, {
106
+ fileName: 'employees.xlsx',
107
+ });
108
+
109
+ // Full options — multi-sheet, custom styles
110
+ await exportToExcelAdvanced(rows, columns, {
111
+ fileName: 'full-report.xlsx',
112
+
113
+ sheets: [
114
+ {
115
+ name: 'All Employees',
116
+ rows: 'all', // or 'selected'
117
+ includeHeaders: true,
118
+ includeSummary: true, // aggregation totals at bottom
119
+ autoFilter: true, // dropdown filter buttons in header
120
+ frozenHeader: true, // freeze row 1
121
+ alternateRowColor: '#f8fafc',
122
+ },
123
+ {
124
+ name: 'Selected Rows',
125
+ rows: 'selected',
126
+ includeHeaders: true,
127
+ },
128
+ {
129
+ type: 'summary', // standalone aggregation sheet
130
+ name: 'Aggregation',
131
+ },
132
+ ],
133
+
134
+ columnStyles: {
135
+ salary: { numFmt: '$#,##0.00', alignment: 'right' },
136
+ bonus: { numFmt: '$#,##0.00', alignment: 'right' },
137
+ percent: { numFmt: '0.00%' },
138
+ joinDate:{ numFmt: 'yyyy-mm-dd' },
139
+ },
140
+
141
+ headerFillColor: '#1e3a5f', // header row background
142
+ headerTextColor: '#e2e8f0', // header row text
143
+ headerFontSize: 11,
144
+ bodyFontSize: 10,
145
+
146
+ aggregationResult: aggResult,
147
+ aggregationModel: { salary: 'sum', bonus: 'sum', score: 'avg' },
148
+ selectedRows: rowSelectionModel,
149
+ });
150
+ ```
151
+
152
+ ### `ExcelAdvancedExportOptions`
153
+
154
+ | Option | Type | Default | Description |
155
+ |---|---|---|---|
156
+ | `fileName` | `string` | `'export.xlsx'` | Output filename (`.xlsx` appended if missing) |
157
+ | `sheets` | `ExcelSheetDefinition[]` | `[{ name: 'Data', rows: 'all' }]` | Sheet definitions |
158
+ | `columnStyles` | `Record<string, ExcelColumnStyle>` | `{}` | Per-column style overrides |
159
+ | `headerFillColor` | `string` | `'#f1f5f9'` | Header row background (`#rrggbb`) |
160
+ | `headerTextColor` | `string` | `'#334155'` | Header row text color |
161
+ | `headerFontSize` | `number` | `10` | Header font size (pt) |
162
+ | `bodyFontSize` | `number` | `10` | Body font size (pt) |
163
+ | `aggregationResult` | `object \| null` | — | Aggregation totals |
164
+ | `aggregationModel` | `object \| null` | — | Aggregation function labels |
165
+ | `selectedRows` | `(string\|number)[]` | — | IDs for `rows: 'selected'` sheets |
166
+
167
+ ### `ExcelSheetDefinition`
168
+
169
+ | Option | Type | Default | Description |
170
+ |---|---|---|---|
171
+ | `name` | `string` | — | Sheet tab name (max 31 chars) |
172
+ | `rows` | `'all' \| 'selected'` | `'all'` | Which rows to include |
173
+ | `includeHeaders` | `boolean` | `true` | Include column header row |
174
+ | `includeSummary` | `boolean` | `false` | Aggregation totals rows at bottom |
175
+ | `autoFilter` | `boolean` | `true` | Excel filter dropdowns on header |
176
+ | `frozenHeader` | `boolean` | `true` | Freeze row 1 |
177
+ | `alternateRowColor` | `string \| false` | `'#f8fafc'` | Odd-row fill. `false` to disable |
178
+
179
+ ### `ExcelColumnStyle`
180
+
181
+ | Option | Type | Description |
182
+ |---|---|---|
183
+ | `numFmt` | `string` | Excel number format, e.g. `'$#,##0.00'`, `'0.00%'`, `'yyyy-mm-dd'` |
184
+ | `width` | `number` | Column width in characters (overrides auto) |
185
+ | `alignment` | `'left' \| 'center' \| 'right'` | Horizontal alignment |
186
+ | `embedImage` | `boolean` | If true, URL in cell is fetched and embedded as image |
187
+ | `imageWidth` | `number` | Width of embedded image (px, default: 40) |
188
+ | `imageHeight`| `number` | Height of embedded image (px, default: 40) |
189
+
190
+ ### Summary Sheet
191
+
192
+ Pass `{ type: 'summary', name: 'My Sheet' }` in `sheets` to add a standalone aggregation sheet:
193
+
194
+ ```
195
+ | Column | Function | Value |
196
+ |--------------|----------|-----------|
197
+ | Salary | SUM | $8,320,000|
198
+ | Bonus | SUM | $1,040,000|
199
+ | Perf. Score | AVG | 3.7 |
200
+ ```
201
+
202
+ ### Feature Comparison: Basic vs Advanced
203
+
204
+ | Feature | `exportToExcel` | `exportToExcelAdvanced` |
205
+ |---|---|---|
206
+ | True `.xlsx` format | ❌ HTML trick | ✅ |
207
+ | Native number cells | ❌ text | ✅ |
208
+ | Native date cells | ❌ text | ✅ |
209
+ | Native boolean cells | ❌ text | ✅ |
210
+ | Number format strings | ❌ | ✅ |
211
+ | Bold / colored header | ❌ CSS ignored | ✅ |
212
+ | Column widths | ❌ | ✅ auto from `colDef.width` |
213
+ | Frozen header row | ❌ | ✅ |
214
+ | Auto-filter dropdowns | ❌ | ✅ |
215
+ | Alternating row colors | ❌ | ✅ |
216
+ | Multi-sheet workbooks | ❌ | ✅ |
217
+ | Aggregation totals row | Inline text | ✅ styled |
218
+ | Standalone summary sheet | ❌ | ✅ |
219
+ | Bundle impact | Zero | Zero (lazy-loaded) |
220
+
221
+ ---
222
+
223
+ ## 4. `exportToJson`
224
+
225
+ ```tsx
226
+ import { exportToJson } from '@opencorestack/opengridx';
227
+
228
+ exportToJson(rows, columns, {
229
+ fileName: 'data.json',
230
+ pretty: true,
231
+ aggregationResult: aggResult,
232
+ aggregationModel,
233
+ selectedRows: [1, 2, 3],
234
+ });
235
+ ```
236
+
237
+ When `aggregationResult` is provided, output shape becomes:
238
+ ```json
239
+ {
240
+ "data": [...],
241
+ "aggregation": {
242
+ "labels": { "salary": "SUM" },
243
+ "values": { "salary": 8320000 }
244
+ }
245
+ }
246
+ ```
247
+
248
+ **`JsonExportOptions`:**
249
+
250
+ | Option | Type | Default | Description |
251
+ |---|---|---|---|
252
+ | `fileName` | `string` | `'export.json'` | Output filename |
253
+ | `pretty` | `boolean` | `true` | Pretty-print with indentation |
254
+ | `selectedRows` | `(string\|number)[]` | — | Export only these row IDs |
255
+ | `aggregationResult` | `object \| null` | — | Append aggregation object |
256
+ | `aggregationModel` | `object \| null` | — | Function labels |
257
+
258
+ ---
259
+
260
+ ## 5. `printGrid`
261
+
262
+ Opens a browser print dialog with a formatted table.
263
+
264
+ ```tsx
265
+ import { printGrid } from '@opencorestack/opengridx';
266
+
267
+ // Simple
268
+ printGrid(rows, columns, 'Employee Report');
269
+
270
+ // With options
271
+ printGrid(rows, columns, {
272
+ title: 'Q1 Report',
273
+ selectedRows: [1, 2, 3],
274
+ aggregationResult: aggResult,
275
+ aggregationModel,
276
+ });
277
+ ```
278
+
279
+ **`PrintOptions`:**
280
+
281
+ | Option | Type | Description |
282
+ |---|---|---|
283
+ | `title` | `string` | Print page title |
284
+ | `selectedRows` | `(string\|number)[]` | Print only these row IDs |
285
+ | `aggregationResult` | `object \| null` | Append totals |
286
+ | `aggregationModel` | `object \| null` | Label totals |
287
+
288
+ ---
289
+
290
+ ## Common Patterns
291
+
292
+ ### Export with toolbar integration
293
+
294
+ ```tsx
295
+ import { DataGrid, GridToolbar, exportToExcelAdvanced } from '@opencorestack/opengridx';
296
+
297
+ function MyGrid() {
298
+ const [rows, setRows] = useState([...]);
299
+ const [columns] = useState([...]);
300
+ const [selected, setSelected] = useState([]);
301
+
302
+ return (
303
+ <DataGrid
304
+ rows={rows}
305
+ columns={columns}
306
+ checkboxSelection
307
+ rowSelectionModel={selected}
308
+ onRowSelectionModelChange={setSelected}
309
+ slots={{ toolbar: GridToolbar }}
310
+ slotProps={{
311
+ toolbar: {
312
+ onExcelAdvanced: () => exportToExcelAdvanced(rows, columns, {
313
+ fileName: 'report.xlsx',
314
+ selectedRows: selected,
315
+ }),
316
+ },
317
+ }}
318
+ />
319
+ );
320
+ }
321
+ ```
322
+
323
+ ### Multi-sheet with selection
324
+
325
+ ```tsx
326
+ await exportToExcelAdvanced(rows, columns, {
327
+ fileName: 'report.xlsx',
328
+ sheets: [
329
+ { name: 'All Data', rows: 'all', includeSummary: true },
330
+ { name: 'Selected', rows: 'selected', includeSummary: false },
331
+ { type: 'summary', name: 'Totals' },
332
+ ],
333
+ selectedRows: rowSelectionModel,
334
+ aggregationResult: aggResult,
335
+ aggregationModel: { salary: 'sum', bonus: 'sum' },
336
+ });
337
+ ```
338
+
339
+ ### Respect `valueFormatter` for styled columns
340
+
341
+ The advanced export keeps **raw values** for typed columns (`number`, `date`, `boolean`) so Excel can format them natively with `numFmt`. For `string` columns, `valueFormatter` is applied before writing.
342
+
343
+ ```tsx
344
+ const columns: GridColDef[] = [
345
+ {
346
+ field: 'salary',
347
+ type: 'number', // ← raw number written to Excel
348
+ valueFormatter: ({ value }) => `$${value.toLocaleString()}`, // used in CSV/print
349
+ },
350
+ ];
351
+
352
+ await exportToExcelAdvanced(rows, columns, {
353
+ columnStyles: {
354
+ salary: { numFmt: '$#,##0.00' }, // ← Excel formats the native number
355
+ },
356
+ });
357
+ ```
358
+
359
+ ---
360
+
361
+ ## Value Formatters
362
+
363
+ All export functions respect `valueFormatter` and `valueGetter`:
364
+
365
+ ```tsx
366
+ const columns: GridColDef[] = [
367
+ {
368
+ field: 'fullName',
369
+ valueGetter: ({ row }) => `${row.firstName} ${row.lastName}`,
370
+ },
371
+ {
372
+ field: 'salary',
373
+ valueFormatter: ({ value }) => `$${value.toLocaleString()}`,
374
+ },
375
+ ];
376
+ ```
377
+
378
+ > **Note:** In `exportToExcelAdvanced`, `valueFormatter` is only applied for `string`-typed columns. For `number`/`date`/`boolean` columns, raw values are passed to Excel and formatted via `columnStyles.numFmt`.
379
+
380
+ ---
381
+
382
+ ## Excluding Columns
383
+
384
+ You can exclude specific columns (e.g., action buttons or menus) from all export formats using the `exportable` property in the column definition. System columns are also automatically excluded.
385
+
386
+ | Method | Description |
387
+ |---|---|
388
+ | `exportable: false` | Set in `GridColDef` to manually exclude any column |
389
+ | `__check__` | Native checkbox column (auto-excluded) |
390
+ | `__actions__` | Common field for action buttons (auto-excluded) |
391
+ | `isSpacer: true` | Spacer columns (auto-excluded) |
392
+
393
+ ### Example
394
+ ```tsx
395
+ const columns: GridColDef[] = [
396
+ { field: 'id', headerName: 'ID' },
397
+ { field: 'name', headerName: 'Name' },
398
+ {
399
+ field: 'actions',
400
+ headerName: 'Actions',
401
+ exportable: false // This column won't appear in CSV/Excel/JSON/Print
402
+ },
403
+ ];
404
+ ```
405
+
406
+ ---
407
+
408
+ ## Performance Notes
409
+
410
+ | Format | 10k rows | 100k rows |
411
+ |---|---|---|
412
+ | CSV | ~50ms | ~500ms |
413
+ | JSON | ~80ms | ~800ms |
414
+ | Excel (basic) | ~200ms | ~2s |
415
+ | Excel (advanced) | ~300ms | ~3s |
416
+ | Print | Best with paginated data | — |
417
+
418
+ ---
419
+
420
+ ## Browser Compatibility
421
+
422
+ All export functions work in:
423
+ - ✅ Chrome/Edge 90+
424
+ - ✅ Firefox 88+
425
+ - ✅ Safari 14+
426
+
427
+ ---
428
+
429
+ ## See Also
430
+
431
+ - [Demo: Export Data](../demo/examples/ExportDemo.tsx)
432
+ - [Demo: Advanced Excel Export](../demo/examples/AdvancedExcelExportDemo.tsx)
433
+ - [Slots API Reference](./SLOTS_API.md)
434
+ - [Theming Guide](./THEMING.md)
@@ -0,0 +1,83 @@
1
+ # 🔍 Filtering System
2
+
3
+ OpenGridX provides a robust filtering system with support for both client-side and server-side operations.
4
+
5
+ ## 📑 Overview
6
+ - **Quick Filter**: Search across all columns simultaneously.
7
+ - **Column Filters**: Specific operators for different data types (string, number, date, etc.).
8
+ - **Multi-Filter Groups**: Support for `AND`/`OR` logic operators.
9
+ - **Server-Side Filtering**: Offload complex queries to your backend.
10
+
11
+ ---
12
+
13
+ ## 🛠️ Usage
14
+
15
+ ### Client-Side Filtering (Default)
16
+ Simply define your columns with `filterable: true` (which is the default).
17
+
18
+ ```tsx
19
+ <DataGrid
20
+ rows={rows}
21
+ columns={[
22
+ { field: 'name', headerName: 'Name' },
23
+ { field: 'age', headerName: 'Age', type: 'number' }
24
+ ]}
25
+ />
26
+ ```
27
+
28
+ ### Server-Side Filtering
29
+ Set `filterMode="server"` and handle the request in your `dataSource`.
30
+
31
+ ```tsx
32
+ <DataGrid
33
+ filterMode="server"
34
+ onFilterModelChange={(model) => console.log('Current Filters:', model)}
35
+ dataSource={{
36
+ getRows: async (params) => {
37
+ // params.filterModel contains the items and logic operators
38
+ return fetchRowsFromBackend(params);
39
+ }
40
+ }}
41
+ />
42
+ ```
43
+
44
+ ---
45
+
46
+ ## ⚙️ Filter Model API
47
+
48
+ The `GridFilterModel` describes the current state of filters.
49
+
50
+ ```typescript
51
+ interface GridFilterModel {
52
+ items: GridFilterItem[]; // Active filter items
53
+ logicOperator?: 'and' | 'or'; // How to combine items
54
+ quickFilterValues?: string[]; // Values for the global search
55
+ }
56
+
57
+ interface GridFilterItem {
58
+ field: string; // Column to filter
59
+ operator: GridFilterOperator;
60
+ value?: any; // Comparison value
61
+ }
62
+ ```
63
+
64
+ ### Supported Operators
65
+ | Type | Operators |
66
+ | :--- | :--- |
67
+ | **String** | `contains`, `equals`, `startsWith`, `endsWith`, `isEmpty`, `isNotEmpty` |
68
+ | **Number** | `=`, `!=`, `>`, `>=`, `<`, `<=`, `isEmpty`, `isNotEmpty` |
69
+ | **Date** | `is`, `not`, `after`, `before`, `isEmpty`, `isNotEmpty` |
70
+ | **Boolean** | `is` |
71
+
72
+ ---
73
+
74
+ ## 🎨 Customizing Filter Components
75
+ You can replace the default filter panel via the `slots` API:
76
+
77
+ ```tsx
78
+ <DataGrid
79
+ slots={{
80
+ filterPanel: MyCustomFilterPanel
81
+ }}
82
+ />
83
+ ```
@@ -0,0 +1,87 @@
1
+ # Infinite Scroll
2
+
3
+ The OpenGridX DataGrid supports infinite scrolling (lazy loading), allowing you to load large datasets incrementally as the user scrolls.
4
+
5
+ ## Concept
6
+
7
+ When infinite scroll is enabled, the grid:
8
+ 1. Disables client-side slicing (pagination in the UI).
9
+ 2. Uses `paginationModel` internally to track the current page and page size.
10
+ 3. Triggers `onRowsScrollEnd` when the user scrolls near the bottom of the grid, signaling that more data should be fetched.
11
+ 4. Data is typically **appended** to the existing rows, rather than replacing them.
12
+
13
+ ## Usage
14
+
15
+ To enable infinite scrolling:
16
+
17
+ 1. Set `pagination={false}` to disable UI pagination controls.
18
+ 2. Set `paginationMode="infinite"`.
19
+ 3. Implement `onRowsScrollEnd` to update your data fetching logic/state (e.g., increment page number).
20
+ 4. Ensure your `dataSource` manages the loaded rows correctly (usually appending).
21
+
22
+ ```tsx
23
+ import { DataGrid, GridDataSource } from '@opencorestack/opengridx';
24
+
25
+ // ... setup columns and mockApi ...
26
+
27
+ export default function InfiniteScrollDemo() {
28
+ const [paginationModel, setPaginationModel] = useState({
29
+ page: 0,
30
+ pageSize: 50
31
+ });
32
+ const [loading, setLoading] = useState(false);
33
+ const [allRows, setAllRows] = useState([]);
34
+
35
+ const dataSource: GridDataSource = useMemo(() => ({
36
+ getRows: async (params) => {
37
+ setLoading(true);
38
+ try {
39
+ // Fetch NEXT batch of rows from server
40
+ const response = await mockApi.getRows(params);
41
+
42
+ // CRITICAL: Append new rows to existing rows
43
+ // (Or ensure response.rows contains ONLY new rows and parent handles appending)
44
+ return response;
45
+ } finally {
46
+ setLoading(false);
47
+ }
48
+ }
49
+ }), []);
50
+
51
+ const handleScrollEnd = useCallback(() => {
52
+ if (!loading) {
53
+ // Increment page to fetch next batch
54
+ setPaginationModel(prev => ({
55
+ ...prev,
56
+ page: prev.page + 1
57
+ }));
58
+ }
59
+ }, [loading]);
60
+
61
+ return (
62
+ <DataGrid
63
+ rows={[]} // Rows managed by dataSource
64
+ columns={columns}
65
+ dataSource={dataSource}
66
+
67
+ // KEY PROPS FOR INFINITE SCROLL
68
+ pagination={false}
69
+ paginationMode="infinite"
70
+ sortingMode="server"
71
+
72
+ paginationModel={paginationModel}
73
+ onPaginationModelChange={setPaginationModel}
74
+
75
+ onRowsScrollEnd={handleScrollEnd}
76
+ />
77
+ );
78
+ }
79
+ ```
80
+
81
+ ## Implementation Details
82
+
83
+ * **`onRowsScrollEnd`**: Triggered when `scrollHeight - scrollTop - clientHeight < threshold` (default 100px).
84
+ * **Request Handling**: `useGridDataSource` includes logic to cancel stale requests if scrolling happens too quickly.
85
+ * **Appending vs Replacing**:
86
+ * In `infinite` mode, rows fetched for **new pages** are appended.
87
+ * Rows fetched due to **sorting/filtering changes** replace the entire dataset (resetting to page 0).
@@ -0,0 +1,65 @@
1
+ # 📱 List View
2
+
3
+ Switch from a multi-column grid to a single-column detailed list. Perfect for mobile responsiveness or card-based layouts.
4
+
5
+ ---
6
+
7
+ ## 🏗️ Usage
8
+
9
+ Enable List View by passing the `listView` prop. You must also provide a `listViewColumn` object which defines how each "Card" should be rendered.
10
+
11
+ ```tsx
12
+ const listColDef: GridListViewColDef<Employee> = {
13
+ field: 'card',
14
+ renderCell: (params) => <MyEmployeeCard row={params.row} />
15
+ };
16
+
17
+ <DataGrid
18
+ listView={true}
19
+ listViewColumn={listColDef}
20
+ rows={rows}
21
+ columns={columns} // Fallback columns for standard grid view
22
+ />
23
+ ```
24
+
25
+ ---
26
+
27
+ ## 🎨 Styling
28
+
29
+ When `listView` is active:
30
+ - **Header is Hidden**: The standard column header row disappears.
31
+ - **Full Width**: The row container becomes a vertical stack where the `renderCell` output takes 100% of the available width.
32
+ - **Card Containers**: Each row maintains its standard selection and hover behaviors, but visually acts as a card.
33
+
34
+ ### Custom Card Rendering
35
+ The `renderCell` function in `listViewColumn` receives all standard `GridRenderCellParams`, allowing you to build rich, complex UIs for each item.
36
+
37
+ ```tsx
38
+ function MyEmployeeCard({ row }) {
39
+ return (
40
+ <div className="employee-card">
41
+ <Avatar src={row.avatar} />
42
+ <div className="info">
43
+ <h3>{row.name}</h3>
44
+ <p>{row.role}</p>
45
+ </div>
46
+ <div className="status">{row.status}</div>
47
+ </div>
48
+ );
49
+ }
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 📱 Responsive Toggle
55
+
56
+ A common pattern is to toggle List View based on screen width:
57
+
58
+ ```tsx
59
+ const isMobile = window.innerWidth < 768;
60
+
61
+ <DataGrid
62
+ listView={isMobile}
63
+ // ...
64
+ />
65
+ ```