@cocoar/data-grid 0.1.1 → 0.2.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/README.md +553 -4
- package/fesm2022/cocoar-data-grid.mjs +466 -14
- package/fesm2022/cocoar-data-grid.mjs.map +1 -1
- package/package.json +5 -3
- package/types/cocoar-data-grid.d.ts +116 -6
package/README.md
CHANGED
|
@@ -1,7 +1,556 @@
|
|
|
1
|
-
# data-
|
|
1
|
+
# @cocoar/data-grid
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
AG Grid wrapper for the Cocoar Design System. Provides a fluent builder API, typed column factories, built-in cell renderers, and a design-token theme that supports light and dark mode out of the box.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- **Fluent Grid Builder** — configure columns, data, selection, sorting, filtering, and events through a chainable `CoarGridBuilder` API
|
|
8
|
+
- **Typed Column Factory** — create date, number, currency, boolean, tag, icon, and locale-aware date columns with a single method call
|
|
9
|
+
- **Built-in Cell Renderers** — `<coar-tag>`, `<coar-icon>`, and locale-aware date renderers available via factory methods
|
|
10
|
+
- **Cocoar Theme** — `ag-theme-cocoar` maps AG Grid CSS variables to `--coar-*` design tokens with automatic light/dark mode
|
|
11
|
+
- **Directive Binding** — `CoarDataGridDirective` binds a builder to `ag-grid-angular`, applies the theme class, and wires viewport events
|
|
12
|
+
- **Observable Data** — bind row data from an `Observable` with automatic loading state
|
|
13
|
+
- **Column State Persistence** — restore column widths, order, and visibility from saved state
|
|
14
|
+
- **External Filtering** — apply filters outside of AG Grid with observable triggers
|
|
15
|
+
- **Full-Row Editing** — enable row-level editing with a single builder call
|
|
16
|
+
- **Escape Hatch** — `option()` and `options()` let you set any AG Grid option directly
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add @cocoar/data-grid ag-grid-community ag-grid-angular
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Peer Dependencies
|
|
25
|
+
|
|
26
|
+
| Package | Version |
|
|
27
|
+
|---------|---------|
|
|
28
|
+
| `@angular/core` | `^21.0.0` |
|
|
29
|
+
| `@cocoar/localization` | `^0.1.0` |
|
|
30
|
+
| `@cocoar/ui` | `^0.1.0` |
|
|
31
|
+
| `ag-grid-angular` | `^35.0.0` |
|
|
32
|
+
| `ag-grid-community` | `^35.0.0` |
|
|
33
|
+
| `rxjs` | `^7.8.0` |
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
### 1. Register AG Grid Modules
|
|
38
|
+
|
|
39
|
+
In your component or `app.config.ts`:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { AllCommunityModule, ModuleRegistry } from 'ag-grid-community';
|
|
43
|
+
|
|
44
|
+
ModuleRegistry.registerModules([AllCommunityModule]);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Import Styles
|
|
48
|
+
|
|
49
|
+
Add the Cocoar AG Grid theme to your application styles:
|
|
50
|
+
|
|
51
|
+
```css
|
|
52
|
+
@import '@cocoar/data-grid/styles.css';
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. Use the Grid
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { Component } from '@angular/core';
|
|
59
|
+
import { AgGridAngular } from 'ag-grid-angular';
|
|
60
|
+
import { CoarGridBuilder, CoarDataGridDirective } from '@cocoar/data-grid';
|
|
61
|
+
|
|
62
|
+
interface User {
|
|
63
|
+
id: number;
|
|
64
|
+
name: string;
|
|
65
|
+
email: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@Component({
|
|
69
|
+
imports: [AgGridAngular, CoarDataGridDirective],
|
|
70
|
+
template: `
|
|
71
|
+
<ag-grid-angular
|
|
72
|
+
[coarDataGrid]="gridBuilder"
|
|
73
|
+
style="height: 400px;"
|
|
74
|
+
/>
|
|
75
|
+
`,
|
|
76
|
+
})
|
|
77
|
+
export class UsersGridComponent {
|
|
78
|
+
readonly gridBuilder = CoarGridBuilder.create<User>()
|
|
79
|
+
.columns([
|
|
80
|
+
col => col.field('name').header('Name').flex(1).sortable(),
|
|
81
|
+
col => col.field('email').header('Email').flex(1),
|
|
82
|
+
])
|
|
83
|
+
.rowData([
|
|
84
|
+
{ id: 1, name: 'Alice', email: 'alice@example.com' },
|
|
85
|
+
{ id: 2, name: 'Bob', email: 'bob@example.com' },
|
|
86
|
+
])
|
|
87
|
+
.rowId(params => String(params.data.id));
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
> The directive automatically applies the `ag-theme-cocoar` class and `display: flex` layout to the host element.
|
|
92
|
+
|
|
93
|
+
## Grid Builder API
|
|
94
|
+
|
|
95
|
+
`CoarGridBuilder` is the main entry point. Create an instance with `CoarGridBuilder.create<TData>()`.
|
|
96
|
+
|
|
97
|
+
### Properties
|
|
98
|
+
|
|
99
|
+
| Property | Type | Description |
|
|
100
|
+
|----------|------|-------------|
|
|
101
|
+
| `gridReady$` | `Observable<GridReadyEvent>` | Emits when the grid is ready |
|
|
102
|
+
| `api` | `GridApi \| undefined` | AG Grid API (available after grid ready) |
|
|
103
|
+
|
|
104
|
+
### Methods
|
|
105
|
+
|
|
106
|
+
#### Column Configuration
|
|
107
|
+
|
|
108
|
+
| Method | Description |
|
|
109
|
+
|--------|-------------|
|
|
110
|
+
| `columns(defs)` | Define columns using builders or factory functions |
|
|
111
|
+
| `defaultColDef(def)` | Set default column definition applied to all columns. Accepts an object or a builder function |
|
|
112
|
+
|
|
113
|
+
#### Data
|
|
114
|
+
|
|
115
|
+
| Method | Description |
|
|
116
|
+
|--------|-------------|
|
|
117
|
+
| `rowData(data)` | Set row data from a static array (or `null`) |
|
|
118
|
+
| `rowData$(data$)` | Set row data from an `Observable`. Emitting `null`/`undefined` shows the loading overlay |
|
|
119
|
+
| `rowId(fn)` | Set a `GetRowIdFunc` for immutable data updates |
|
|
120
|
+
|
|
121
|
+
#### Selection
|
|
122
|
+
|
|
123
|
+
| Method | Description |
|
|
124
|
+
|--------|-------------|
|
|
125
|
+
| `rowSelection(mode)` | Enable `'single'` or `'multiple'` row selection |
|
|
126
|
+
|
|
127
|
+
#### Row Styling
|
|
128
|
+
|
|
129
|
+
| Method | Description |
|
|
130
|
+
|--------|-------------|
|
|
131
|
+
| `rowClassRules(rules)` | Apply conditional CSS classes to rows |
|
|
132
|
+
| `rowClass(fn)` | Set a function that returns dynamic class name(s) per row |
|
|
133
|
+
|
|
134
|
+
#### Sorting
|
|
135
|
+
|
|
136
|
+
| Method | Description |
|
|
137
|
+
|--------|-------------|
|
|
138
|
+
| `defaultSort(field, direction)` | Set initial sort column and `'asc'` or `'desc'` direction |
|
|
139
|
+
| `sortFunction(fn)` | Set a custom post-sort function to reorder rows after AG Grid sorts |
|
|
140
|
+
| `updateSortAndFilterWhen(trigger$)` | Re-trigger sort and filter when the observable emits |
|
|
141
|
+
|
|
142
|
+
#### Column State
|
|
143
|
+
|
|
144
|
+
| Method | Description |
|
|
145
|
+
|--------|-------------|
|
|
146
|
+
| `columnState(state)` | Restore column widths, order, and visibility from an array or observable |
|
|
147
|
+
|
|
148
|
+
#### Tree / Group Data
|
|
149
|
+
|
|
150
|
+
| Method | Description |
|
|
151
|
+
|--------|-------------|
|
|
152
|
+
| `openRows(openRows$)` | Set which parent rows are expanded (observable of row IDs) |
|
|
153
|
+
|
|
154
|
+
#### Editing
|
|
155
|
+
|
|
156
|
+
| Method | Description |
|
|
157
|
+
|--------|-------------|
|
|
158
|
+
| `fullRowEdit()` | Enable full-row editing mode |
|
|
159
|
+
| `stopEditingWhenCellsLoseFocus()` | Stop editing when cells lose focus |
|
|
160
|
+
|
|
161
|
+
#### Resize
|
|
162
|
+
|
|
163
|
+
| Method | Description |
|
|
164
|
+
|--------|-------------|
|
|
165
|
+
| `shiftResizeMode()` | Enable shift-key column resize mode |
|
|
166
|
+
|
|
167
|
+
#### Animation
|
|
168
|
+
|
|
169
|
+
| Method | Description |
|
|
170
|
+
|--------|-------------|
|
|
171
|
+
| `animateRows()` | Enable row animation (enabled by default) |
|
|
172
|
+
|
|
173
|
+
#### Events
|
|
174
|
+
|
|
175
|
+
| Method | Description |
|
|
176
|
+
|--------|-------------|
|
|
177
|
+
| `onGridReady(handler)` | Handle grid ready event |
|
|
178
|
+
| `onRowClicked(handler)` | Handle row click |
|
|
179
|
+
| `onRowDoubleClicked(handler)` | Handle row double-click |
|
|
180
|
+
| `onCellClicked(handler)` | Handle cell click |
|
|
181
|
+
| `onCellDoubleClicked(handler)` | Handle cell double-click |
|
|
182
|
+
| `onCellContextMenu(handler)` | Handle cell right-click (Ctrl+click passes through to the browser) |
|
|
183
|
+
| `onViewportClick(handler)` | Handle click on empty grid area (wired by directive) |
|
|
184
|
+
| `onViewportContextMenu(handler)` | Handle right-click on empty grid area (wired by directive) |
|
|
185
|
+
| `onGridSizeChanged(handler)` | Handle grid size change |
|
|
186
|
+
|
|
187
|
+
#### External Filtering
|
|
188
|
+
|
|
189
|
+
| Method | Description |
|
|
190
|
+
|--------|-------------|
|
|
191
|
+
| `externalFilter(doesFilterPass, isFilterPresent?)` | Set an external filter function |
|
|
192
|
+
| `updateExternalFilterWhen(trigger$)` | Re-trigger the external filter when the observable emits |
|
|
193
|
+
|
|
194
|
+
#### Escape Hatch
|
|
195
|
+
|
|
196
|
+
| Method | Description |
|
|
197
|
+
|--------|-------------|
|
|
198
|
+
| `option(key, value)` | Set any single `GridOptions` property |
|
|
199
|
+
| `options(opts)` | Merge a partial `GridOptions` object |
|
|
200
|
+
|
|
201
|
+
## Column Builder API
|
|
202
|
+
|
|
203
|
+
`CoarGridColumnBuilder` configures individual columns with a fluent API. You rarely instantiate it directly — it is provided by the factory function in `columns()`.
|
|
204
|
+
|
|
205
|
+
| Method | Description |
|
|
206
|
+
|--------|-------------|
|
|
207
|
+
| `field(name)` | Set the data field name |
|
|
208
|
+
| `header(text)` | Set the column header text |
|
|
209
|
+
| `headerTooltip(text)` | Set header tooltip |
|
|
210
|
+
| `width(px, minWidth?, maxWidth?)` | Set width in pixels with optional min/max |
|
|
211
|
+
| `fixedWidth(px)` | Set width, minWidth, and maxWidth to the same value |
|
|
212
|
+
| `minWidth(px)` | Set minimum width |
|
|
213
|
+
| `maxWidth(px)` | Set maximum width |
|
|
214
|
+
| `flex(n)` | Set flex grow factor (default: `1`) |
|
|
215
|
+
| `sortable()` | Enable sorting |
|
|
216
|
+
| `resizable()` | Enable resizing (enabled by default) |
|
|
217
|
+
| `hidden()` | Hide the column |
|
|
218
|
+
| `pinned(side)` | Pin to `'left'`, `'right'`, or `null` |
|
|
219
|
+
| `lockPosition(value?)` | Lock column position |
|
|
220
|
+
| `cellRenderer(component, params?)` | Set a custom cell renderer Angular component |
|
|
221
|
+
| `cellRendererParams(params)` | Set cell renderer parameters |
|
|
222
|
+
| `cellRendererConfig(component, config)` | Set cell renderer with a `config` object |
|
|
223
|
+
| `valueFormatter(fn)` | Format the displayed value |
|
|
224
|
+
| `valueGetter(fn)` | Transform data before display |
|
|
225
|
+
| `cellClass(value)` | Set CSS class (string, array, or function) |
|
|
226
|
+
| `cellStyle(value)` | Set CSS style (object or function) |
|
|
227
|
+
| `classRule(className, condition)` | Add a conditional CSS class rule |
|
|
228
|
+
| `tooltip(value?)` | Show tooltip — field value by default, or a string/function |
|
|
229
|
+
| `onCellDoubleClicked(handler)` | Handle cell double-click |
|
|
230
|
+
| `filter(value?)` | Enable filtering (boolean or filter type string) |
|
|
231
|
+
| `filterParams(params)` | Set filter parameters |
|
|
232
|
+
| `quickFilter(fn)` | Set quick-filter text extractor, or `false` to exclude |
|
|
233
|
+
| `comparator(fn)` | Set a custom sort comparator |
|
|
234
|
+
| `rowDrag(value?)` | Enable row drag on this column |
|
|
235
|
+
| `option(key, value)` | Set any single `ColDef` property |
|
|
236
|
+
| `customize(fn)` | Apply custom modifications to the `ColDef` |
|
|
237
|
+
| `build()` | Build and return the AG Grid `ColDef` |
|
|
238
|
+
|
|
239
|
+
## Column Factory Methods
|
|
240
|
+
|
|
241
|
+
When you pass a function to `columns()`, it receives a `CoarGridColumnFactory<TData>`. The factory provides shorthand methods for common column types.
|
|
242
|
+
|
|
243
|
+
### `field(fieldName)`
|
|
244
|
+
|
|
245
|
+
Creates a plain column builder — identical to `new CoarGridColumnBuilder(fieldName)`.
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
col => col.field('name').header('Name').flex(1).sortable()
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### `date(fieldName, format?)`
|
|
252
|
+
|
|
253
|
+
Creates a date column with a `valueFormatter`. The `format` parameter accepts:
|
|
254
|
+
|
|
255
|
+
| Value | Output |
|
|
256
|
+
|-------|--------|
|
|
257
|
+
| `'short'` (default) | `date.toLocaleDateString()` |
|
|
258
|
+
| `'long'` | Full date with month name |
|
|
259
|
+
| `'datetime'` | `date.toLocaleString()` |
|
|
260
|
+
| `Intl.DateTimeFormatOptions` | Custom Intl formatting |
|
|
261
|
+
| `(date: Date) => string` | Custom formatter function |
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
col => col.date('createdAt', 'long').header('Created').width(180)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### `number(fieldName, decimals?)`
|
|
268
|
+
|
|
269
|
+
Creates a right-aligned number column formatted with `toLocaleString`. Default `decimals` is `0`.
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
col => col.number('score', 2).header('Score').width(100)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### `currency(fieldName, currency?)`
|
|
276
|
+
|
|
277
|
+
Creates a right-aligned currency column. Default currency is `'USD'`.
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
col => col.currency('price', 'EUR').header('Price').width(120)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### `boolean(fieldName, options?)`
|
|
284
|
+
|
|
285
|
+
Creates a column that displays `'Yes'`/`'No'` (or custom values).
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
col => col.boolean('active', { trueValue: 'Active', falseValue: 'Inactive' }).header('Status')
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### `tag(fieldName, config?)`
|
|
292
|
+
|
|
293
|
+
Creates a column that renders values as `<coar-tag>` elements. Sortable by default.
|
|
294
|
+
|
|
295
|
+
Supports string values (split by separator), arrays, and object arrays.
|
|
296
|
+
|
|
297
|
+
**`TagCellRendererConfig`:**
|
|
298
|
+
|
|
299
|
+
| Property | Type | Default | Description |
|
|
300
|
+
|----------|------|---------|-------------|
|
|
301
|
+
| `separator` | `string` | `','` | Delimiter to split string values |
|
|
302
|
+
| `variant` | `TagVariant` | — | Default variant for all tags |
|
|
303
|
+
| `variantMap` | `Record<string, TagVariant>` | — | Map tag values to variants |
|
|
304
|
+
| `size` | `'s' \| 'm' \| 'l'` | `'s'` | Tag size |
|
|
305
|
+
| `i18nPrefix` | `string` | — | Prefix for i18n translation keys |
|
|
306
|
+
| `labelProperty` | `string` | — | Property name when values are objects |
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
col => col.tag('roles', {
|
|
310
|
+
separator: ',',
|
|
311
|
+
size: 's',
|
|
312
|
+
variantMap: { admin: 'primary', editor: 'info', viewer: 'neutral' },
|
|
313
|
+
})
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### `icon(fieldName, config?)`
|
|
317
|
+
|
|
318
|
+
Creates a column that renders the cell value as a `<coar-icon>`.
|
|
319
|
+
|
|
320
|
+
**`IconCellRendererConfig`:**
|
|
321
|
+
|
|
322
|
+
| Property | Type | Default | Description |
|
|
323
|
+
|----------|------|---------|-------------|
|
|
324
|
+
| `size` | `CoarIconSize` | `'s'` | Icon size (`'xs'`, `'s'`, `'m'`, `'l'`, `'xl'`) |
|
|
325
|
+
| `source` | `string` | — | Icon source registry key |
|
|
326
|
+
| `color` | `string` | `'inherit'` | CSS color value |
|
|
327
|
+
| `onClick` | `(params) => void` | — | Click handler (makes the icon clickable) |
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
col => col.icon('fileType', { size: 'm', color: 'var(--coar-color-primary)' })
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### `localDate(fieldName, config?)`
|
|
334
|
+
|
|
335
|
+
Creates a date column that renders via `CoarDatePipe` from `@cocoar/localization` for full locale integration. Sortable by default.
|
|
336
|
+
|
|
337
|
+
**`DateCellRendererConfig`:**
|
|
338
|
+
|
|
339
|
+
| Property | Type | Default | Description |
|
|
340
|
+
|----------|------|---------|-------------|
|
|
341
|
+
| `showSeconds` | `boolean` | — | Include seconds in time display |
|
|
342
|
+
| `customFormat` | `string` | — | Custom Angular date format string |
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
col => col.localDate('updatedAt', { showSeconds: false }).header('Updated')
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Directive
|
|
349
|
+
|
|
350
|
+
`CoarDataGridDirective` connects a `CoarGridBuilder` to an `ag-grid-angular` instance.
|
|
351
|
+
|
|
352
|
+
**Selector:** `ag-grid-angular[coarDataGrid]`
|
|
353
|
+
**Export:** `coarDataGrid`
|
|
354
|
+
|
|
355
|
+
**Host bindings applied automatically:**
|
|
356
|
+
- CSS class: `ag-theme-cocoar`
|
|
357
|
+
- Style: `display: flex; flex-direction: column; flex-grow: 1`
|
|
358
|
+
|
|
359
|
+
The directive also forwards viewport click and context-menu events from the grid's empty area to the builder's `onViewportClick` / `onViewportContextMenu` handlers.
|
|
360
|
+
|
|
361
|
+
```html
|
|
362
|
+
<ag-grid-angular
|
|
363
|
+
[coarDataGrid]="gridBuilder"
|
|
364
|
+
style="height: 500px;"
|
|
365
|
+
/>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Theming
|
|
369
|
+
|
|
370
|
+
### CSS Theme
|
|
371
|
+
|
|
372
|
+
Import the theme CSS in your application styles:
|
|
373
|
+
|
|
374
|
+
```css
|
|
375
|
+
@import '@cocoar/data-grid/styles.css';
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
The `ag-theme-cocoar` class maps AG Grid CSS variables to Cocoar design tokens. Light mode is the default; dark mode activates when a `.dark-mode` class is present on the grid or a parent element.
|
|
379
|
+
|
|
380
|
+
**Key CSS variable mappings:**
|
|
381
|
+
|
|
382
|
+
| AG Grid Variable | Cocoar Token | Purpose |
|
|
383
|
+
|-----------------|-------------|---------|
|
|
384
|
+
| `--ag-background-color` | `--coar-background-neutral-primary` | Grid background |
|
|
385
|
+
| `--ag-header-background-color` | `--coar-background-neutral-secondary` | Header background |
|
|
386
|
+
| `--ag-row-hover-color` | `--coar-background-neutral-tertiary` | Row hover |
|
|
387
|
+
| `--ag-selected-row-background-color` | `--coar-background-accent-tertiary` | Selected row |
|
|
388
|
+
| `--ag-border-color` | `--coar-border-neutral-tertiary` | Borders |
|
|
389
|
+
| `--ag-foreground-color` | `--coar-text-neutral-primary` | Text |
|
|
390
|
+
| `--ag-header-foreground-color` | `--coar-text-neutral-secondary` | Header text |
|
|
391
|
+
| `--ag-font-family` | `--coar-font-family-body` | Typography |
|
|
392
|
+
| `--ag-checkbox-checked-color` | `--coar-background-accent-primary` | Checkbox |
|
|
393
|
+
|
|
394
|
+
**Utility CSS classes** available inside `ag-theme-cocoar`:
|
|
395
|
+
- `.clickable` — pointer cursor with accent color
|
|
396
|
+
- `.text-right` — right-aligned cell content
|
|
397
|
+
- `.text-center` — center-aligned cell content
|
|
398
|
+
|
|
399
|
+
### JavaScript Theme
|
|
400
|
+
|
|
401
|
+
The library also exports a JavaScript theme for AG Grid's v33+ theming API (based on `themeQuartz`):
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
import { cocoarTheme, createCocoarTheme } from '@cocoar/data-grid';
|
|
405
|
+
|
|
406
|
+
// Use the pre-configured instance (applied by the builder automatically)
|
|
407
|
+
const theme = cocoarTheme;
|
|
408
|
+
|
|
409
|
+
// Or create a customized instance
|
|
410
|
+
const custom = createCocoarTheme();
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
The builder applies `cocoarTheme` by default — you only need this export if you use AG Grid directly without the builder.
|
|
414
|
+
|
|
415
|
+
## Examples
|
|
416
|
+
|
|
417
|
+
### Row Selection
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
const grid = CoarGridBuilder.create<User>()
|
|
421
|
+
.columns([
|
|
422
|
+
col => col.field('name').header('Name').flex(1),
|
|
423
|
+
col => col.field('email').header('Email').flex(1),
|
|
424
|
+
])
|
|
425
|
+
.rowData(users)
|
|
426
|
+
.rowSelection('single')
|
|
427
|
+
.onRowClicked(event => {
|
|
428
|
+
console.log('Selected:', event.data);
|
|
429
|
+
});
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Conditional Row and Cell Styling
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
const grid = CoarGridBuilder.create<Task>()
|
|
436
|
+
.columns([
|
|
437
|
+
col => col.field('title').header('Title').flex(1),
|
|
438
|
+
col => col.field('priority').header('Priority').width(100)
|
|
439
|
+
.classRule('high-priority', params => params.value === 'high')
|
|
440
|
+
.cellStyle(params =>
|
|
441
|
+
params.value === 'high' ? { fontWeight: '600' } : null
|
|
442
|
+
),
|
|
443
|
+
])
|
|
444
|
+
.rowData(tasks)
|
|
445
|
+
.rowClassRules({
|
|
446
|
+
'overdue': params => params.data?.dueDate < new Date(),
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Typed Columns
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
const grid = CoarGridBuilder.create<Invoice>()
|
|
454
|
+
.columns([
|
|
455
|
+
col => col.field('number').header('#').fixedWidth(80),
|
|
456
|
+
col => col.date('issuedAt', 'long').header('Issued').width(180),
|
|
457
|
+
col => col.number('quantity', 0).header('Qty').width(80),
|
|
458
|
+
col => col.currency('total', 'EUR').header('Total').width(120),
|
|
459
|
+
col => col.boolean('paid').header('Paid').width(80),
|
|
460
|
+
])
|
|
461
|
+
.rowData(invoices);
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Tag and Icon Cell Renderers
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
const grid = CoarGridBuilder.create<User>()
|
|
468
|
+
.columns([
|
|
469
|
+
col => col.field('name').header('Name').flex(1),
|
|
470
|
+
col => col.tag('roles', {
|
|
471
|
+
variantMap: { admin: 'primary', editor: 'info', viewer: 'neutral' },
|
|
472
|
+
size: 's',
|
|
473
|
+
}).header('Roles').flex(1),
|
|
474
|
+
col => col.icon('status', {
|
|
475
|
+
size: 's',
|
|
476
|
+
onClick: params => alert(`Clicked ${params.data.name}`),
|
|
477
|
+
}).header('').fixedWidth(50),
|
|
478
|
+
])
|
|
479
|
+
.rowData(users);
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Observable Data Binding
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
readonly users$ = inject(UserService).getUsers();
|
|
486
|
+
|
|
487
|
+
readonly grid = CoarGridBuilder.create<User>()
|
|
488
|
+
.columns([
|
|
489
|
+
col => col.field('name').header('Name').flex(1),
|
|
490
|
+
col => col.field('email').header('Email').flex(1),
|
|
491
|
+
])
|
|
492
|
+
.rowData$(this.users$)
|
|
493
|
+
.rowId(params => String(params.data.id));
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Sorting and Custom Comparators
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
const grid = CoarGridBuilder.create<Item>()
|
|
500
|
+
.columns([
|
|
501
|
+
col => col.field('name').header('Name').flex(1).sortable()
|
|
502
|
+
.comparator((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' })),
|
|
503
|
+
col => col.field('priority').header('Priority').width(120).sortable()
|
|
504
|
+
.comparator((a, b) => priorityOrder[a] - priorityOrder[b]),
|
|
505
|
+
])
|
|
506
|
+
.rowData(items)
|
|
507
|
+
.defaultSort('priority', 'asc');
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Context Menu Integration
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
const grid = CoarGridBuilder.create<File>()
|
|
514
|
+
.columns([...])
|
|
515
|
+
.rowData(files)
|
|
516
|
+
.onCellContextMenu(event => {
|
|
517
|
+
const mouseEvent = event.event as MouseEvent;
|
|
518
|
+
openContextMenu(mouseEvent, event.data);
|
|
519
|
+
})
|
|
520
|
+
.onViewportContextMenu(($event, api) => {
|
|
521
|
+
openBackgroundMenu($event);
|
|
522
|
+
});
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Full-Row Editing
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
const grid = CoarGridBuilder.create<Record>()
|
|
529
|
+
.columns([
|
|
530
|
+
col => col.field('name').header('Name').flex(1).option('editable', true),
|
|
531
|
+
col => col.field('value').header('Value').flex(1).option('editable', true),
|
|
532
|
+
])
|
|
533
|
+
.rowData(records)
|
|
534
|
+
.fullRowEdit()
|
|
535
|
+
.stopEditingWhenCellsLoseFocus();
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### External Filtering
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
readonly searchTerm = signal('');
|
|
542
|
+
|
|
543
|
+
readonly grid = CoarGridBuilder.create<Item>()
|
|
544
|
+
.columns([...])
|
|
545
|
+
.rowData(items)
|
|
546
|
+
.externalFilter(node => {
|
|
547
|
+
const term = this.searchTerm().toLowerCase();
|
|
548
|
+
if (!term) return true;
|
|
549
|
+
return node.data.name.toLowerCase().includes(term);
|
|
550
|
+
})
|
|
551
|
+
.updateExternalFilterWhen(toObservable(this.searchTerm));
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
## License
|
|
555
|
+
|
|
556
|
+
Apache-2.0
|