@object-ui/plugin-aggrid 0.4.0

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,28 @@
1
+ # @object-ui/plugin-aggrid
2
+
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **Cell & Row Editing**: Added inline editing support with `editable` prop and `singleClickEdit` option
8
+ - **CSV Export**: Built-in export functionality with configurable options
9
+ - **Event Callbacks**: Support for `onCellClicked`, `onRowClicked`, `onSelectionChanged`, `onCellValueChanged`, and `onExport` callbacks
10
+ - **Status Bar**: Display aggregations (count, sum, avg, min, max) at the bottom of the grid
11
+ - **Column Configuration**: Global column settings with `columnConfig` for resizable, sortable, and filterable columns
12
+ - **Range Selection**: Enable Excel-like range selection with `enableRangeSelection`
13
+ - **Context Menu**: Customizable right-click context menu with built-in and custom actions
14
+ - **Enhanced TypeScript Types**: Added `AgGridCallbacks`, `ExportConfig`, `StatusBarConfig`, `ColumnConfig`, and `ContextMenuConfig` types
15
+ - **Improved API**: Extended schema with editing, export, status bar, column configuration, and context menu
16
+
17
+ ## 0.3.0
18
+
19
+ ### Minor Changes
20
+
21
+ - Initial release of AG Grid plugin
22
+ - Support for AG Grid Community Edition
23
+ - Lazy loading with React.Suspense
24
+ - Multiple theme support (Quartz, Alpine, Balham, Material)
25
+ - Full pagination, sorting, and filtering support
26
+ - TypeScript support with type definitions
27
+ - Automatic component registration
28
+ - Comprehensive test coverage
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ObjectQL
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,504 @@
1
+ # Plugin AgGrid - Lazy-Loaded AG Grid Data Grid
2
+
3
+ A lazy-loaded data grid component for Object UI based on AG Grid Community Edition.
4
+
5
+ ## Features
6
+
7
+ - **Internal Lazy Loading**: AG Grid libraries are loaded on-demand using `React.lazy()` and `Suspense`
8
+ - **Zero Configuration**: Just import the package and use `type: 'aggrid'` in your schema
9
+ - **Automatic Registration**: Components auto-register with the ComponentRegistry
10
+ - **Skeleton Loading**: Shows a skeleton while AG Grid loads
11
+ - **Full AG Grid Features**: Sorting, filtering, pagination, cell rendering, and more
12
+ - **Cell & Row Editing**: Inline editing using AG Grid's built-in editors
13
+ - **CSV Export**: Built-in data export functionality
14
+ - **Event Callbacks**: Handle cell clicks, selection changes, and value updates
15
+ - **Status Bar**: Display aggregations (count, sum, avg, min, max)
16
+ - **Context Menu**: Customizable right-click menu with built-in and custom actions
17
+ - **Column Configuration**: Global settings for resizable, sortable, and filterable columns
18
+ - **Range Selection**: Excel-like range selection support
19
+ - **Multiple Themes**: Support for Quartz, Alpine, Balham, and Material themes
20
+ - **Customizable**: Full access to AG Grid's GridOptions for advanced configuration
21
+
22
+ ## AG Grid Community vs Enterprise
23
+
24
+ This plugin uses **AG Grid Community Edition** which is free and open source. Most features (sorting, filtering, editing, CSV export, basic context menu) work with the Community edition. Some advanced features like integrated charting may require AG Grid Enterprise (commercial license). See [AG Grid Pricing](https://www.ag-grid.com/license-pricing/) for details.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pnpm add @object-ui/plugin-aggrid ag-grid-community ag-grid-react
30
+ ```
31
+
32
+ Note: `ag-grid-community` and `ag-grid-react` are peer dependencies and must be installed separately.
33
+
34
+ ## Usage
35
+
36
+ ### Automatic Registration (Side-Effect Import)
37
+
38
+ ```typescript
39
+ // In your app entry point (e.g., App.tsx or main.tsx)
40
+ import '@object-ui/plugin-aggrid';
41
+
42
+ // Now you can use aggrid type in your schemas
43
+ const schema = {
44
+ type: 'aggrid',
45
+ rowData: [
46
+ { make: 'Tesla', model: 'Model Y', price: 64950 },
47
+ { make: 'Ford', model: 'F-Series', price: 33850 },
48
+ { make: 'Toyota', model: 'Corolla', price: 29600 }
49
+ ],
50
+ columnDefs: [
51
+ { field: 'make', headerName: 'Make', sortable: true, filter: true },
52
+ { field: 'model', headerName: 'Model', sortable: true, filter: true },
53
+ { field: 'price', headerName: 'Price', sortable: true, filter: 'number' }
54
+ ],
55
+ pagination: true,
56
+ paginationPageSize: 10,
57
+ theme: 'quartz',
58
+ height: 500
59
+ };
60
+ ```
61
+
62
+ ### Manual Integration
63
+
64
+ ```typescript
65
+ import { aggridComponents } from '@object-ui/plugin-aggrid';
66
+ import { ComponentRegistry } from '@object-ui/core';
67
+
68
+ // Manually register if needed
69
+ Object.entries(aggridComponents).forEach(([type, component]) => {
70
+ ComponentRegistry.register(type, component);
71
+ });
72
+ ```
73
+
74
+ ### TypeScript Support
75
+
76
+ The plugin exports TypeScript types for full type safety:
77
+
78
+ ```typescript
79
+ import type {
80
+ AgGridSchema,
81
+ SimpleColumnDef,
82
+ AgGridCallbacks,
83
+ ExportConfig,
84
+ StatusBarConfig,
85
+ ColumnConfig,
86
+ ContextMenuConfig
87
+ } from '@object-ui/plugin-aggrid';
88
+
89
+ const schema: AgGridSchema = {
90
+ type: 'aggrid',
91
+ rowData: [
92
+ { make: 'Tesla', model: 'Model Y', price: 64950 }
93
+ ],
94
+ columnDefs: [
95
+ { field: 'make', headerName: 'Make', sortable: true, filter: true }
96
+ ],
97
+ pagination: true,
98
+ theme: 'quartz',
99
+ editable: true,
100
+ exportConfig: {
101
+ enabled: true,
102
+ fileName: 'cars.csv'
103
+ },
104
+ columnConfig: {
105
+ resizable: true,
106
+ sortable: true,
107
+ filterable: true
108
+ },
109
+ contextMenu: {
110
+ enabled: true,
111
+ items: ['copy', 'export']
112
+ },
113
+ callbacks: {
114
+ onCellValueChanged: (event) => {
115
+ console.log('Changed:', event);
116
+ }
117
+ }
118
+ };
119
+ ```
120
+
121
+ ## Schema API
122
+
123
+ ```typescript
124
+ {
125
+ type: 'aggrid',
126
+
127
+ // Data
128
+ rowData?: any[], // Grid data (required)
129
+ columnDefs?: ColDef[], // Column definitions (required)
130
+
131
+ // Display
132
+ pagination?: boolean, // Enable pagination (default: false)
133
+ paginationPageSize?: number, // Rows per page (default: 10)
134
+ theme?: 'quartz' | 'alpine' | 'balham' | 'material', // Grid theme (default: 'quartz')
135
+ height?: number | string, // Grid height (default: 500)
136
+ rowSelection?: 'single' | 'multiple', // Row selection mode
137
+ domLayout?: 'normal' | 'autoHeight' | 'print', // Layout mode
138
+ animateRows?: boolean, // Animate row changes (default: true)
139
+
140
+ // Editing
141
+ editable?: boolean, // Enable cell editing (default: false)
142
+ editType?: 'fullRow', // Row editing mode
143
+ singleClickEdit?: boolean, // Start edit on single click (default: false)
144
+ stopEditingWhenCellsLoseFocus?: boolean, // Stop editing on blur (default: true)
145
+
146
+ // Export
147
+ exportConfig?: {
148
+ enabled?: boolean, // Show export button (default: false)
149
+ fileName?: string, // Export filename (default: 'export.csv')
150
+ skipColumnHeaders?: boolean, // Skip column headers in export (default: false)
151
+ onlySelected?: boolean, // Export only selected rows (default: false)
152
+ allColumns?: boolean // Export all columns (default: false)
153
+ },
154
+
155
+ // Status Bar
156
+ statusBar?: {
157
+ enabled?: boolean, // Show status bar (default: false)
158
+ aggregations?: ('sum' | 'avg' | 'count' | 'min' | 'max')[] // Aggregations to show
159
+ },
160
+
161
+ // Event Callbacks
162
+ callbacks?: {
163
+ onCellClicked?: (event) => void, // Cell click handler
164
+ onRowClicked?: (event) => void, // Row click handler
165
+ onSelectionChanged?: (event) => void, // Selection change handler
166
+ onCellValueChanged?: (event) => void, // Cell value change handler
167
+ onExport?: (data, format) => void, // Export handler (CSV only)
168
+ onContextMenuAction?: (action, rowData) => void // Context menu action handler
169
+ },
170
+
171
+ // Column Configuration
172
+ columnConfig?: {
173
+ resizable?: boolean, // Make all columns resizable
174
+ sortable?: boolean, // Make all columns sortable
175
+ filterable?: boolean, // Make all columns filterable
176
+ },
177
+ enableRangeSelection?: boolean, // Enable Excel-like range selection (default: false)
178
+ enableCharts?: boolean, // Enable integrated charts (requires Enterprise, default: false)
179
+
180
+ // Context Menu
181
+ contextMenu?: {
182
+ enabled?: boolean, // Enable context menu (default: false)
183
+ items?: string[], // Menu items: 'copy', 'export', 'autoSizeAll', etc.
184
+ customItems?: Array<{ // Custom menu items
185
+ name: string,
186
+ action: string,
187
+ icon?: string,
188
+ disabled?: boolean
189
+ }>
190
+ },
191
+
192
+ // Advanced
193
+ gridOptions?: GridOptions, // Advanced AG Grid options
194
+ className?: string // Tailwind classes
195
+ }
196
+ ```
197
+
198
+ ## Column Definition Examples
199
+
200
+ ### Basic Column
201
+
202
+ ```typescript
203
+ {
204
+ field: 'name',
205
+ headerName: 'Name',
206
+ sortable: true,
207
+ filter: true
208
+ }
209
+ ```
210
+
211
+ ### Numeric Column with Formatter
212
+
213
+ ```typescript
214
+ {
215
+ field: 'price',
216
+ headerName: 'Price',
217
+ sortable: true,
218
+ filter: 'number',
219
+ valueFormatter: (params) => '$' + params.value.toLocaleString()
220
+ }
221
+ ```
222
+
223
+ ### Column with Custom Cell Renderer
224
+
225
+ ```typescript
226
+ {
227
+ field: 'status',
228
+ headerName: 'Status',
229
+ cellRenderer: (params) => {
230
+ return params.value === 'active'
231
+ ? '<span class="text-green-500">✓ Active</span>'
232
+ : '<span class="text-red-500">✗ Inactive</span>';
233
+ }
234
+ }
235
+ ```
236
+
237
+ ## Themes
238
+
239
+ AG Grid comes with four built-in themes:
240
+
241
+ - **Quartz** (default): Modern, clean design
242
+ - **Alpine**: Traditional data grid appearance
243
+ - **Balham**: Professional business look
244
+ - **Material**: Google Material Design inspired
245
+
246
+ ```typescript
247
+ const schema = {
248
+ type: 'aggrid',
249
+ theme: 'alpine', // or 'quartz', 'balham', 'material'
250
+ // ... other props
251
+ };
252
+ ```
253
+
254
+ ## Cell & Row Editing
255
+
256
+ Enable inline editing of cells:
257
+
258
+ ```typescript
259
+ const schema = {
260
+ type: 'aggrid',
261
+ rowData: [...],
262
+ columnDefs: [
263
+ { field: 'name', headerName: 'Name', editable: true },
264
+ { field: 'price', headerName: 'Price', editable: true },
265
+ { field: 'status', headerName: 'Status', editable: false }
266
+ ],
267
+ editable: true, // Enable editing globally
268
+ singleClickEdit: false, // Double-click to edit (default)
269
+ callbacks: {
270
+ onCellValueChanged: (event) => {
271
+ console.log('Cell changed:', event.data, event.colDef.field, event.newValue);
272
+ // Save to backend here
273
+ }
274
+ }
275
+ };
276
+ ```
277
+
278
+ ## CSV Export
279
+
280
+ Enable data export with a built-in button:
281
+
282
+ ```typescript
283
+ const schema = {
284
+ type: 'aggrid',
285
+ rowData: [...],
286
+ columnDefs: [...],
287
+ exportConfig: {
288
+ enabled: true, // Show export button
289
+ fileName: 'my-data.csv', // Custom filename
290
+ onlySelected: false, // Export all rows (or only selected)
291
+ allColumns: true // Export all columns
292
+ },
293
+ callbacks: {
294
+ onExport: (data, format) => {
295
+ console.log(`Exporting ${data.length} rows as ${format}`);
296
+ // Track export event or custom processing
297
+ }
298
+ }
299
+ };
300
+ ```
301
+
302
+ ## Status Bar & Aggregations
303
+
304
+ Display summary statistics at the bottom of the grid:
305
+
306
+ ```typescript
307
+ const schema = {
308
+ type: 'aggrid',
309
+ rowData: [...],
310
+ columnDefs: [...],
311
+ statusBar: {
312
+ enabled: true,
313
+ aggregations: ['count', 'sum', 'avg', 'min', 'max']
314
+ }
315
+ };
316
+ ```
317
+
318
+ ## Event Callbacks
319
+
320
+ Handle user interactions with the grid:
321
+
322
+ ```typescript
323
+ const schema = {
324
+ type: 'aggrid',
325
+ rowData: [...],
326
+ columnDefs: [...],
327
+ rowSelection: 'multiple',
328
+ callbacks: {
329
+ onRowClicked: (event) => {
330
+ console.log('Row clicked:', event.data);
331
+ },
332
+ onCellClicked: (event) => {
333
+ console.log('Cell clicked:', event.colDef.field, event.value);
334
+ },
335
+ onSelectionChanged: (event) => {
336
+ const selectedRows = event.api.getSelectedRows();
337
+ console.log('Selected rows:', selectedRows);
338
+ },
339
+ onCellValueChanged: (event) => {
340
+ console.log('Value changed from', event.oldValue, 'to', event.newValue);
341
+ // Save changes to backend
342
+ saveToBackend(event.data);
343
+ }
344
+ }
345
+ };
346
+ ```
347
+
348
+ ## Context Menu
349
+
350
+ Add a right-click context menu with custom actions:
351
+
352
+ ```typescript
353
+ const schema = {
354
+ type: 'aggrid',
355
+ rowData: [...],
356
+ columnDefs: [...],
357
+ contextMenu: {
358
+ enabled: true,
359
+ items: [
360
+ 'copy', // Copy selected cells
361
+ 'copyWithHeaders', // Copy with column headers
362
+ 'separator',
363
+ 'export', // Export to CSV
364
+ 'autoSizeAll', // Auto-size all columns
365
+ 'resetColumns' // Reset column state
366
+ ],
367
+ customItems: [
368
+ {
369
+ name: 'Delete Row',
370
+ action: 'delete',
371
+ disabled: false
372
+ },
373
+ {
374
+ name: 'View Details',
375
+ action: 'view'
376
+ }
377
+ ]
378
+ },
379
+ callbacks: {
380
+ onContextMenuAction: (action, rowData) => {
381
+ console.log(`Action: ${action}`, rowData);
382
+ // Handle custom menu actions
383
+ if (action === 'delete') {
384
+ deleteRow(rowData);
385
+ } else if (action === 'view') {
386
+ viewDetails(rowData);
387
+ }
388
+ }
389
+ }
390
+ };
391
+ ```
392
+
393
+ ## Column Configuration
394
+
395
+ Apply global settings to all columns:
396
+
397
+ ```typescript
398
+ const schema = {
399
+ type: 'aggrid',
400
+ rowData: [...],
401
+ columnDefs: [...],
402
+ columnConfig: {
403
+ resizable: true, // All columns resizable by default
404
+ sortable: true, // All columns sortable by default
405
+ filterable: true, // All columns filterable by default
406
+ },
407
+ enableRangeSelection: true // Excel-like range selection
408
+ };
409
+ ```
410
+
411
+ You can override these defaults on individual columns:
412
+
413
+ ```typescript
414
+ const schema = {
415
+ type: 'aggrid',
416
+ rowData: [...],
417
+ columnDefs: [
418
+ { field: 'id', headerName: 'ID', sortable: false }, // Override: not sortable
419
+ { field: 'name', headerName: 'Name' }, // Uses defaults
420
+ { field: 'email', headerName: 'Email' } // Uses defaults
421
+ ],
422
+ columnConfig: {
423
+ resizable: true,
424
+ sortable: true,
425
+ filterable: true
426
+ }
427
+ };
428
+ ```
429
+
430
+ ## Lazy Loading Architecture
431
+
432
+ The plugin uses a two-file pattern for optimal code splitting:
433
+
434
+ 1. **`AgGridImpl.tsx`**: Contains the actual AG Grid imports (heavy ~200-300 KB)
435
+ 2. **`index.tsx`**: Entry point with `React.lazy()` wrapper (light)
436
+
437
+ When bundled, Vite automatically creates separate chunks:
438
+ - `index.js` (~200 bytes) - The entry point
439
+ - `AgGridImpl-xxx.js` (~200-300 KB) - The lazy-loaded implementation
440
+
441
+ The AG Grid library is only downloaded when an `aggrid` component is actually rendered, not on initial page load.
442
+
443
+ ## Bundle Size Impact
444
+
445
+ By using lazy loading, the main application bundle stays lean:
446
+ - Without lazy loading: +200-300 KB on initial load
447
+ - With lazy loading: +0.19 KB on initial load, +200-300 KB only when grid is rendered
448
+
449
+ This results in significantly faster initial page loads for applications that don't use data grids on every page.
450
+
451
+ ## Advanced Usage
452
+
453
+ ### With GridOptions
454
+
455
+ ```typescript
456
+ const schema = {
457
+ type: 'aggrid',
458
+ rowData: [...],
459
+ columnDefs: [...],
460
+ gridOptions: {
461
+ suppressCellFocus: true,
462
+ enableCellTextSelection: true,
463
+ enableRangeSelection: true,
464
+ rowMultiSelectWithClick: true,
465
+ // Any AG Grid GridOptions property
466
+ }
467
+ };
468
+ ```
469
+
470
+ ### Auto Height Layout
471
+
472
+ ```typescript
473
+ const schema = {
474
+ type: 'aggrid',
475
+ rowData: [...],
476
+ columnDefs: [...],
477
+ domLayout: 'autoHeight', // Grid adjusts height to fit all rows
478
+ };
479
+ ```
480
+
481
+ ## Development
482
+
483
+ ```bash
484
+ # Build the plugin
485
+ pnpm build
486
+
487
+ # Run tests
488
+ pnpm test
489
+
490
+ # Type check
491
+ pnpm type-check
492
+
493
+ # The package will generate proper ESM and UMD builds with lazy loading preserved
494
+ ```
495
+
496
+ ## License
497
+
498
+ MIT
499
+
500
+ ## Resources
501
+
502
+ - [AG Grid Community Documentation](https://www.ag-grid.com/documentation/)
503
+ - [AG Grid Column Definitions](https://www.ag-grid.com/documentation/javascript/column-definitions/)
504
+ - [AG Grid Grid Options](https://www.ag-grid.com/documentation/javascript/grid-options/)