igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
447 lines (341 loc) • 15.2 kB
Markdown
---
name: igniteui-wc-migrate-grid-lite-to-premium
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.
user-invocable: true
---
# Migrate from Grid Lite to Premium Data Grid (Web Components)
## Purpose
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.
## MANDATORY AGENT PROTOCOL
> **DO NOT write any code from memory.** Grid APIs change between versions.
Before producing migration code:
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.
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.
3. **Only then produce output** - base all code on verified references, not memory.
---
## When to Migrate
Migrate from Grid Lite to the Premium Grid when the user needs **any** of these features:
| Required Feature | Grid Lite | Premium Grid |
|---|---|---|
| Cell / Row / Batch editing | No | Yes |
| Row adding / deleting | No | Yes |
| Row / Cell / Column selection | No | Yes |
| Paging (client or remote) | No | Yes |
| GroupBy | No | Yes |
| Summaries (built-in & custom) | No | Yes |
| Column pinning | No | Yes |
| Column moving | No | Yes |
| Master-Detail rows | No | Yes |
| Export (Excel / CSV) | No | Yes |
| Toolbar | No | Yes |
| State persistence | No | Yes |
| Advanced filtering | No | Yes |
| Action strip | No | Yes |
| Row drag | No | Yes |
| Clipboard support | No | Yes |
| Cell merging | No | Yes |
> **IMPORTANT:** The upgrade path from Grid Lite is **always** to `IgcGridComponent` (`<igc-grid>`). Never recommend a different component type as a substitute.
---
## Step 1 - Install / Verify the Premium Package
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).
> **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.
```bash
# Remove Grid Lite
npm uninstall igniteui-grid-lite
# Open-source / trial (shows watermark)
npm install igniteui-webcomponents-grids
# OR licensed package (requires private registry)
npm install @infragistics/igniteui-webcomponents-grids
```
## Step 2 - Update Imports and Registration
**Before (Grid Lite):**
```typescript
import { IgcGridLite, IgcGridLiteColumn } from 'igniteui-grid-lite';
import type { BaseIgcCellContext } from 'igniteui-grid-lite';
import 'igniteui-webcomponents/themes/light/bootstrap.css';
```
**After (Premium Grid):**
```typescript
// Side-effect import - registers all premium grid custom elements; must come first
import 'igniteui-webcomponents-grids/grids/combined.js';
// Type imports
import type {
IgcGridComponent,
IgcColumnComponent,
IgcCellTemplateContext,
IgcColumnTemplateContext,
IgcSortingEventArgs,
IgcFilteringEventArgs,
IgcRowSelectionEventArgs,
IgcSortingExpression,
} from 'igniteui-webcomponents-grids';
// Value imports
import {
SortingDirection,
IgcStringFilteringOperand,
IgcNumberFilteringOperand,
IgcBooleanFilteringOperand,
IgcDateFilteringOperand,
IgcFilteringExpressionsTree,
FilteringLogic,
IgcNoopSortingStrategy,
IgcNoopFilteringStrategy,
} from 'igniteui-webcomponents-grids';
// Theme - change to the grids-specific path
// Available: light|dark x bootstrap|material|fluent|indigo
import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css';
```
## Step 3 - Update HTML Tags
| Grid Lite | Premium Grid |
|---|---|
| `<igc-grid-lite>` | `<igc-grid>` |
| `<igc-grid-lite-column>` | `<igc-column>` |
| Bare boolean attrs (`sortable`, `filterable`, `hidden`) | Quoted values (`sortable="true"`, `filterable="true"`, `hidden="true"`) |
| No grid-level filter toggle | `allow-filtering="true"` required on `<igc-grid>` |
| No height requirement | `height` attribute required for row virtualization |
**Before:**
```html
<igc-grid-lite id="grid" auto-generate>
<igc-grid-lite-column field="name" sortable filterable resizable></igc-grid-lite-column>
<igc-grid-lite-column field="price" data-type="number" sortable></igc-grid-lite-column>
</igc-grid-lite>
```
**After:**
```html
<!-- height is required for row virtualization; set it here or on a fixed-height parent -->
<igc-grid id="grid" auto-generate="true" allow-filtering="true" height="600px">
<igc-column field="name" sortable="true" filterable="true" resizable="true"></igc-column>
<igc-column field="price" data-type="number" sortable="true"></igc-column>
</igc-grid>
```
> **Note:** `allow-filtering="true"` on `<igc-grid>` is required to enable filtering. Grid Lite had no grid-level filter toggle.
## Step 4 - Update TypeScript References
```typescript
// Before
const grid = document.getElementById('grid') as IgcGridLite;
const column = document.querySelector('igc-grid-lite-column[field="name"]') as IgcGridLiteColumn;
// After
const grid = document.getElementById('grid') as IgcGridComponent;
const column = document.querySelector('igc-column[field="name"]') as IgcColumnComponent;
// grid.data = myArray - unchanged
```
## Step 5 - Migrate Column Properties
| Grid Lite Property | Premium Grid Property | Notes |
|---|---|---|
| `field` | `field` | Unchanged |
| `header` | `header` | Unchanged |
| `width` | `width` | Unchanged |
| `hidden` | `hidden` | Unchanged |
| `resizable` | `resizable` | Unchanged |
| `sortable` | `sortable` | Unchanged |
| `filterable` | `filterable` | Unchanged |
| `dataType` | `dataType` | Premium adds `dateTime`, `time`, `currency`, `percent` |
| `filteringCaseSensitive` | `filteringIgnoreCase` | **Logic inverted** - `true` becomes `false` |
| `sortingCaseSensitive` | `sortingIgnoreCase` | **Logic inverted** - `true` becomes `false` |
| `sortConfiguration: { comparer }` | `sortStrategy: IgcSortingStrategy` | Class-based (see below) |
| _(none)_ | `editable`, `pinned`, `groupable`, `hasSummary`, `disableHiding`, `disablePinning`, `selectable`, `searchable`, `formatter`, `minWidth`, `maxWidth` | Premium-only |
**Custom sort strategy migration:**
```typescript
// Before (Grid Lite) - function comparer on column
column.sortConfiguration = { comparer: (a, b) => a.length - b.length };
// After (Premium Grid) - class extending DefaultSortingStrategy
import { DefaultSortingStrategy } from 'igniteui-webcomponents-grids';
class LengthSort extends DefaultSortingStrategy {
override compareValues(a: string, b: string) { return a.length - b.length; }
}
column.sortStrategy = new LengthSort();
```
## Step 6 - Migrate Cell and Header Templates
| Aspect | Grid Lite | Premium Grid |
|---|---|---|
| Cell template property | `column.cellTemplate` | `column.bodyTemplate` |
| Cell context type | `BaseIgcCellContext` | `IgcCellTemplateContext` |
| Cell value | `ctx.value` | `ctx.implicit` |
| Row data | `ctx.row` | `ctx.cell.row.data` |
| Header template | no params | `IgcColumnTemplateContext` param |
**Cell template migration:**
```typescript
// Before (Grid Lite)
column.cellTemplate = (ctx) => html`<span class=${ctx.value}>${ctx.value}</span>`;
// After (Premium Grid)
column.bodyTemplate = (ctx: IgcCellTemplateContext) =>
html`<span class=${ctx.implicit}>${ctx.implicit}</span>`;
```
**Header template migration:**
```typescript
// Before (Grid Lite) - no parameters
column.headerTemplate = () => html`<strong>Name</strong>`;
// After (Premium Grid) - receives IgcColumnTemplateContext
column.headerTemplate = (ctx: IgcColumnTemplateContext) =>
html`<strong>${ctx.column.header ?? ctx.column.field}</strong>`;
```
## Step 7 - Migrate Remote Data Operations
Grid Lite uses `dataPipelineConfiguration` (async callbacks). The Premium Grid uses **noop strategies + events**.
**Before (Grid Lite):**
```typescript
grid.dataPipelineConfiguration = {
sort: async ({ grid }) => dataService.sortRemote(grid.sortingExpressions),
filter: async ({ grid }) => dataService.filterRemote(grid.filterExpressions),
};
```
**After (Premium Grid):**
```typescript
const grid = document.getElementById('grid') as IgcGridComponent;
// Disable built-in sort/filter so the grid does not process data locally
grid.sortStrategy = IgcNoopSortingStrategy.instance();
grid.filterStrategy = IgcNoopFilteringStrategy.instance();
// React to done events and reload data from the server
grid.addEventListener('sortingDone', async () => {
grid.data = await dataService.sortRemote(grid.sortingExpressions);
});
grid.addEventListener('filteringDone', async () => {
grid.data = await dataService.filterRemote(grid.filteringExpressionsTree);
});
```
## Step 8 - Migrate Sort / Filter Events
| Grid Lite Event | Premium Grid Event | Notes |
|---|---|---|
| `sorting` | `sorting` | Same name - both cancellable (`e.detail.cancel = true`) |
| `sorted` | `sortingDone` | Name changed - `CustomEvent<IgcSortingExpression[]>` |
| `filtering` | `filtering` | Same name - both cancellable |
| `filtered` | `filteringDone` | Name changed - `CustomEvent<IgcFilteringExpressionsTree>` |
```typescript
// Cancel a sort before it applies
grid.addEventListener('sorting', (e: CustomEvent<IgcSortingEventArgs>) => {
e.detail.cancel = true;
});
// React after sort completes
grid.addEventListener('sortingDone', (e: CustomEvent<IgcSortingExpression[]>) => {
console.log('Sorted by', e.detail);
});
// Cancel a filter before it applies
grid.addEventListener('filtering', (e: CustomEvent<IgcFilteringEventArgs>) => {
e.detail.cancel = true;
});
// React after filter completes
grid.addEventListener('filteringDone', (e: CustomEvent<IgcFilteringExpressionsTree>) => {
console.log('Filter tree', e.detail);
});
```
## Step 9 - Migrate Programmatic Sort / Filter API
**Grid Lite API:**
```typescript
grid.sort({ key: 'name', direction: 'ascending' });
grid.filter({ key: 'age', condition: 'greaterThan', searchTerm: 21 });
grid.clearSort();
grid.clearFilter();
```
**Premium Grid API:**
```typescript
import { SortingDirection, IgcNumberFilteringOperand } from 'igniteui-webcomponents-grids';
// Sorting - fieldName + SortingDirection enum (Asc = 1, Desc = 2, None = 0)
grid.sort([{ fieldName: 'name', dir: SortingDirection.Asc, ignoreCase: true }]);
grid.clearSort('name'); // clear one column
grid.clearSort(); // clear all
// Filtering - positional arguments with typed operand instances
grid.filter('age', 21, IgcNumberFilteringOperand.instance().condition('greaterThan'), true);
grid.clearFilter('age'); // clear one column
grid.clearFilter(); // clear all
// Multi-column filtering via expression tree
const tree = new IgcFilteringExpressionsTree(FilteringLogic.And);
tree.filteringOperands.push({
fieldName: 'age',
condition: IgcNumberFilteringOperand.instance().condition('greaterThan'),
searchVal: 21,
ignoreCase: true,
});
grid.filteringExpressionsTree = tree;
```
**Key expression shape changes:**
| Aspect | Grid Lite | Premium Grid |
|---|---|---|
| Sort target field | `key` | `fieldName` |
| Sort direction | `direction: 'ascending'` (string) | `dir: SortingDirection.Asc` (enum) |
| Filter target field | `key` | `fieldName` |
| Filter search value | `searchTerm` | `searchVal` (expression tree) |
| Case sensitivity (sort) | `caseSensitive: true` | `ignoreCase: false` (**inverted**) |
| Case sensitivity (filter) | `caseSensitive: true` | `ignoreCase: false` (**inverted**) |
| Filter criteria | `criteria` string | `FilteringLogic` enum on the tree |
---
## Adding Enterprise Features Post-Migration
Once on the Premium Grid, enable the features that motivated the migration:
### Row Editing
```html
<igc-grid id="grid" row-editable="true" primary-key="id" height="600px">
<igc-column field="name" editable="true"></igc-column>
<igc-column field="price" data-type="number" editable="true"></igc-column>
</igc-grid>
```
> **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.
### Row Selection
```html
<igc-grid id="grid" row-selection="multiple" primary-key="id" height="600px">
<!-- columns -->
</igc-grid>
```
```typescript
grid.addEventListener('rowSelectionChanging', (e: CustomEvent<IgcRowSelectionEventArgs>) => {
console.log('Selected rows:', e.detail.added);
});
```
### Paging
```html
<igc-grid id="grid" primary-key="id" height="600px">
<!-- columns -->
<igc-paginator per-page="15"></igc-paginator>
</igc-grid>
```
### GroupBy
```html
<igc-grid id="grid" primary-key="id" height="600px">
<igc-column field="category" groupable="true"></igc-column>
</igc-grid>
```
```typescript
grid.groupBy([{ fieldName: 'category', dir: SortingDirection.Asc }]);
```
### Column Pinning
```typescript
const column = grid.getColumnByName('name');
column.pin(); // pin to start (default)
column.unpin();
```
### Summaries
```html
<igc-column field="price" data-type="number" has-summary="true"></igc-column>
```
### Toolbar (Column Hiding, Pinning, Export)
```html
<igc-grid id="grid" auto-generate="true" height="600px">
<igc-grid-toolbar>
<igc-grid-toolbar-title>My Grid</igc-grid-toolbar-title>
<igc-grid-toolbar-actions>
<igc-grid-toolbar-advanced-filtering></igc-grid-toolbar-advanced-filtering>
<igc-grid-toolbar-hiding></igc-grid-toolbar-hiding>
<igc-grid-toolbar-pinning></igc-grid-toolbar-pinning>
<igc-grid-toolbar-exporter></igc-grid-toolbar-exporter>
</igc-grid-toolbar-actions>
</igc-grid-toolbar>
<!-- columns -->
</igc-grid>
```
### Advanced Filtering Dialog
```typescript
grid.allowAdvancedFiltering = true;
grid.openAdvancedFilteringDialog();
```
### Excel-Style Filter UI
```typescript
grid.filterMode = 'excelStyleFilter'; // default is 'quickFilter'
```
### Batch Editing
```html
<igc-grid id="grid" batch-editing="true" row-editable="true" primary-key="id" height="600px">
<igc-column field="name" editable="true"></igc-column>
</igc-grid>
```
---
## Related Skills
- **[`igniteui-wc-integrate-with-framework`](../igniteui-wc-integrate-with-framework/SKILL.md)** - Framework integration setup
- **[`igniteui-wc-customize-component-theme`](../igniteui-wc-customize-component-theme/SKILL.md)** - Theming and styling
- **[`igniteui-wc-choose-components`](../igniteui-wc-choose-components/SKILL.md)** - Choosing the right grid component