UNPKG

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
--- 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