--- license: MIT name: igniteui-wc-migrate-grid-lite-to-premium description: "Step-by-step migration from igniteui-grid-lite (IgcGridLite, ) to the premium igniteui-webcomponents-grids data grid (IgcGridComponent, ), covering imports, class names, HTML tags, properties, events, templates, sorting, filtering, remote data, and theming API changes. WHEN TO USE: the user wants to upgrade from Grid Lite to the premium grid, or needs enterprise features Grid Lite lacks (editing, selection, paging, grouping, summaries, Excel export, state persistence). WHEN NOT TO USE: starting a new grid from scratch (use choose-components), migrating between other grids (Tree Grid, Hierarchical Grid, Pivot Grid) or across major versions of the same package, the project uses igniteui-angular or Blazor grids, or the user only needs theming (use customize-component-theme)." 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, ``) to the **Premium Data Grid** (`igniteui-webcomponents-grids`, commercially licensed, ``). 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` (``). 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 — import as an inline string so it can be injected into the shadow root (requires bundler support for ?inline, e.g. Vite) // Available: light|dark x bootstrap|material|fluent|indigo import gridTheme from 'igniteui-webcomponents-grids/grids/themes/light/material.css?inline'; ``` > **Grid inside a Shadow root — required step:** A bare CSS import lands in the document head and never reaches inside a Shadow root — the grid's internal structure and elements get no styles. Inject the theme as a ` > > `; > } > ``` ## Step 3 - Update HTML Tags | Grid Lite | Premium Grid | |---|---| | `` | `` | | `` | `` | | Bare boolean attrs (`sortable`, `filterable`, `hidden`) | Quoted values (`sortable="true"`, `filterable="true"`, `hidden="true"`) | | No grid-level filter toggle | `allow-filtering="true"` required on `` | | No height requirement | `height` attribute required for row virtualization | **Before:** ```html ``` **After:** ```html ``` > **Note:** `allow-filtering="true"` on `` 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` | Object with a `sort(...)` method (see below) - no base class to extend | | _(none)_ | `editable`, `pinned`, `groupable`, `hasSummary`, `disableHiding`, `disablePinning`, `selectable`, `searchable`, `formatter`, `minWidth`, `maxWidth` | Premium-only | **Custom sort strategy migration:** The Premium Grid has no exported base class for sort strategies: `IgcSortingStrategy` is exported as a type only, and the built-in default strategy is internal. A column's `sortStrategy` is any object with this method: ```typescript sort(data: any[], fieldName: string, dir: SortingDirection, ignoreCase: boolean, valueResolver: (record: any, fieldName: string, isDate?: boolean, isTime?: boolean) => any): any[] ``` It receives the whole data array and returns it sorted. Read cell values through `valueResolver`, not `record[fieldName]`, so nested fields (e.g. `address.city`) and date/time columns work. ```typescript // Before (Grid Lite) - function comparer on column column.sortConfiguration = { comparer: (a, b) => a.length - b.length }; // After (Premium Grid) - object implementing sort() import { SortingDirection } from 'igniteui-webcomponents-grids'; class LengthSort { sort(data: any[], fieldName: string, dir: SortingDirection, _ignoreCase: boolean, valueResolver: (record: any, fieldName: string, isDate?: boolean, isTime?: boolean) => any) { const factor = dir === SortingDirection.Desc ? -1 : 1; const len = (record: any) => String(valueResolver(record, fieldName) ?? '').length; return [...data].sort((a, b) => factor * (len(a) - len(b))); } } 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`${ctx.value}`; // After (Premium Grid) column.bodyTemplate = (ctx: IgcCellTemplateContext) => html`${ctx.implicit}`; ``` **Header template migration:** ```typescript // Before (Grid Lite) - no parameters column.headerTemplate = () => html`Name`; // After (Premium Grid) - receives IgcColumnTemplateContext column.headerTemplate = (ctx: IgcColumnTemplateContext) => html`${ctx.column.header ?? ctx.column.field}`; ``` ## 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` | | `filtering` | `filtering` | Same name - both cancellable | | `filtered` | `filteringDone` | Name changed - `CustomEvent` | ```typescript // Cancel a sort before it applies grid.addEventListener('sorting', (e: CustomEvent) => { e.detail.cancel = true; }); // React after sort completes grid.addEventListener('sortingDone', (e: CustomEvent) => { console.log('Sorted by', e.detail); }); // Cancel a filter before it applies grid.addEventListener('filtering', (e: CustomEvent) => { e.detail.cancel = true; }); // React after filter completes grid.addEventListener('filteringDone', (e: CustomEvent) => { 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 ``` > **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 ``` ```typescript grid.addEventListener('rowSelectionChanging', (e: CustomEvent) => { console.log('Selected rows:', e.detail.added); }); ``` ### Paging ```html ``` ### GroupBy ```html ``` ```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 ``` ### Toolbar (Column Hiding, Pinning, Export) ```html My Grid ``` ### Advanced Filtering Dialog ```typescript grid.allowAdvancedFiltering = true; grid.openAdvancedFilteringDialog(); ``` ### Excel-Style Filter UI ```typescript grid.filterMode = 'excelStyleFilter'; // default is 'quickFilter' ``` ### Batch Editing ```html ``` --- ## 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