igniteui-cli 15.3.0 → 15.3.1-beta.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.
- package/package.json +7 -7
- package/templates/blazor/igb/projects/ai-config/files/skills/igniteui-blazor-grids/references/grid-migration.md +322 -0
- package/templates/react/igr-ts/projects/ai-config/files/skills/grid-lite-to-igr-grid-migration/SKILL.md +274 -0
- package/templates/react/igr-ts/projects/ai-config/files/skills/igniteui-react-generate-from-image-design/reference/gotchas.md +2 -2
- package/templates/webcomponents/igc-ts/projects/ai-config/files/skills/igniteui-wc-migrate-grid-lite-to-premium/SKILL.md +446 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "igniteui-cli",
|
|
3
|
-
"version": "15.3.
|
|
3
|
+
"version": "15.3.1-beta.1",
|
|
4
4
|
"description": "CLI tool for creating Ignite UI projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -66,9 +66,9 @@
|
|
|
66
66
|
"all": true
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@igniteui/angular-templates": "~
|
|
70
|
-
"@igniteui/cli-core": "~15.3.
|
|
71
|
-
"@igniteui/mcp-server": "~15.3.
|
|
69
|
+
"@igniteui/angular-templates": "~22.0.1531-beta.1",
|
|
70
|
+
"@igniteui/cli-core": "~15.3.1-beta.1",
|
|
71
|
+
"@igniteui/mcp-server": "~15.3.1-beta.1",
|
|
72
72
|
"@inquirer/prompts": "^7.9.0",
|
|
73
73
|
"chalk": "^5.3.0",
|
|
74
74
|
"glob": "^11.0.0",
|
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
"yargs": "^17.7.2"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@angular-devkit/core": "^
|
|
83
|
-
"@angular-devkit/schematics": "^
|
|
84
|
-
"@schematics/angular": "^
|
|
82
|
+
"@angular-devkit/core": "^22.0.0",
|
|
83
|
+
"@angular-devkit/schematics": "^22.0.0",
|
|
84
|
+
"@schematics/angular": "^22.0.0",
|
|
85
85
|
"@types/jasmine": "^5.1.4",
|
|
86
86
|
"@types/node": "^22.5.5",
|
|
87
87
|
"@types/yargs": "^17.0.33",
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Grid Migration - Grid Lite → Premium IgbGrid
|
|
2
|
+
|
|
3
|
+
> **Part of the [`igniteui-blazor-grids`](../SKILL.md) skill hub.**
|
|
4
|
+
> For `IgbGrid` setup and column configuration — see [`structure.md`](./structure.md).
|
|
5
|
+
> For specialized grid types including `IgbGridLite` — see [`types.md`](./types.md).
|
|
6
|
+
> For cell and row editing after migration — see [`editing.md`](./editing.md).
|
|
7
|
+
|
|
8
|
+
## Contents
|
|
9
|
+
|
|
10
|
+
- [When to Migrate from Grid Lite to IgbGrid](#when-to-migrate-from-grid-lite-to-igbgrid)
|
|
11
|
+
- [Setup](#setup)
|
|
12
|
+
- [Minimal Migration Example](#minimal-migration-example)
|
|
13
|
+
- [Component and API Changes](#component-and-api-changes)
|
|
14
|
+
- [Cell Templates](#cell-templates)
|
|
15
|
+
- [Header Templates](#header-templates)
|
|
16
|
+
- [Remote Data](#remote-data)
|
|
17
|
+
- [Programmatic Sort / Filter](#programmatic-sort--filter)
|
|
18
|
+
- [Common Enterprise Features](#common-enterprise-features)
|
|
19
|
+
- [Cleanup After Migration](#cleanup-after-migration)
|
|
20
|
+
- [Key Rules](#key-rules)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## When to Migrate from Grid Lite to IgbGrid
|
|
25
|
+
|
|
26
|
+
Migrate when you need any of the following features (not available in `IgbGridLite`):
|
|
27
|
+
|
|
28
|
+
| Feature | Grid Lite | Premium Grid (`IgbGrid`) |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| Cell editing | ✗ | ✓ `Editable` on column, `RowEditable` on grid |
|
|
31
|
+
| Batch editing (with undo) | ✗ | ✗ (not supported in Blazor) |
|
|
32
|
+
| Row adding / deleting | ✗ | ✓ `RowEditable` + `IgbActionStrip` |
|
|
33
|
+
| Row selection | ✗ | ✓ `RowSelection="GridSelectionMode.Single|Multiple"` |
|
|
34
|
+
| Cell selection | ✗ | ✓ `CellSelection` |
|
|
35
|
+
| Column selection | ✗ | ✓ `ColumnSelection` |
|
|
36
|
+
| Paging | ✗ | ✓ `IgbPaginator` child |
|
|
37
|
+
| GroupBy | ✗ | ✓ `GroupingExpressions` (IgbGrid only) |
|
|
38
|
+
| Column summaries | ✗ | ✓ `HasSummary` on `IgbColumn` |
|
|
39
|
+
| Column pinning | ✗ | ✓ `Pinned` on `IgbColumn` |
|
|
40
|
+
| Column moving | ✗ | ✓ `Moving="true"` on grid |
|
|
41
|
+
| Master-detail rows | ✗ | ✓ `IgbGrid` row expansion |
|
|
42
|
+
| Excel / CSV export (toolbar) | ✗ | ✓ `IgbGridToolbarExporter` |
|
|
43
|
+
| Column hiding toolbar | ✗ | ✓ `IgbGridToolbarHiding` |
|
|
44
|
+
| Column pinning toolbar | ✗ | ✓ `IgbGridToolbarPinning` |
|
|
45
|
+
| Advanced filtering UI | ✗ | ✓ `IgbGridToolbarAdvancedFiltering` |
|
|
46
|
+
| State persistence | ✗ | ✓ `IgbGridState` |
|
|
47
|
+
| Clipboard operations | ✗ | ✓ `ClipboardOptions` |
|
|
48
|
+
| Action strip | ✗ | ✓ `IgbActionStrip` |
|
|
49
|
+
| Row drag and drop | ✗ | ✓ `RowDraggable="true"` |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Setup
|
|
54
|
+
|
|
55
|
+
### 1. Replace the NuGet package registration
|
|
56
|
+
|
|
57
|
+
```csharp
|
|
58
|
+
// Remove:
|
|
59
|
+
builder.Services.AddIgniteUIBlazor(typeof(IgbGridLiteModule));
|
|
60
|
+
|
|
61
|
+
// Add:
|
|
62
|
+
builder.Services.AddIgniteUIBlazor(typeof(IgbGridModule));
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 2. Replace the CSS link in `index.html`
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<!-- Remove: -->
|
|
69
|
+
<link href="_content/IgniteUI.Blazor.GridLite/css/themes/light/bootstrap.css" rel="stylesheet" />
|
|
70
|
+
|
|
71
|
+
<!-- Add: -->
|
|
72
|
+
<link href="_content/IgniteUI.Blazor/themes/light/bootstrap.css" rel="stylesheet" />
|
|
73
|
+
<link href="_content/IgniteUI.Blazor/themes/grid/light/bootstrap.css" rel="stylesheet" />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3. Update `_Imports.razor`
|
|
77
|
+
|
|
78
|
+
`IgniteUI.Blazor.Controls` covers both `IgbGridLite` and `IgbGrid` — no change needed if already present.
|
|
79
|
+
|
|
80
|
+
```razor
|
|
81
|
+
@using IgniteUI.Blazor.Controls
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Minimal Migration Example
|
|
87
|
+
|
|
88
|
+
```razor
|
|
89
|
+
<!-- Before: -->
|
|
90
|
+
<IgbGridLite TItem="Product" Data="@products">
|
|
91
|
+
<IgbGridLiteColumn Field="Name" Header="Name" DataType="GridLiteColumnDataType.String" Sortable Filterable Resizable />
|
|
92
|
+
<IgbGridLiteColumn Field="Price" Header="Price" DataType="GridLiteColumnDataType.Number" />
|
|
93
|
+
</IgbGridLite>
|
|
94
|
+
|
|
95
|
+
<!-- After: -->
|
|
96
|
+
<IgbGrid @ref="grid" Data="@products" PrimaryKey="Id" AutoGenerate="false"
|
|
97
|
+
Width="100%" Height="600px" AllowFiltering="true">
|
|
98
|
+
<IgbColumn Field="Name" Header="Name" DataType="GridColumnDataType.String" Sortable="true" Filterable="true" Resizable="true" />
|
|
99
|
+
<IgbColumn Field="Price" Header="Price" DataType="GridColumnDataType.Number" Sortable="true" />
|
|
100
|
+
</IgbGrid>
|
|
101
|
+
|
|
102
|
+
@code {
|
|
103
|
+
private IgbGrid grid = default!;
|
|
104
|
+
private List<Product> products = new();
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Key additions vs Grid Lite:**
|
|
109
|
+
- `PrimaryKey` — required for editing, selection, and row-targeted APIs
|
|
110
|
+
- `Height` — required for row virtualization
|
|
111
|
+
- `AllowFiltering="true"` on the grid — enables the filter row UI; `Filterable="true"` on a column opts that column in
|
|
112
|
+
- `@ref` — required for programmatic API access
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Component and API Changes
|
|
117
|
+
|
|
118
|
+
| Grid Lite | Premium Grid |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `IgbGridLite` | `IgbGrid` |
|
|
121
|
+
| `IgbGridLiteColumn` | `IgbColumn` |
|
|
122
|
+
| `GridLiteColumnDataType` | `GridColumnDataType` |
|
|
123
|
+
| `IgbGridLiteModule` | `IgbGridModule` |
|
|
124
|
+
| `IgbGridLiteSortingExpression` | `IgbSortingExpression` |
|
|
125
|
+
| `IgbGridLiteFilterExpression` | `IgbFilteringExpression` |
|
|
126
|
+
| Column `Key` (in sort/filter objects) | Column `FieldName` (in sort/filter objects) |
|
|
127
|
+
| `TItem` generic parameter | `TItem` (unchanged) |
|
|
128
|
+
| No `PrimaryKey` | `PrimaryKey` required for most features |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Cell Templates
|
|
133
|
+
|
|
134
|
+
Grid Lite has no cell templates. In `IgbGrid`, use the `BodyTemplate` render fragment on `IgbColumn`:
|
|
135
|
+
|
|
136
|
+
```razor
|
|
137
|
+
<IgbColumn Field="Status" Header="Status">
|
|
138
|
+
<BodyTemplate>
|
|
139
|
+
@{
|
|
140
|
+
var cell = (IgbCellTemplateContext)context;
|
|
141
|
+
var status = cell.Cell.Value?.ToString();
|
|
142
|
+
}
|
|
143
|
+
<span style="color: @(status == "Active" ? "green" : "red")">@status</span>
|
|
144
|
+
</BodyTemplate>
|
|
145
|
+
</IgbColumn>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
| | Grid Lite | Premium Grid |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| Cell template | Not supported | `BodyTemplate` render fragment |
|
|
151
|
+
| Cell value | — | `((IgbCellTemplateContext)context).Cell.Value` |
|
|
152
|
+
| Row data | — | `((IgbCellTemplateContext)context).Cell.Row.Data` |
|
|
153
|
+
| Edit template | — | `InlineEditorTemplate` render fragment |
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Header Templates
|
|
158
|
+
|
|
159
|
+
Grid Lite has no header templates. In `IgbGrid`, use the `HeaderTemplate` render fragment:
|
|
160
|
+
|
|
161
|
+
```razor
|
|
162
|
+
<IgbColumn Field="Price" Header="Price">
|
|
163
|
+
<HeaderTemplate>
|
|
164
|
+
<strong>@((context as IgbColumnTemplateContext)?.Column.Header)</strong>
|
|
165
|
+
</HeaderTemplate>
|
|
166
|
+
</IgbColumn>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Remote Data
|
|
172
|
+
|
|
173
|
+
For server-side sort/filter, handle the `SortingDone` / `FilteringDone` events to reload data:
|
|
174
|
+
```razor
|
|
175
|
+
<IgbGrid @ref="grid" Data="@data" PrimaryKey="Id" Height="600px"
|
|
176
|
+
SortingDone="OnSortingDone" FilteringDone="OnFilteringDone">
|
|
177
|
+
</IgbGrid>
|
|
178
|
+
|
|
179
|
+
@code {
|
|
180
|
+
private IgbGrid grid = default!;
|
|
181
|
+
private List<MyItem> data = new();
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
private async Task OnSortingDone(IgbSortingExpressionEventArgs args)
|
|
185
|
+
{
|
|
186
|
+
data = await DataService.SortAsync(args.Detail);
|
|
187
|
+
StateHasChanged();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private async Task OnFilteringDone(IgbFilteringExpressionsTreeEventArgs args)
|
|
191
|
+
{
|
|
192
|
+
data = await DataService.FilterAsync(args.Detail);
|
|
193
|
+
StateHasChanged();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Programmatic Sort / Filter
|
|
201
|
+
|
|
202
|
+
```razor
|
|
203
|
+
@code {
|
|
204
|
+
private IgbGrid grid = default!;
|
|
205
|
+
|
|
206
|
+
// Sort
|
|
207
|
+
private async Task SortByName()
|
|
208
|
+
{
|
|
209
|
+
await grid.SortAsync(new IgbSortingExpression[]
|
|
210
|
+
{
|
|
211
|
+
new IgbSortingExpression { FieldName = "Name", Dir = SortingDirection.Asc }
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private async Task ClearSorting() => await grid.ClearSortAsync();
|
|
216
|
+
|
|
217
|
+
// Filter
|
|
218
|
+
private void FilterActive()
|
|
219
|
+
{
|
|
220
|
+
var tree = new IgbFilteringExpressionsTree() { Operator = FilteringLogic.And };
|
|
221
|
+
tree.FilteringOperands = new IgbFilteringExpression[]
|
|
222
|
+
{
|
|
223
|
+
new IgbFilteringExpression { FieldName = "IsActive", ConditionName = "true", SearchVal = true }
|
|
224
|
+
};
|
|
225
|
+
grid.FilteringExpressionsTree = tree;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private async Task ClearFilters() => await grid.ClearFilterAsync();
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
> In Grid Lite, sort/filter expressions used a `Key` property. In `IgbGrid`, use `FieldName`.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Common Enterprise Features
|
|
237
|
+
|
|
238
|
+
### Editing
|
|
239
|
+
|
|
240
|
+
```razor
|
|
241
|
+
<IgbGrid Data="@data" PrimaryKey="Id" RowEditable="true" Height="600px">
|
|
242
|
+
<IgbColumn Field="Name" Editable="true" />
|
|
243
|
+
<IgbColumn Field="Price" Editable="true" DataType="GridColumnDataType.Number" />
|
|
244
|
+
</IgbGrid>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
See [`editing.md`](./editing.md) for cell editing, row editing, validation, and custom editors.
|
|
248
|
+
|
|
249
|
+
### Row Selection
|
|
250
|
+
|
|
251
|
+
```razor
|
|
252
|
+
<IgbGrid Data="@data" PrimaryKey="Id" RowSelection="GridSelectionMode.Multiple" Height="600px">
|
|
253
|
+
<IgbColumn Field="Name" />
|
|
254
|
+
</IgbGrid>
|
|
255
|
+
|
|
256
|
+
@code {
|
|
257
|
+
// Read selected rows via grid.SelectedRows
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Paging
|
|
262
|
+
|
|
263
|
+
```razor
|
|
264
|
+
<IgbGrid Data="@data" PrimaryKey="Id" Height="600px">
|
|
265
|
+
<IgbPaginator PerPage="15" />
|
|
266
|
+
<IgbColumn Field="Name" />
|
|
267
|
+
</IgbGrid>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
See [`paging-remote.md`](./paging-remote.md) for remote paging and paginator configuration.
|
|
271
|
+
|
|
272
|
+
### Summaries
|
|
273
|
+
|
|
274
|
+
```razor
|
|
275
|
+
<IgbColumn Field="Price" DataType="GridColumnDataType.Number" HasSummary="true" />
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Toolbar + Export
|
|
279
|
+
|
|
280
|
+
```razor
|
|
281
|
+
<IgbGrid Data="@data" PrimaryKey="Id" Height="600px">
|
|
282
|
+
<IgbGridToolbar>
|
|
283
|
+
<IgbGridToolbarTitle>Products</IgbGridToolbarTitle>
|
|
284
|
+
<IgbGridToolbarActions>
|
|
285
|
+
<IgbGridToolbarHiding />
|
|
286
|
+
<IgbGridToolbarPinning />
|
|
287
|
+
<IgbGridToolbarAdvancedFiltering />
|
|
288
|
+
<IgbGridToolbarExporter ExportExcel="true" ExportCSV="true" />
|
|
289
|
+
</IgbGridToolbarActions>
|
|
290
|
+
</IgbGridToolbar>
|
|
291
|
+
<IgbColumn Field="Name" />
|
|
292
|
+
<IgbColumn Field="Price" />
|
|
293
|
+
</IgbGrid>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
See [`features.md`](./features.md) for toolbar customization, export events, grouping, summaries, and action strip.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Cleanup After Migration
|
|
301
|
+
|
|
302
|
+
1. Remove `IgbGridLiteModule` registration from `Program.cs`.
|
|
303
|
+
2. Remove the `IgniteUI.Blazor.GridLite` CSS `<link>` from `index.html`.
|
|
304
|
+
3. Rename all `IgbGridLite` → `IgbGrid`, `IgbGridLiteColumn` → `IgbColumn` in `.razor` files.
|
|
305
|
+
4. Replace `GridLiteColumnDataType` → `GridColumnDataType` enum values.
|
|
306
|
+
5. In sort/filter expression objects, rename the `Key` property → `FieldName`.
|
|
307
|
+
6. Remove the `IgniteUI.Blazor.GridLite` NuGet package if no `IgbGridLite` instances remain:
|
|
308
|
+
```bash
|
|
309
|
+
dotnet remove package IgniteUI.Blazor.GridLite
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Key Rules
|
|
315
|
+
|
|
316
|
+
- `PrimaryKey` is required for editing, selection, row APIs, and `IgbActionStrip` — Grid Lite had no equivalent.
|
|
317
|
+
- `Height` (or a CSS-constrained container) is required for row virtualization in `IgbGrid`.
|
|
318
|
+
- `AllowFiltering="true"` must be set on the grid to show the filter row; `Filterable="true"` on a column opts that column in.
|
|
319
|
+
- Cell and header templates use Blazor render fragments (`BodyTemplate`, `HeaderTemplate`, `InlineEditorTemplate`) — not callbacks or delegates.
|
|
320
|
+
- For remote data, handle `SortingDone` / `FilteringDone` and reload `Data` from your server.
|
|
321
|
+
- `IgbColumn.FieldName` (in expression objects) replaces `IgbGridLiteColumn.Key` used in Grid Lite sort/filter expressions.
|
|
322
|
+
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grid-lite-to-igr-grid-migration
|
|
3
|
+
description: Step-by-step migration guide from Grid Lite (IgrGridLite) to the premium Ignite UI for React Data Grid (IgrGrid), covering every import, registration, component name, property, event, template, sorting, filtering, and toolbar API change.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Ignite UI for React — Grid Lite → Premium Data Grid Migration
|
|
8
|
+
|
|
9
|
+
## MANDATORY AGENT PROTOCOL
|
|
10
|
+
|
|
11
|
+
> **DO NOT write any code from memory.** Grid APIs change between versions.
|
|
12
|
+
|
|
13
|
+
Before producing migration code:
|
|
14
|
+
|
|
15
|
+
1. **Read the user's existing component files** to understand current Grid Lite usage (columns, templates, data binding, `dataPipelineConfiguration`).
|
|
16
|
+
2. **Use the MCP server** — call `get_doc` or `search_docs` with `framework: "react"` to confirm API details when in doubt.
|
|
17
|
+
3. **Only then produce output** — base all code on verified references, not memory.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## When to Migrate from Grid Lite to Premium Grid
|
|
22
|
+
|
|
23
|
+
Migrate when you need any of the following features (not available in Grid Lite):
|
|
24
|
+
|
|
25
|
+
| Feature | Grid Lite | Premium Grid (`IgrGrid`) |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| Cell editing | ✗ | ✓ `editable`, `rowEditable` |
|
|
28
|
+
| Batch editing (with undo) | ✗ | ✓ Transaction service |
|
|
29
|
+
| Row adding / deleting | ✗ | ✓ `rowEditable` + `IgrActionStrip` |
|
|
30
|
+
| Row selection | ✗ | ✓ `rowSelection="single|multiple"` |
|
|
31
|
+
| Cell selection | ✗ | ✓ `cellSelection` |
|
|
32
|
+
| Column selection | ✗ | ✓ `columnSelection` |
|
|
33
|
+
| Paging | ✗ | ✓ `IgrPaginator` child |
|
|
34
|
+
| GroupBy | ✗ | ✓ `groupingExpressions` |
|
|
35
|
+
| Column summaries | ✗ | ✓ `hasSummary` on `IgrColumn` |
|
|
36
|
+
| Column pinning | ✗ | ✓ `pinned` on `IgrColumn` |
|
|
37
|
+
| Column moving | ✗ | ✓ `moving={true}` on grid |
|
|
38
|
+
| Master-detail rows | ✗ | ✓ `IgrGrid` row expansion |
|
|
39
|
+
| Excel / CSV export (toolbar) | ✗ | ✓ `IgrGridToolbarExporter` |
|
|
40
|
+
| Column hiding toolbar | ✗ | ✓ `IgrGridToolbarHiding` |
|
|
41
|
+
| Column pinning toolbar | ✗ | ✓ `IgrGridToolbarPinning` |
|
|
42
|
+
| Advanced filtering UI | ✗ | ✓ `filterMode="excelStyleFilter"` / `IgrGridToolbarAdvancedFiltering` |
|
|
43
|
+
| State persistence | ✗ | ✓ `IgrGridState` directive |
|
|
44
|
+
| Clipboard operations | ✗ | ✓ `clipboardOptions` |
|
|
45
|
+
| Action strip | ✗ | ✓ `IgrActionStrip` |
|
|
46
|
+
| Row drag and drop | ✗ | ✓ `rowDraggable={true}` |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Setup
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install --save igniteui-react-grids
|
|
54
|
+
# licensed: npm install --save @infragistics/igniteui-react-grids
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { IgrGridModule, IgrGrid, IgrColumn, IgrPaginator,
|
|
59
|
+
IgrCellTemplateContext, IgrColumnTemplateContext } from "igniteui-react-grids";
|
|
60
|
+
import "igniteui-react-grids/grids/themes/light/bootstrap.css";
|
|
61
|
+
|
|
62
|
+
// Required once before render — Grid Lite has no equivalent
|
|
63
|
+
IgrGridModule.register();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
> Use `@infragistics/igniteui-react-grids` and the matching CSS path for the licensed package.
|
|
67
|
+
> Check `package.json` — `igniteui-grid-lite` may be a standalone dependency alongside `igniteui-react`.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Minimal Migration Example
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { useRef, useState } from "react";
|
|
75
|
+
import { IgrGrid, IgrColumn, IgrGridModule } from "igniteui-react-grids";
|
|
76
|
+
import "igniteui-react-grids/grids/themes/light/bootstrap.css";
|
|
77
|
+
IgrGridModule.register();
|
|
78
|
+
|
|
79
|
+
export default function MyView() {
|
|
80
|
+
const gridRef = useRef<IgrGrid>(null);
|
|
81
|
+
const [data] = useState<Product[]>([]);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<IgrGrid ref={gridRef} data={data} primaryKey="id" autoGenerate={false}
|
|
85
|
+
height="600px" allowFiltering={true}>
|
|
86
|
+
<IgrColumn field="name" header="Name" sortable={true} filterable={true} resizable={true} />
|
|
87
|
+
<IgrColumn field="price" header="Price" dataType="number" sortable={true} />
|
|
88
|
+
</IgrGrid>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Key additions vs Grid Lite:**
|
|
94
|
+
- `primaryKey` — required for editing, selection, row-targeted APIs
|
|
95
|
+
- `height` — required for row virtualization
|
|
96
|
+
- `allowFiltering={true}` on the grid — required for filter UI; `filterable={true}` on the column opts that column in
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Cell Templates
|
|
101
|
+
|
|
102
|
+
Prop renamed: `cellTemplate` → `bodyTemplate`. Context type changes.
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { IgrCellTemplateContext } from "igniteui-react-grids";
|
|
106
|
+
|
|
107
|
+
const statusCell = (ctx: IgrCellTemplateContext) => (
|
|
108
|
+
<span style={{ color: ctx.cell.value === "Active" ? "green" : "red" }}>
|
|
109
|
+
{ctx.cell.value}
|
|
110
|
+
</span>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
<IgrColumn field="status" bodyTemplate={statusCell} />
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
| | Grid Lite | Premium Grid |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| Prop | `cellTemplate` | `bodyTemplate` |
|
|
119
|
+
| Value | `ctx.value` | `ctx.cell.value` or `ctx.implicit` |
|
|
120
|
+
| Row data | `ctx.row.data` | `ctx.cell.row.data` |
|
|
121
|
+
| Edit template | — | `inlineEditorTemplate` |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Header Templates
|
|
126
|
+
|
|
127
|
+
Prop name unchanged (`headerTemplate`); context type changes to `IgrColumnTemplateContext` from `igniteui-react-grids`.
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
import { IgrColumnTemplateContext } from "igniteui-react-grids";
|
|
131
|
+
|
|
132
|
+
const priceHeader = (ctx: IgrColumnTemplateContext) => (
|
|
133
|
+
<strong>{ctx.column.header}</strong>
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
<IgrColumn field="price" headerTemplate={priceHeader} />
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Remote Data (replaces `dataPipelineConfiguration`)
|
|
142
|
+
|
|
143
|
+
For server-side operations, disable local sort/filter processing first by assigning noop strategies, then listen to the done events to issue new requests.
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { IgrGrid, IgrGridModule,
|
|
147
|
+
IgrNoopSortingStrategy, IgrNoopFilteringStrategy } from "igniteui-react-grids";
|
|
148
|
+
|
|
149
|
+
// Disable built-in sort/filter so the grid does not process data locally.
|
|
150
|
+
// Set these once after the grid mounts (e.g., in a useEffect or ref callback).
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
if (!gridRef.current) return;
|
|
153
|
+
gridRef.current.sortStrategy = IgrNoopSortingStrategy.instance();
|
|
154
|
+
gridRef.current.filterStrategy = IgrNoopFilteringStrategy.instance();
|
|
155
|
+
}, []);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
const handleSortingDone = async () => {
|
|
160
|
+
if (!gridRef.current) return;
|
|
161
|
+
setData(await dataService.sort(gridRef.current.sortingExpressions));
|
|
162
|
+
};
|
|
163
|
+
const handleFilteringDone = async () => {
|
|
164
|
+
if (!gridRef.current) return;
|
|
165
|
+
setData(await dataService.filter(gridRef.current.filteringExpressionsTree));
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
<IgrGrid ref={gridRef} data={data} primaryKey="id" height="600px"
|
|
169
|
+
onSortingDone={handleSortingDone} onFilteringDone={handleFilteringDone}>
|
|
170
|
+
{/* columns */}
|
|
171
|
+
</IgrGrid>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Programmatic Sort / Filter
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
import { SortingDirection, IgrNumberFilteringOperand } from "igniteui-react-grids";
|
|
180
|
+
|
|
181
|
+
// fieldName + SortingDirection enum (not key + string)
|
|
182
|
+
gridRef.current.sort([{ fieldName: 'name', dir: SortingDirection.Asc, ignoreCase: true }]);
|
|
183
|
+
gridRef.current.clearSort('name'); // or clearSort() for all
|
|
184
|
+
|
|
185
|
+
// Positional args with operand
|
|
186
|
+
// Note: verify IgrNumberFilteringOperand.instance() is available in your version
|
|
187
|
+
gridRef.current.filter('age', 21, IgrNumberFilteringOperand.instance().condition('greaterThan'));
|
|
188
|
+
gridRef.current.clearFilter('age'); // or clearFilter() for all
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Common Enterprise Features
|
|
194
|
+
|
|
195
|
+
### Editing
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
<IgrGrid data={data} primaryKey="id" rowEditable={true} onRowEditDone={handleRowEditDone} height="600px">
|
|
199
|
+
<IgrColumn field="name" editable={true} />
|
|
200
|
+
</IgrGrid>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Row Selection
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
<IgrGrid data={data} primaryKey="id" rowSelection="multiple" height="600px">
|
|
207
|
+
{/* columns */}
|
|
208
|
+
</IgrGrid>
|
|
209
|
+
// Read: gridRef.current.selectedRows
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Paging
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
<IgrGrid data={data} primaryKey="id" height="600px">
|
|
216
|
+
<IgrPaginator perPage={15} />
|
|
217
|
+
</IgrGrid>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Summaries
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
<IgrColumn field="price" dataType="number" hasSummary={true} />
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Toolbar + Export
|
|
227
|
+
|
|
228
|
+
> **Note:** `IgrExcelExporterService` / `IgrExcelExporterOptions` (programmatic export) must be imported from `"igniteui-react"`, **not** `"igniteui-react-grids"`. The toolbar approach below does not need them.
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
import { IgrGrid, IgrColumn, IgrGridToolbar, IgrGridToolbarTitle,
|
|
232
|
+
IgrGridToolbarActions, IgrGridToolbarHiding, IgrGridToolbarPinning,
|
|
233
|
+
IgrGridToolbarExporter, IgrGridToolbarAdvancedFiltering,
|
|
234
|
+
IgrGridToolbarExportEventArgs, IgrGridModule } from "igniteui-react-grids";
|
|
235
|
+
IgrGridModule.register();
|
|
236
|
+
|
|
237
|
+
<IgrGrid data={data} primaryKey="id" height="600px" onToolbarExporting={handleExporting}>
|
|
238
|
+
<IgrGridToolbar>
|
|
239
|
+
<IgrGridToolbarTitle>Products</IgrGridToolbarTitle>
|
|
240
|
+
<IgrGridToolbarActions>
|
|
241
|
+
<IgrGridToolbarHiding />
|
|
242
|
+
<IgrGridToolbarPinning />
|
|
243
|
+
<IgrGridToolbarAdvancedFiltering />
|
|
244
|
+
<IgrGridToolbarExporter exportExcel={true} exportCSV={true} />
|
|
245
|
+
</IgrGridToolbarActions>
|
|
246
|
+
</IgrGridToolbar>
|
|
247
|
+
{/* columns */}
|
|
248
|
+
</IgrGrid>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
const handleExporting = (e: IgrGridToolbarExportEventArgs) => {
|
|
253
|
+
e.detail.options.fileName = "MyExport";
|
|
254
|
+
// set e.detail.cancel = true to abort
|
|
255
|
+
};
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Cleanup After Migration
|
|
261
|
+
|
|
262
|
+
1. Remove all `dataPipelineConfiguration` usage — replace with events (see Remote Data).
|
|
263
|
+
2. Remove `IgrCellContext` / `IgrHeaderContext` imports from `igniteui-react/grid-lite`.
|
|
264
|
+
3. Uninstall `igniteui-grid-lite` if no Grid Lite instances remain: `npm uninstall igniteui-grid-lite`.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Related Skills
|
|
269
|
+
|
|
270
|
+
- [igniteui-react-components](../igniteui-react-components/SKILL.md) — Identify the right `Igr*` components, install, import, and use them; covers JSX patterns, events, refs, and forms. Use this after migrating to explore the full premium grid feature set.
|
|
271
|
+
- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — Customize `IgrGrid` styling using CSS custom properties and the Ignite UI theming system.
|
|
272
|
+
- [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md) — Reduce bundle size after migrating to `igniteui-react-grids` with granular imports, tree-shaking, and lazy loading.
|
|
273
|
+
- [igniteui-react-generate-from-image-design](../igniteui-react-generate-from-image-design/SKILL.md) — Build a full React view from a screenshot or mockup using Ignite UI components and MCP-driven theming.
|
|
274
|
+
|
|
@@ -139,8 +139,8 @@ For core UI component theming, prefer `create_component_theme` and apply the ret
|
|
|
139
139
|
Override the drawer width using the nav drawer CSS custom properties measured from the design image:
|
|
140
140
|
```css
|
|
141
141
|
igc-nav-drawer {
|
|
142
|
-
--
|
|
143
|
-
--
|
|
142
|
+
--menu-full-width: <extracted-sidebar-width>;
|
|
143
|
+
--menu-mini-width: <extracted-mini-drawer-width>;
|
|
144
144
|
}
|
|
145
145
|
```
|
|
146
146
|
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: igniteui-wc-migrate-grid-lite-to-premium
|
|
3
|
+
description: Step-by-step migration guide from igniteui-grid-lite (IgcGridLite) to the premium igniteui-webcomponents-grids (IgcGridComponent), covering every import, class name, HTML tag, property, event, template, sorting, filtering, and theming API change.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Migrate from Grid Lite to Premium Data Grid (Web Components)
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
This skill automates the migration from **Grid Lite** (`igniteui-grid-lite`, MIT licensed, `<igc-grid-lite>`) to the **Premium Data Grid** (`igniteui-webcomponents-grids`, commercially licensed, `<igc-grid>`). Use it when a project outgrows Grid Lite's read-only capabilities and needs enterprise features such as editing, selection, paging, grouping, summaries, Excel export, or state persistence.
|
|
12
|
+
|
|
13
|
+
## MANDATORY AGENT PROTOCOL
|
|
14
|
+
|
|
15
|
+
> **DO NOT write any code from memory.** Grid APIs change between versions.
|
|
16
|
+
|
|
17
|
+
Before producing migration code:
|
|
18
|
+
|
|
19
|
+
1. **Identify the current Grid Lite usage** - read the user's existing TypeScript and HTML files to understand their column configuration, cell templates, data binding, and any `dataPipelineConfiguration` usage.
|
|
20
|
+
2. **Use the MCP server** - call `mcp_igniteui-cli_get_api_reference` or `mcp_igniteui-cli_get_doc` (framework: `webcomponents`) to verify current API details when in doubt.
|
|
21
|
+
3. **Only then produce output** - base all code on verified references, not memory.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## When to Migrate
|
|
26
|
+
|
|
27
|
+
Migrate from Grid Lite to the Premium Grid when the user needs **any** of these features:
|
|
28
|
+
|
|
29
|
+
| Required Feature | Grid Lite | Premium Grid |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| Cell / Row / Batch editing | No | Yes |
|
|
32
|
+
| Row adding / deleting | No | Yes |
|
|
33
|
+
| Row / Cell / Column selection | No | Yes |
|
|
34
|
+
| Paging (client or remote) | No | Yes |
|
|
35
|
+
| GroupBy | No | Yes |
|
|
36
|
+
| Summaries (built-in & custom) | No | Yes |
|
|
37
|
+
| Column pinning | No | Yes |
|
|
38
|
+
| Column moving | No | Yes |
|
|
39
|
+
| Master-Detail rows | No | Yes |
|
|
40
|
+
| Export (Excel / CSV) | No | Yes |
|
|
41
|
+
| Toolbar | No | Yes |
|
|
42
|
+
| State persistence | No | Yes |
|
|
43
|
+
| Advanced filtering | No | Yes |
|
|
44
|
+
| Action strip | No | Yes |
|
|
45
|
+
| Row drag | No | Yes |
|
|
46
|
+
| Clipboard support | No | Yes |
|
|
47
|
+
| Cell merging | No | Yes |
|
|
48
|
+
|
|
49
|
+
> **IMPORTANT:** The upgrade path from Grid Lite is **always** to `IgcGridComponent` (`<igc-grid>`). Never recommend a different component type as a substitute.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Step 1 - Install / Verify the Premium Package
|
|
54
|
+
|
|
55
|
+
Grid Lite uses the separate `igniteui-grid-lite` npm package. The Premium Grid ships in `igniteui-webcomponents-grids` (or `@infragistics/igniteui-webcomponents-grids` for licensed builds).
|
|
56
|
+
|
|
57
|
+
> **AGENT INSTRUCTION:** Check `package.json` to determine which package variant is installed. If only `igniteui-grid-lite` is present, the user needs to install the premium package.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Remove Grid Lite
|
|
61
|
+
npm uninstall igniteui-grid-lite
|
|
62
|
+
|
|
63
|
+
# Open-source / trial (shows watermark)
|
|
64
|
+
npm install igniteui-webcomponents-grids
|
|
65
|
+
|
|
66
|
+
# OR licensed package (requires private registry)
|
|
67
|
+
npm install @infragistics/igniteui-webcomponents-grids
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Step 2 - Update Imports and Registration
|
|
71
|
+
|
|
72
|
+
**Before (Grid Lite):**
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { IgcGridLite, IgcGridLiteColumn } from 'igniteui-grid-lite';
|
|
76
|
+
import type { BaseIgcCellContext } from 'igniteui-grid-lite';
|
|
77
|
+
import 'igniteui-webcomponents/themes/light/bootstrap.css';
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**After (Premium Grid):**
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Side-effect import - registers all premium grid custom elements; must come first
|
|
84
|
+
import 'igniteui-webcomponents-grids/grids/combined.js';
|
|
85
|
+
|
|
86
|
+
// Type imports
|
|
87
|
+
import type {
|
|
88
|
+
IgcGridComponent,
|
|
89
|
+
IgcColumnComponent,
|
|
90
|
+
IgcCellTemplateContext,
|
|
91
|
+
IgcColumnTemplateContext,
|
|
92
|
+
IgcSortingEventArgs,
|
|
93
|
+
IgcFilteringEventArgs,
|
|
94
|
+
IgcRowSelectionEventArgs,
|
|
95
|
+
IgcSortingExpression,
|
|
96
|
+
} from 'igniteui-webcomponents-grids';
|
|
97
|
+
|
|
98
|
+
// Value imports
|
|
99
|
+
import {
|
|
100
|
+
SortingDirection,
|
|
101
|
+
IgcStringFilteringOperand,
|
|
102
|
+
IgcNumberFilteringOperand,
|
|
103
|
+
IgcBooleanFilteringOperand,
|
|
104
|
+
IgcDateFilteringOperand,
|
|
105
|
+
IgcFilteringExpressionsTree,
|
|
106
|
+
FilteringLogic,
|
|
107
|
+
IgcNoopSortingStrategy,
|
|
108
|
+
IgcNoopFilteringStrategy,
|
|
109
|
+
} from 'igniteui-webcomponents-grids';
|
|
110
|
+
|
|
111
|
+
// Theme - change to the grids-specific path
|
|
112
|
+
// Available: light|dark x bootstrap|material|fluent|indigo
|
|
113
|
+
import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css';
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Step 3 - Update HTML Tags
|
|
117
|
+
|
|
118
|
+
| Grid Lite | Premium Grid |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `<igc-grid-lite>` | `<igc-grid>` |
|
|
121
|
+
| `<igc-grid-lite-column>` | `<igc-column>` |
|
|
122
|
+
| Bare boolean attrs (`sortable`, `filterable`, `hidden`) | Quoted values (`sortable="true"`, `filterable="true"`, `hidden="true"`) |
|
|
123
|
+
| No grid-level filter toggle | `allow-filtering="true"` required on `<igc-grid>` |
|
|
124
|
+
| No height requirement | `height` attribute required for row virtualization |
|
|
125
|
+
|
|
126
|
+
**Before:**
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<igc-grid-lite id="grid" auto-generate>
|
|
130
|
+
<igc-grid-lite-column field="name" sortable filterable resizable></igc-grid-lite-column>
|
|
131
|
+
<igc-grid-lite-column field="price" data-type="number" sortable></igc-grid-lite-column>
|
|
132
|
+
</igc-grid-lite>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**After:**
|
|
136
|
+
|
|
137
|
+
```html
|
|
138
|
+
<!-- height is required for row virtualization; set it here or on a fixed-height parent -->
|
|
139
|
+
<igc-grid id="grid" auto-generate="true" allow-filtering="true" height="600px">
|
|
140
|
+
<igc-column field="name" sortable="true" filterable="true" resizable="true"></igc-column>
|
|
141
|
+
<igc-column field="price" data-type="number" sortable="true"></igc-column>
|
|
142
|
+
</igc-grid>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> **Note:** `allow-filtering="true"` on `<igc-grid>` is required to enable filtering. Grid Lite had no grid-level filter toggle.
|
|
146
|
+
|
|
147
|
+
## Step 4 - Update TypeScript References
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Before
|
|
151
|
+
const grid = document.getElementById('grid') as IgcGridLite;
|
|
152
|
+
const column = document.querySelector('igc-grid-lite-column[field="name"]') as IgcGridLiteColumn;
|
|
153
|
+
|
|
154
|
+
// After
|
|
155
|
+
const grid = document.getElementById('grid') as IgcGridComponent;
|
|
156
|
+
const column = document.querySelector('igc-column[field="name"]') as IgcColumnComponent;
|
|
157
|
+
|
|
158
|
+
// grid.data = myArray - unchanged
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Step 5 - Migrate Column Properties
|
|
162
|
+
|
|
163
|
+
| Grid Lite Property | Premium Grid Property | Notes |
|
|
164
|
+
|---|---|---|
|
|
165
|
+
| `field` | `field` | Unchanged |
|
|
166
|
+
| `header` | `header` | Unchanged |
|
|
167
|
+
| `width` | `width` | Unchanged |
|
|
168
|
+
| `hidden` | `hidden` | Unchanged |
|
|
169
|
+
| `resizable` | `resizable` | Unchanged |
|
|
170
|
+
| `sortable` | `sortable` | Unchanged |
|
|
171
|
+
| `filterable` | `filterable` | Unchanged |
|
|
172
|
+
| `dataType` | `dataType` | Premium adds `dateTime`, `time`, `currency`, `percent` |
|
|
173
|
+
| `filteringCaseSensitive` | `filteringIgnoreCase` | **Logic inverted** - `true` becomes `false` |
|
|
174
|
+
| `sortingCaseSensitive` | `sortingIgnoreCase` | **Logic inverted** - `true` becomes `false` |
|
|
175
|
+
| `sortConfiguration: { comparer }` | `sortStrategy: IgcSortingStrategy` | Class-based (see below) |
|
|
176
|
+
| _(none)_ | `editable`, `pinned`, `groupable`, `hasSummary`, `disableHiding`, `disablePinning`, `selectable`, `searchable`, `formatter`, `minWidth`, `maxWidth` | Premium-only |
|
|
177
|
+
|
|
178
|
+
**Custom sort strategy migration:**
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// Before (Grid Lite) - function comparer on column
|
|
182
|
+
column.sortConfiguration = { comparer: (a, b) => a.length - b.length };
|
|
183
|
+
|
|
184
|
+
// After (Premium Grid) - class extending DefaultSortingStrategy
|
|
185
|
+
import { DefaultSortingStrategy } from 'igniteui-webcomponents-grids';
|
|
186
|
+
|
|
187
|
+
class LengthSort extends DefaultSortingStrategy {
|
|
188
|
+
override compareValues(a: string, b: string) { return a.length - b.length; }
|
|
189
|
+
}
|
|
190
|
+
column.sortStrategy = new LengthSort();
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Step 6 - Migrate Cell and Header Templates
|
|
194
|
+
|
|
195
|
+
| Aspect | Grid Lite | Premium Grid |
|
|
196
|
+
|---|---|---|
|
|
197
|
+
| Cell template property | `column.cellTemplate` | `column.bodyTemplate` |
|
|
198
|
+
| Cell context type | `BaseIgcCellContext` | `IgcCellTemplateContext` |
|
|
199
|
+
| Cell value | `ctx.value` | `ctx.implicit` |
|
|
200
|
+
| Row data | `ctx.row` | `ctx.cell.row.data` |
|
|
201
|
+
| Header template | no params | `IgcColumnTemplateContext` param |
|
|
202
|
+
|
|
203
|
+
**Cell template migration:**
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// Before (Grid Lite)
|
|
207
|
+
column.cellTemplate = (ctx) => html`<span class=${ctx.value}>${ctx.value}</span>`;
|
|
208
|
+
|
|
209
|
+
// After (Premium Grid)
|
|
210
|
+
column.bodyTemplate = (ctx: IgcCellTemplateContext) =>
|
|
211
|
+
html`<span class=${ctx.implicit}>${ctx.implicit}</span>`;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Header template migration:**
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// Before (Grid Lite) - no parameters
|
|
218
|
+
column.headerTemplate = () => html`<strong>Name</strong>`;
|
|
219
|
+
|
|
220
|
+
// After (Premium Grid) - receives IgcColumnTemplateContext
|
|
221
|
+
column.headerTemplate = (ctx: IgcColumnTemplateContext) =>
|
|
222
|
+
html`<strong>${ctx.column.header ?? ctx.column.field}</strong>`;
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Step 7 - Migrate Remote Data Operations
|
|
226
|
+
|
|
227
|
+
Grid Lite uses `dataPipelineConfiguration` (async callbacks). The Premium Grid uses **noop strategies + events**.
|
|
228
|
+
|
|
229
|
+
**Before (Grid Lite):**
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
grid.dataPipelineConfiguration = {
|
|
233
|
+
sort: async ({ grid }) => dataService.sortRemote(grid.sortingExpressions),
|
|
234
|
+
filter: async ({ grid }) => dataService.filterRemote(grid.filterExpressions),
|
|
235
|
+
};
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**After (Premium Grid):**
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
const grid = document.getElementById('grid') as IgcGridComponent;
|
|
242
|
+
|
|
243
|
+
// Disable built-in sort/filter so the grid does not process data locally
|
|
244
|
+
grid.sortStrategy = IgcNoopSortingStrategy.instance();
|
|
245
|
+
grid.filterStrategy = IgcNoopFilteringStrategy.instance();
|
|
246
|
+
|
|
247
|
+
// React to done events and reload data from the server
|
|
248
|
+
grid.addEventListener('sortingDone', async () => {
|
|
249
|
+
grid.data = await dataService.sortRemote(grid.sortingExpressions);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
grid.addEventListener('filteringDone', async () => {
|
|
253
|
+
grid.data = await dataService.filterRemote(grid.filteringExpressionsTree);
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Step 8 - Migrate Sort / Filter Events
|
|
258
|
+
|
|
259
|
+
| Grid Lite Event | Premium Grid Event | Notes |
|
|
260
|
+
|---|---|---|
|
|
261
|
+
| `sorting` | `sorting` | Same name - both cancellable (`e.detail.cancel = true`) |
|
|
262
|
+
| `sorted` | `sortingDone` | Name changed - `CustomEvent<IgcSortingExpression[]>` |
|
|
263
|
+
| `filtering` | `filtering` | Same name - both cancellable |
|
|
264
|
+
| `filtered` | `filteringDone` | Name changed - `CustomEvent<IgcFilteringExpressionsTree>` |
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
// Cancel a sort before it applies
|
|
268
|
+
grid.addEventListener('sorting', (e: CustomEvent<IgcSortingEventArgs>) => {
|
|
269
|
+
e.detail.cancel = true;
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// React after sort completes
|
|
273
|
+
grid.addEventListener('sortingDone', (e: CustomEvent<IgcSortingExpression[]>) => {
|
|
274
|
+
console.log('Sorted by', e.detail);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Cancel a filter before it applies
|
|
278
|
+
grid.addEventListener('filtering', (e: CustomEvent<IgcFilteringEventArgs>) => {
|
|
279
|
+
e.detail.cancel = true;
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// React after filter completes
|
|
283
|
+
grid.addEventListener('filteringDone', (e: CustomEvent<IgcFilteringExpressionsTree>) => {
|
|
284
|
+
console.log('Filter tree', e.detail);
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Step 9 - Migrate Programmatic Sort / Filter API
|
|
289
|
+
|
|
290
|
+
**Grid Lite API:**
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
grid.sort({ key: 'name', direction: 'ascending' });
|
|
294
|
+
grid.filter({ key: 'age', condition: 'greaterThan', searchTerm: 21 });
|
|
295
|
+
grid.clearSort();
|
|
296
|
+
grid.clearFilter();
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Premium Grid API:**
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import { SortingDirection, IgcNumberFilteringOperand } from 'igniteui-webcomponents-grids';
|
|
303
|
+
|
|
304
|
+
// Sorting - fieldName + SortingDirection enum (Asc = 1, Desc = 2, None = 0)
|
|
305
|
+
grid.sort([{ fieldName: 'name', dir: SortingDirection.Asc, ignoreCase: true }]);
|
|
306
|
+
grid.clearSort('name'); // clear one column
|
|
307
|
+
grid.clearSort(); // clear all
|
|
308
|
+
|
|
309
|
+
// Filtering - positional arguments with typed operand instances
|
|
310
|
+
grid.filter('age', 21, IgcNumberFilteringOperand.instance().condition('greaterThan'), true);
|
|
311
|
+
grid.clearFilter('age'); // clear one column
|
|
312
|
+
grid.clearFilter(); // clear all
|
|
313
|
+
|
|
314
|
+
// Multi-column filtering via expression tree
|
|
315
|
+
const tree = new IgcFilteringExpressionsTree(FilteringLogic.And);
|
|
316
|
+
tree.filteringOperands.push({
|
|
317
|
+
fieldName: 'age',
|
|
318
|
+
condition: IgcNumberFilteringOperand.instance().condition('greaterThan'),
|
|
319
|
+
searchVal: 21,
|
|
320
|
+
ignoreCase: true,
|
|
321
|
+
});
|
|
322
|
+
grid.filteringExpressionsTree = tree;
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Key expression shape changes:**
|
|
326
|
+
|
|
327
|
+
| Aspect | Grid Lite | Premium Grid |
|
|
328
|
+
|---|---|---|
|
|
329
|
+
| Sort target field | `key` | `fieldName` |
|
|
330
|
+
| Sort direction | `direction: 'ascending'` (string) | `dir: SortingDirection.Asc` (enum) |
|
|
331
|
+
| Filter target field | `key` | `fieldName` |
|
|
332
|
+
| Filter search value | `searchTerm` | `searchVal` (expression tree) |
|
|
333
|
+
| Case sensitivity (sort) | `caseSensitive: true` | `ignoreCase: false` (**inverted**) |
|
|
334
|
+
| Case sensitivity (filter) | `caseSensitive: true` | `ignoreCase: false` (**inverted**) |
|
|
335
|
+
| Filter criteria | `criteria` string | `FilteringLogic` enum on the tree |
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Adding Enterprise Features Post-Migration
|
|
340
|
+
|
|
341
|
+
Once on the Premium Grid, enable the features that motivated the migration:
|
|
342
|
+
|
|
343
|
+
### Row Editing
|
|
344
|
+
|
|
345
|
+
```html
|
|
346
|
+
<igc-grid id="grid" row-editable="true" primary-key="id" height="600px">
|
|
347
|
+
<igc-column field="name" editable="true"></igc-column>
|
|
348
|
+
<igc-column field="price" data-type="number" editable="true"></igc-column>
|
|
349
|
+
</igc-grid>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
> **Note:** `primary-key` is strongly recommended whenever editing, selection, or row-targeted APIs (`getRowByKey`, row pinning, transactions) are used. Without it the grid falls back to object identity, which breaks across virtualization and remote data.
|
|
353
|
+
|
|
354
|
+
### Row Selection
|
|
355
|
+
|
|
356
|
+
```html
|
|
357
|
+
<igc-grid id="grid" row-selection="multiple" primary-key="id" height="600px">
|
|
358
|
+
<!-- columns -->
|
|
359
|
+
</igc-grid>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
grid.addEventListener('rowSelectionChanging', (e: CustomEvent<IgcRowSelectionEventArgs>) => {
|
|
364
|
+
console.log('Selected rows:', e.detail.added);
|
|
365
|
+
});
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Paging
|
|
369
|
+
|
|
370
|
+
```html
|
|
371
|
+
<igc-grid id="grid" primary-key="id" height="600px">
|
|
372
|
+
<!-- columns -->
|
|
373
|
+
<igc-paginator per-page="15"></igc-paginator>
|
|
374
|
+
</igc-grid>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### GroupBy
|
|
378
|
+
|
|
379
|
+
```html
|
|
380
|
+
<igc-grid id="grid" primary-key="id" height="600px">
|
|
381
|
+
<igc-column field="category" groupable="true"></igc-column>
|
|
382
|
+
</igc-grid>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
grid.groupBy([{ fieldName: 'category', dir: SortingDirection.Asc }]);
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Column Pinning
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const column = grid.getColumnByName('name');
|
|
393
|
+
column.pin(); // pin to start (default)
|
|
394
|
+
column.unpin();
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Summaries
|
|
398
|
+
|
|
399
|
+
```html
|
|
400
|
+
<igc-column field="price" data-type="number" has-summary="true"></igc-column>
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Toolbar (Column Hiding, Pinning, Export)
|
|
404
|
+
|
|
405
|
+
```html
|
|
406
|
+
<igc-grid id="grid" auto-generate="true" height="600px">
|
|
407
|
+
<igc-grid-toolbar>
|
|
408
|
+
<igc-grid-toolbar-title>My Grid</igc-grid-toolbar-title>
|
|
409
|
+
<igc-grid-toolbar-actions>
|
|
410
|
+
<igc-grid-toolbar-advanced-filtering></igc-grid-toolbar-advanced-filtering>
|
|
411
|
+
<igc-grid-toolbar-hiding></igc-grid-toolbar-hiding>
|
|
412
|
+
<igc-grid-toolbar-pinning></igc-grid-toolbar-pinning>
|
|
413
|
+
<igc-grid-toolbar-exporter></igc-grid-toolbar-exporter>
|
|
414
|
+
</igc-grid-toolbar-actions>
|
|
415
|
+
</igc-grid-toolbar>
|
|
416
|
+
<!-- columns -->
|
|
417
|
+
</igc-grid>
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Advanced Filtering Dialog
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
grid.allowAdvancedFiltering = true;
|
|
424
|
+
grid.openAdvancedFilteringDialog();
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Excel-Style Filter UI
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
grid.filterMode = 'excelStyleFilter'; // default is 'quickFilter'
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Batch Editing
|
|
434
|
+
|
|
435
|
+
```html
|
|
436
|
+
<igc-grid id="grid" batch-editing="true" row-editable="true" primary-key="id" height="600px">
|
|
437
|
+
<igc-column field="name" editable="true"></igc-column>
|
|
438
|
+
</igc-grid>
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
## Related Skills
|
|
443
|
+
|
|
444
|
+
- **[`igniteui-wc-integrate-with-framework`](../igniteui-wc-integrate-with-framework/SKILL.md)** - Framework integration setup
|
|
445
|
+
- **[`igniteui-wc-customize-component-theme`](../igniteui-wc-customize-component-theme/SKILL.md)** - Theming and styling
|
|
446
|
+
- **[`igniteui-wc-choose-components`](../igniteui-wc-choose-components/SKILL.md)** - Choosing the right grid component
|