From f649a8ccb2c561c7cad5c5b8e8b99931c8822b21 Mon Sep 17 00:00:00 2001 From: Konstantin Dinev Date: Tue, 11 Aug 2026 16:26:21 +0300 Subject: [PATCH] feat(skills): reducing the size of skills and updating for correctness --- CHANGELOG.md | 17 + skills/README.md | 113 ++--- .../grid-lite-to-igr-grid-migration/SKILL.md | 289 ++++------- skills/igniteui-react-components/SKILL.md | 185 ++------ .../reference/CHARTS-GRIDS.md | 398 ---------------- .../reference/COMPONENT-CATALOGUE.md | 161 ------- .../reference/COMPONENTS.md | 65 +++ .../reference/DATAVIZ.md | 90 ++++ .../reference/EVENT-HANDLING.md | 72 --- .../reference/INSTALLATION.md | 139 ------ .../reference/JSX-PATTERNS.md | 187 -------- .../reference/MCP-SERVER.md | 77 --- .../reference/MCP.md | 43 ++ .../reference/REFS-FORMS.md | 232 --------- .../reference/TROUBLESHOOTING.md | 162 +------ .../reference/USAGE.md | 85 ++++ .../igniteui-react-customize-theme/SKILL.md | 218 ++++----- .../reference/CSS-THEMING.md | 269 ++--------- .../reference/MCP-SERVER.md | 67 --- .../reference/TROUBLESHOOTING.md | 35 -- .../SKILL.md | 245 +++------- .../reference/component-mapping.md | 132 ----- .../reference/gotchas.md | 209 +++----- .../SKILL.md | 449 ++---------------- 24 files changed, 778 insertions(+), 3161 deletions(-) delete mode 100644 skills/igniteui-react-components/reference/CHARTS-GRIDS.md delete mode 100644 skills/igniteui-react-components/reference/COMPONENT-CATALOGUE.md create mode 100644 skills/igniteui-react-components/reference/COMPONENTS.md create mode 100644 skills/igniteui-react-components/reference/DATAVIZ.md delete mode 100644 skills/igniteui-react-components/reference/EVENT-HANDLING.md delete mode 100644 skills/igniteui-react-components/reference/INSTALLATION.md delete mode 100644 skills/igniteui-react-components/reference/JSX-PATTERNS.md delete mode 100644 skills/igniteui-react-components/reference/MCP-SERVER.md create mode 100644 skills/igniteui-react-components/reference/MCP.md delete mode 100644 skills/igniteui-react-components/reference/REFS-FORMS.md create mode 100644 skills/igniteui-react-components/reference/USAGE.md delete mode 100644 skills/igniteui-react-customize-theme/reference/MCP-SERVER.md delete mode 100644 skills/igniteui-react-customize-theme/reference/TROUBLESHOOTING.md delete mode 100644 skills/igniteui-react-generate-from-image-design/reference/component-mapping.md diff --git a/CHANGELOG.md b/CHANGELOG.md index e2dfeb3..77ec572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ ## Unreleased +### Changed +- Skills: + - Condensed all React skills to the framework-specific facts an agent cannot infer, cutting total size roughly in half. Reference files were consolidated (`COMPONENTS`, `USAGE`, `DATAVIZ`, `MCP`, `TROUBLESHOOTING`) and duplicated setup/theming guidance removed. + - Documented MCP tools with their real named-argument schemas, including that doc tools take `framework` while API tools take `platform`, and added `get_project_setup_guide`. + - Documented dark mode as a global switch driven by `--ig-theme-variant` plus `configureTheme()`, rather than a scopable set of custom properties. + - Added the Grid Lite to premium grid migration skill to the skills README. + +### Fixed +- Skills: + - Corrected the palette override mechanism: shades derive from the `500` shade (e.g. `--ig-primary-500`). The previously documented `--ig-primary-h` / `-s` / `-l` tokens do not exist and silently did nothing. + - Removed `IgrGridModule.register()` from the grid migration guidance — module registration is deprecated and handled by the React wrapper on import. + - Corrected the Excel/CSV exporter import path to `igniteui-react-grids`. + - Replaced the non-existent `--ig-button-foreground` token example, and directed component-level theming at `get_component_design_tokens` or the `@cssproperty` annotations. + - Corrected the form submit handler type to `React.FormEvent`, and event handler types to the generated `Igr*EventArgs` aliases. + - Replaced the non-existent `get_theming_guidance` tool with `read_resource`. + - Fixed a broken reference link in the components skill. + ## 19.8.1 - 2026-07-13 ### Changed diff --git a/skills/README.md b/skills/README.md index ab1ae69..45dd477 100644 --- a/skills/README.md +++ b/skills/README.md @@ -1,98 +1,45 @@ -# LLM Agent Skills for Ignite UI for React +# Agent Skills for Ignite UI for React -This directory contains skills for GitHub Copilot and other LLM agents to help developers use **Ignite UI for React** effectively in their applications. +Task-focused instructions that help AI coding agents use **Ignite UI for React** correctly — component selection, setup, theming, performance, and migration. Each skill is self-contained and framework-specific. -## What are Skills? +## Available skills -Skills are structured instructions that help AI agents understand and execute common tasks consistently. Each skill is a self-contained guide that provides step-by-step instructions, code examples, and best practices — all specific to React and the `igniteui-react` family of packages. +| Skill | Use when | +| --- | --- | +| [igniteui-react-components](./igniteui-react-components/SKILL.md) | Choosing an `Igr*` component, setting up `igniteui-react`, writing JSX, wiring events/refs/forms, or debugging components that render unstyled or invisible | +| [igniteui-react-customize-theme](./igniteui-react-customize-theme/SKILL.md) | Applying brand colors, switching light/dark, overriding component appearance | +| [igniteui-react-optimize-bundle-size](./igniteui-react-optimize-bundle-size/SKILL.md) | The bundle is too large, or grids/charts are in the initial chunk | +| [igniteui-react-generate-from-image-design](./igniteui-react-generate-from-image-design/SKILL.md) | Building a view from a screenshot, mockup, or wireframe | +| [grid-lite-to-igr-grid-migration](./grid-lite-to-igr-grid-migration/SKILL.md) | Grid Lite lacks a needed feature — editing, selection, paging, grouping, export | -## Available Skills +Agents pick a skill from the request, so ordinary questions are enough: *"add a data grid to my React app"*, *"build this dashboard screenshot"*, *"match our brand colors"*, *"my bundle is too large"*. Naming a skill directly also works: *"use the igniteui-react-customize-theme skill"*. -| Skill | Description | Use When | -| --- | --- | --- | -| [igniteui-react-components](./igniteui-react-components/SKILL.md) | Identify the right React components (`Igr*`) for a UI pattern, then install, import, and use them - JSX patterns, events, refs, forms | Choosing components or setting up and using them in React | -| [igniteui-react-customize-theme](./igniteui-react-customize-theme/SKILL.md) | Customize styling using CSS custom properties, Sass, and the theming system in a React context | Applying custom brand colors/styles | -| [igniteui-react-optimize-bundle-size](./igniteui-react-optimize-bundle-size/SKILL.md) | Reduce bundle size with granular imports, tree-shaking, and lazy loading | Optimizing production performance | -| [igniteui-react-generate-from-image-design](./igniteui-react-generate-from-image-design/SKILL.md) | Build a React view from a screenshot or mockup using Ignite UI components plus MCP-first theming and token mapping | Converting a design image into a working Ignite UI React page or dashboard | +## MCP servers -## How to Use +Two optional MCP servers make the agent's answers authoritative rather than recalled: -When working with an AI agent like GitHub Copilot, reference skills by name or ask questions naturally: +- **`igniteui-cli`** — component docs and API reference (`list_components`, `get_doc`, `get_api_reference`, `search_docs`, `search_api`) +- **`igniteui-theming`** — palette, typography, elevation, and per-component theme generation -### Natural Questions +Every skill works without them, falling back to the type declarations in `node_modules`. Setup instructions are in [igniteui-react-components/reference/MCP.md](./igniteui-react-components/reference/MCP.md) and the theming skill. -- "How do I add a data grid to my React app?" -- "What Ignite UI component should I use for a date picker?" -- "Build this dashboard screenshot in Ignite UI React" -- "Help me customize the button colors to match my brand" -- "My bundle size is too large, how can I reduce it?" -- "How do I handle events on IgrCombo?" +## Installation -### Direct Skill Reference +Copy the skill folders into the directory your agent reads: -- "Follow the igniteui-react-components skill for setting up my project" -- "Use the igniteui-react-generate-from-image-design skill for this mockup" -- "Use the igniteui-react-customize-theme skill to help me style components" -- "Apply the igniteui-react-optimize-bundle-size skill to reduce my bundle" +| Agent | Directory | +| --- | --- | +| Claude Code | `.claude/skills/` | +| GitHub Copilot | `.agents/skills/` | +| Cursor, Windsurf, others | see the agent's documentation | -## Skill Structure - -Each skill contains: - -- **Example Usage**: Common questions or scenarios -- **When to Use**: Situations where the skill applies -- **Related Skills**: Other relevant skills to explore -- **Step-by-Step Instructions**: Detailed guidance with code examples -- **Common Issues & Solutions**: Troubleshooting guidance -- **Best Practices**: Recommended approaches -- **Additional Resources**: Further reading and documentation - -## Editor / Agent Setup - -Most modern AI assistants (GitHub Copilot, Cursor, Windsurf, Claude Code, etc.) should auto-discover these skills from a specified location in the workspace or global profile. - -For example, you can copy them into the agent-specific skills folder for your editor: - -### GitHub Copilot - -Copy the skill files into your project's `.agents/skills/` directory: +Keep each skill's `SKILL.md` alongside its `reference/` folder — the reference files are loaded on demand and the relative links between skills assume the layout is preserved. ``` -.agents/ - skills/ - igniteui-react-components/ - SKILL.md - reference/ - igniteui-react-customize-theme/ - SKILL.md - reference/ - igniteui-react-optimize-bundle-size/ - SKILL.md - igniteui-react-generate-from-image-design/ - SKILL.md - references/ +.claude/skills/ + igniteui-react-components/{SKILL.md,reference/} + igniteui-react-customize-theme/{SKILL.md,reference/} + igniteui-react-optimize-bundle-size/SKILL.md + igniteui-react-generate-from-image-design/{SKILL.md,reference/} + grid-lite-to-igr-grid-migration/SKILL.md ``` - -### Claude Code - -Copy the skill files into your project's `.claude/skills/` directory: - -``` -.claude/ - skills/ - igniteui-react-components/ - SKILL.md - reference/ - igniteui-react-customize-theme/ - SKILL.md - reference/ - igniteui-react-optimize-bundle-size/ - SKILL.md - igniteui-react-generate-from-image-design/ - SKILL.md - references/ -``` - -### Other Agents (Cursor, Windsurf, etc.) - -Consult your agent's documentation for the correct skills directory path and copy the skill files there. The skill structure is agent-agnostic — any assistant that supports skill files can use them directly. diff --git a/skills/grid-lite-to-igr-grid-migration/SKILL.md b/skills/grid-lite-to-igr-grid-migration/SKILL.md index bbedeee..474b0d4 100644 --- a/skills/grid-lite-to-igr-grid-migration/SKILL.md +++ b/skills/grid-lite-to-igr-grid-migration/SKILL.md @@ -1,240 +1,138 @@ --- name: grid-lite-to-igr-grid-migration -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. +description: Migrate from Grid Lite (IgrGridLite) to the premium Ignite UI for React Data Grid (IgrGrid) — imports, theme CSS, column and template API changes, sorting and filtering, remote data replacing dataPipelineConfiguration, and the toolbar/export APIs. Use when Grid Lite lacks a needed feature such as editing, selection, paging, grouping, summaries, pinning, or export. user-invocable: true --- -# Ignite UI for React — Grid Lite → Premium Data Grid Migration +# Grid Lite → Premium Data Grid -## MANDATORY AGENT PROTOCOL +Read the user's current Grid Lite usage first — columns, templates, data binding, `dataPipelineConfiguration` — then confirm APIs with `get_doc({ framework: 'react', name: 'grid-editing' })` or `get_api_reference({ platform: 'react', component: 'IgrGrid' })` rather than from memory. Grid APIs change between versions. -> **DO NOT write any code from memory.** Grid APIs change between versions. +## Is the migration warranted? -Before producing migration code: +Grid Lite has none of these; each is a valid reason to move: -1. **Read the user's existing component files** to understand current Grid Lite usage (columns, templates, data binding, `dataPipelineConfiguration`). -2. **Use the MCP server** — call `get_doc` or `search_docs` with `framework: "react"` to confirm API details when in doubt. -3. **Only then produce output** — base all code on verified references, not memory. +| Feature | `IgrGrid` | +|---|---| +| Cell / row editing | `editable` on the column, `rowEditable` on the grid | +| Batch editing with undo | transaction service | +| Row add / delete | `rowEditable` + `IgrActionStrip` | +| Row / cell / column selection | `rowSelection`, `cellSelection`, `columnSelection` | +| Paging | `IgrPaginator` child | +| Grouping | `groupingExpressions` | +| Summaries | `hasSummary` on the column | +| Column pinning / moving / hiding | `pinned`, `moving`, toolbar actions | +| Master-detail, hierarchical rows | row expansion, `IgrTreeGrid`, `IgrHierarchicalGrid` | +| Excel / CSV export | `IgrGridToolbarExporter` | +| Advanced filtering UI | `filterMode="excelStyleFilter"`, `IgrGridToolbarAdvancedFiltering` | +| State persistence | `IgrGridState` | +| Row drag and drop | `rowDraggable` | ---- - -## When to Migrate from Grid Lite to Premium Grid - -Migrate when you need any of the following features (not available in Grid Lite): - -| Feature | Grid Lite | Premium Grid (`IgrGrid`) | -|---|---|---| -| Cell editing | ✗ | ✓ `editable`, `rowEditable` | -| Batch editing (with undo) | ✗ | ✓ Transaction service | -| Row adding / deleting | ✗ | ✓ `rowEditable` + `IgrActionStrip` | -| Row selection | ✗ | ✓ `rowSelection="single|multiple"` | -| Cell selection | ✗ | ✓ `cellSelection` | -| Column selection | ✗ | ✓ `columnSelection` | -| Paging | ✗ | ✓ `IgrPaginator` child | -| GroupBy | ✗ | ✓ `groupingExpressions` | -| Column summaries | ✗ | ✓ `hasSummary` on `IgrColumn` | -| Column pinning | ✗ | ✓ `pinned` on `IgrColumn` | -| Column moving | ✗ | ✓ `moving={true}` on grid | -| Master-detail rows | ✗ | ✓ `IgrGrid` row expansion | -| Excel / CSV export (toolbar) | ✗ | ✓ `IgrGridToolbarExporter` | -| Column hiding toolbar | ✗ | ✓ `IgrGridToolbarHiding` | -| Column pinning toolbar | ✗ | ✓ `IgrGridToolbarPinning` | -| Advanced filtering UI | ✗ | ✓ `filterMode="excelStyleFilter"` / `IgrGridToolbarAdvancedFiltering` | -| State persistence | ✗ | ✓ `IgrGridState` directive | -| Clipboard operations | ✗ | ✓ `clipboardOptions` | -| Action strip | ✗ | ✓ `IgrActionStrip` | -| Row drag and drop | ✗ | ✓ `rowDraggable={true}` | - ---- +If none applies, staying on Grid Lite is lighter — see [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md). ## Setup ```bash -npm install --save igniteui-react-grids -# licensed: npm install --save @infragistics/igniteui-react-grids +npm install --save igniteui-react-grids # or @infragistics/igniteui-react-grids when licensed ``` ```tsx -import { IgrGridModule, IgrGrid, IgrColumn, IgrPaginator, - IgrCellTemplateContext, IgrColumnTemplateContext } from "igniteui-react-grids"; -import "igniteui-react-grids/grids/themes/light/bootstrap.css"; - -// Required once before render — Grid Lite has no equivalent -IgrGridModule.register(); +import { IgrGrid, IgrColumn } from 'igniteui-react-grids'; +import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; // in addition to the base theme ``` -> Use `@infragistics/igniteui-react-grids` and the matching CSS path for the licensed package. -> Check `package.json` — `igniteui-grid-lite` may be a standalone dependency alongside `igniteui-react`. - ---- +**No registration.** `IgrGridModule.register()` is deprecated and unnecessary — the React wrapper registers the element on import. Do not add it, and delete it if present. -## Minimal Migration Example +## Minimal port ```tsx -import { useRef, useState } from "react"; -import { IgrGrid, IgrColumn, IgrGridModule } from "igniteui-react-grids"; -import "igniteui-react-grids/grids/themes/light/bootstrap.css"; -IgrGridModule.register(); +import { useRef, useState } from 'react'; +import { IgrGrid, IgrColumn } from 'igniteui-react-grids'; +import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; -export default function MyView() { - const gridRef = useRef(null); - const [data] = useState([]); +export default function Products({ data }: { data: Product[] }) { + const grid = useRef(null); return ( - - - + + ); } ``` -**Key additions vs Grid Lite:** -- `primaryKey` — required for editing, selection, row-targeted APIs -- `height` — required for row virtualization -- `allowFiltering={true}` on the grid — required for filter UI; `filterable={true}` on the column opts that column in +Three additions Grid Lite did not need: ---- +- `primaryKey` — required for editing, selection, and any row-targeted API. +- `height` — required for row virtualization; without it the grid renders no rows. +- `allowFiltering` on the grid **and** `filterable` on each column — the grid-level flag alone shows no UI. -## Cell Templates +As in Grid Lite, **do not set column `width`** unless the user asked; `IgrColumn` sizes itself and fixed widths leave dead space. -Prop renamed: `cellTemplate` → `bodyTemplate`. Context type changes. +## API renames -```tsx -import { IgrCellTemplateContext } from "igniteui-react-grids"; - -const statusCell = (ctx: IgrCellTemplateContext) => ( - - {ctx.cell.value} - -); - - -``` - -| | Grid Lite | Premium Grid | +| | Grid Lite | `IgrGrid` | |---|---|---| -| Prop | `cellTemplate` | `bodyTemplate` | -| Value | `ctx.value` | `ctx.cell.value` or `ctx.implicit` | +| Cell template prop | `cellTemplate` | `bodyTemplate` | +| Cell context type | `IgrCellContext` | `IgrCellTemplateContext` | +| Cell value | `ctx.value` | `ctx.cell.value` (or `ctx.implicit`) | | Row data | `ctx.row.data` | `ctx.cell.row.data` | -| Edit template | — | `inlineEditorTemplate` | - ---- - -## Header Templates - -Prop name unchanged (`headerTemplate`); context type changes to `IgrColumnTemplateContext` from `igniteui-react-grids`. +| Header context type | `IgrHeaderContext` | `IgrColumnTemplateContext` | +| Header prop | `headerTemplate` | `headerTemplate` (unchanged) | +| Editor template | — | `inlineEditorTemplate` | +| Sorting expression | `{ key, direction: 'ascending' }` | `{ fieldName, dir: SortingDirection.Asc }` | +| Remote data | `dataPipelineConfiguration` | noop strategies + done events | ```tsx -import { IgrColumnTemplateContext } from "igniteui-react-grids"; +import { type IgrCellTemplateContext, IgrColumn } from 'igniteui-react-grids'; -const priceHeader = (ctx: IgrColumnTemplateContext) => ( - {ctx.column.header} +const status = (ctx: IgrCellTemplateContext) => ( + {ctx.cell.value} ); - -``` - ---- - -## Remote Data (replaces `dataPipelineConfiguration`) - -For server-side operations, disable local sort/filter processing first by assigning noop strategies, then listen to the done events to issue new requests. - -```tsx -import { IgrGrid, IgrGridModule, - IgrNoopSortingStrategy, IgrNoopFilteringStrategy } from "igniteui-react-grids"; - -// Disable built-in sort/filter so the grid does not process data locally. -// Set these once after the grid mounts (e.g., in a useEffect or ref callback). -useEffect(() => { - if (!gridRef.current) return; - gridRef.current.sortStrategy = IgrNoopSortingStrategy.instance(); - gridRef.current.filterStrategy = IgrNoopFilteringStrategy.instance(); -}, []); -``` - -```tsx -const handleSortingDone = async () => { - if (!gridRef.current) return; - setData(await dataService.sort(gridRef.current.sortingExpressions)); -}; -const handleFilteringDone = async () => { - if (!gridRef.current) return; - setData(await dataService.filter(gridRef.current.filteringExpressionsTree)); -}; - - - {/* columns */} - + ``` ---- +Note the context types are no longer generic over the row type. -## Programmatic Sort / Filter +## Programmatic sort and filter ```tsx -import { SortingDirection, IgrNumberFilteringOperand } from "igniteui-react-grids"; +import { SortingDirection, IgrNumberFilteringOperand } from 'igniteui-react-grids'; -// fieldName + SortingDirection enum (not key + string) -gridRef.current.sort([{ fieldName: 'name', dir: SortingDirection.Asc, ignoreCase: true }]); -gridRef.current.clearSort('name'); // or clearSort() for all +grid.current.sort([{ fieldName: 'name', dir: SortingDirection.Asc, ignoreCase: true }]); +grid.current.clearSort('name'); // or clearSort() for all -// Positional args with operand -// Note: verify IgrNumberFilteringOperand.instance() is available in your version -gridRef.current.filter('age', 21, IgrNumberFilteringOperand.instance().condition('greaterThan')); -gridRef.current.clearFilter('age'); // or clearFilter() for all +grid.current.filter('age', 21, IgrNumberFilteringOperand.instance().condition('greaterThan')); +grid.current.clearFilter('age'); ``` ---- +Operands are available per data type: `IgrStringFilteringOperand`, `IgrNumberFilteringOperand`, `IgrBooleanFilteringOperand`, `IgrDateFilteringOperand`, `IgrDateTimeFilteringOperand`, `IgrTimeFilteringOperand`. -## Common Enterprise Features - -### Editing - -```tsx - - - -``` +## Remote data (replacing `dataPipelineConfiguration`) -### Row Selection +Assign noop strategies so the grid stops processing locally, then re-fetch on the done events. ```tsx - - {/* columns */} - -// Read: gridRef.current.selectedRows -``` - -### Paging +import { IgrNoopSortingStrategy, IgrNoopFilteringStrategy } from 'igniteui-react-grids'; -```tsx - - - -``` - -### Summaries +useEffect(() => { + if (!grid.current) return; + grid.current.sortStrategy = IgrNoopSortingStrategy.instance(); + grid.current.filterStrategy = IgrNoopFilteringStrategy.instance(); +}, []); -```tsx - + setData(await api.sort(grid.current!.sortingExpressions))} + onFilteringDone={async () => setData(await api.filter(grid.current!.filteringExpressionsTree))}> ``` -### Toolbar + Export - -> **Note:** `IgrExcelExporterService` / `IgrExcelExporterOptions` (programmatic export) must be imported from `"igniteui-react"`, **not** `"igniteui-react-grids"`. The toolbar approach below does not need them. +## Toolbar and export ```tsx -import { IgrGrid, IgrColumn, IgrGridToolbar, IgrGridToolbarTitle, - IgrGridToolbarActions, IgrGridToolbarHiding, IgrGridToolbarPinning, - IgrGridToolbarExporter, IgrGridToolbarAdvancedFiltering, - IgrGridToolbarExportEventArgs, IgrGridModule } from "igniteui-react-grids"; -IgrGridModule.register(); - - + Products @@ -244,31 +142,40 @@ IgrGridModule.register(); - {/* columns */} ``` ```tsx -const handleExporting = (e: IgrGridToolbarExportEventArgs) => { - e.detail.options.fileName = "MyExport"; - // set e.detail.cancel = true to abort +const onExporting = (e: IgrGridToolbarExportEventArgs) => { + e.detail.options.fileName = 'products'; + // e.detail.cancel = true to abort }; ``` ---- +For programmatic export, `IgrExcelExporterService` / `IgrExcelExporterOptions` and the CSV equivalents come from **`igniteui-react-grids`** — the same package as the grid. -## Cleanup After Migration +## Other feature snippets -1. Remove all `dataPipelineConfiguration` usage — replace with events (see Remote Data). -2. Remove `IgrCellContext` / `IgrHeaderContext` imports from `igniteui-react/grid-lite`. -3. Uninstall `igniteui-grid-lite` if no Grid Lite instances remain: `npm uninstall igniteui-grid-lite`. +```tsx + + + + ---- + {/* grid.current.selectedRows */} + + +``` -## Related Skills +## Cleanup + +1. Remove `dataPipelineConfiguration` and any hooks it used. +2. Remove `IgrCellContext` / `IgrHeaderContext` imports from `igniteui-react/grid-lite`. +3. Remove any `IgrGridModule.register()` calls. +4. `npm uninstall igniteui-grid-lite` once no `IgrGridLite` instances remain. +5. Keep the base theme CSS; add the grid theme CSS. -- [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. -- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — Customize `IgrGrid` styling using CSS custom properties and the Ignite UI theming system. -- [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. -- [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. +## Related skills +- [igniteui-react-components](../igniteui-react-components/SKILL.md) — the wider grid feature set, events, refs +- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — grid tokens such as `--ig-grid-header-background` diff --git a/skills/igniteui-react-components/SKILL.md b/skills/igniteui-react-components/SKILL.md index 133a644..8e78088 100644 --- a/skills/igniteui-react-components/SKILL.md +++ b/skills/igniteui-react-components/SKILL.md @@ -1,181 +1,72 @@ --- name: igniteui-react-components -description: This skill identifies the right Ignite UI for React components for any UI pattern and covers installing, importing, and using them — including JSX patterns, event handling, refs, forms, and TypeScript. Use this when choosing components, setting up a React project, writing component JSX, handling events, or integrating with React state and form libraries. +description: Pick, install, and use Ignite UI for React (Igr*) components — package routing, theme CSS, JSX and slots, events, refs, forms, TypeScript, charts/gauges/maps, grids. Use when choosing a component for a UI pattern, setting up igniteui-react, writing Igr* JSX, wiring events or refs, or debugging components that render unstyled, invisible, or with broken icons. user-invocable: true --- # Ignite UI for React Components -## Prerequisites +`Igr*` components are React wrappers around `igc-*` web components. Everything below follows from that. -- The **Ignite UI CLI MCP server** (`igniteui-cli`) available as a tool provider +## Non-negotiables -> **AGENT INSTRUCTION — MCP Server Setup (REQUIRED)** -> -> Before using the Ignite UI CLI MCP tools, you MUST verify the MCP server is available -> by calling `list_components`. If the tool is not available or the call fails, -> you MUST automatically configure it by following the setup process steps described below. -> -> After writing the file, inform the user that the MCP server has been -> configured and they may need to reload the editor for the tools to activate. -> Start the MCP server and wait for that MCP server to start before continuing the component-related work. -> Do NOT skip this step or ask the user to do it manually. +1. **Import a theme CSS file** or components render unstyled with broken icons. +2. **No `.register()`** for `igniteui-react`, `igniteui-react-grids`, `igniteui-react/grid-lite`, or `igniteui-react-dockmanager` — the wrapper registers the element on import. Charts, gauges, and maps (separate legacy packages) **do** require `.register()`. +3. **CSS selectors must target `igc-*`**, never `IgrButton`. Use `::part()` for shadow DOM internals. +4. **Events are `CustomEvent`**, not React `SyntheticEvent`. Read `e.detail`. +5. **Never set column `width`** on `IgrColumn` / `IgrGridLiteColumn` unless asked — see [DATAVIZ.md](./reference/DATAVIZ.md). +6. **Charts, gauges, maps, and grids need an explicitly sized container** or they render at zero height. -## Setting Up the Ignite UI CLI MCP Server +## Packages -> **Full setup instructions for VS Code, Cursor, Claude Desktop, and JetBrains IDEs are in [`reference/MCP-SERVER.md`](./reference/MCP-SERVER.md).** Read that file for editor-specific configuration steps and verification. - -### Package Routing - -| Component family | Install packages | Import from | -|---|---|---| -| Core UI components | `igniteui-react` | `igniteui-react` | -| Advanced grids | `igniteui-react-grids` (trial) `@infragistics/igniteui-react-grids` (licensed) | `igniteui-react-grids` | -| Grid Lite | `igniteui-react`, `igniteui-grid-lite` | `igniteui-react`, `igniteui-grid-lite` | -| Charts | `igniteui-react-charts` (trial) `@infragistics/igniteui-react-charts` (licensed) | `igniteui-react-charts` | -| Gauges | `igniteui-react-gauges` (trial) `@infragistics/igniteui-react-gauges` (licensed) | `igniteui-react-gauges` | -| Maps | `igniteui-react-maps` (trial) `@infragistics/igniteui-react-maps` (licensed) | `igniteui-react-maps` | -## Example Usage - -- "What component should I use to display a list of items with actions?" -- "I need a date picker for a booking form in React" -- "Build a dashboard layout with cards and a data grid" -- "What's the best component for a navigation sidebar?" -- "I need a searchable dropdown with multi-select" -- "How do I install Ignite UI for React?" -- "Set up igniteui-react in my project" -- "How do I handle events on IgrCombo?" -- "How do I use IgrInput with React Hook Form?" -- "Show me how to use refs with IgrDialog" -- "What TypeScript types should I use for IgrButton props?" -- "How do I pass children vs slots to Ignite UI components?" - -## Related Skills - -- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — Theme and style components -- [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md) — Reduce bundle size - -## When to Use - -- Deciding which component fits a UI requirement -- User describes a UI pattern and needs a matching component name -- User wants to explore what components are available -- Setting up Ignite UI for React in a new or existing project -- Writing JSX that uses Ignite UI components -- Handling events from Ignite UI components -- Integrating components with React state or form libraries -- Using refs to call imperative methods on components -- Working with TypeScript prop types - ---- - -## Content Guide - -This skill is organized into focused reference files. Load the appropriate file for the situation: - -| Topic | File | When to Use | +| Need | Install | Import from | |---|---|---| -| Component Catalogue | [COMPONENT-CATALOGUE.md](./reference/COMPONENT-CATALOGUE.md) | Mapping UI patterns to components, available packages, common UI scenarios | -| Installation & Setup | [INSTALLATION.md](./reference/INSTALLATION.md) | Setting up packages, importing theme CSS, Next.js setup | -| JSX Patterns | [JSX-PATTERNS.md](./reference/JSX-PATTERNS.md) | Props, children, slots, IgrTabs content vs navigation | -| Event Handling | [EVENT-HANDLING.md](./reference/EVENT-HANDLING.md) | Event props, CustomEvent types, common events | -| Refs & Forms | [REFS-FORMS.md](./reference/REFS-FORMS.md) | useRef, controlled/uncontrolled forms, React Hook Form | -| Charts, Gauges, Maps & Grid Lite | [CHARTS-GRIDS.md](./reference/CHARTS-GRIDS.md) | Module registration, container sizing | -| Troubleshooting | [TROUBLESHOOTING.md](./reference/TROUBLESHOOTING.md) | Common issues and solutions | - ---- +| Core UI (MIT) | `igniteui-react` | `igniteui-react` | +| Grid Lite (MIT) | `igniteui-react` **+** `igniteui-grid-lite` | `igniteui-react/grid-lite` | +| Data/Tree/Pivot/Hierarchical Grid | `igniteui-react-grids` | `igniteui-react-grids` | +| Dock Manager | `igniteui-react-dockmanager` | `igniteui-react-dockmanager` | +| Charts, gauges, maps | `igniteui-react-charts` / `-gauges` / `-maps` | same | -## Quick Start +Commercial packages also publish under `@infragistics/…` for licensed workspaces; use that scope and its matching CSS path when the workspace already uses it. `igniteui-grid-lite` is an optional peer of `igniteui-react` — Grid Lite needs both installed. -### 1. Install +## Quick start ```bash npm install igniteui-react ``` -### 2. Import Theme CSS (REQUIRED) - ```tsx -// main.tsx +// main.tsx — theme first, your overrides after import 'igniteui-webcomponents/themes/light/bootstrap.css'; ``` -> **CRITICAL:** Without the theme CSS, components will render without styles and icons will be broken. See [INSTALLATION.md](./reference/INSTALLATION.md) for all available themes and setup. - -### 3. Use Components - ```tsx import { IgrButton, IgrInput } from 'igniteui-react'; -function App() { - return ( -
- - Submit -
- ); -} + +Submit ``` -> **No `defineComponents()` needed.** React wrappers auto-register. See [CHARTS-GRIDS.md](./reference/CHARTS-GRIDS.md) for exceptions (charts, gauges, maps). - ---- - -## Key Concepts - -### Choosing the Right Component - -Use [COMPONENT-CATALOGUE.md](./reference/COMPONENT-CATALOGUE.md) to map any UI need to the right `Igr*` component and package. For quick guidance: - -- **MIT package** (`igniteui-react`) — inputs, buttons, layout, navigation, notifications, scheduling, AI chat -- **Lightweight grid** (MIT) — `IgrGridLite` from `igniteui-react/grid-lite` (requires both `igniteui-react` and `igniteui-grid-lite`) -- **Commercial** — `igniteui-react-grids` (advanced grids), `igniteui-react-charts`, `igniteui-react-gauges`, `igniteui-react-maps` - -### Theme CSS Import - -- **Always import theme CSS** before using components. **For grids**, also import `igniteui-react-grids/grids/themes/...` -- see [INSTALLATION.md](./reference/INSTALLATION.md) +Themes: `igniteui-webcomponents/themes/{light|dark}/{bootstrap|material|fluent|indigo}.css`. +**Grids need a second import**: `igniteui-react-grids/grids/themes/{light|dark}/.css`. +Next.js has no single entry point — import the theme CSS in `app/layout.tsx` or in each `'use client'` file that uses components. -### JSX Patterns +## Reference -- Use props just like any React component -- Use `slot` attribute for named slots: `📊` -- See [JSX-PATTERNS.md](./reference/JSX-PATTERNS.md) +| File | Load when | +|---|---| +| [COMPONENTS.md](./reference/COMPONENTS.md) | Choosing a component for a described UI pattern | +| [USAGE.md](./reference/USAGE.md) | Writing JSX — slots, events, refs, forms, TypeScript | +| [DATAVIZ.md](./reference/DATAVIZ.md) | Charts, gauges, maps, Grid Lite, grid columns | +| [MCP.md](./reference/MCP.md) | Looking up authoritative API docs; setting up the MCP server | +| [TROUBLESHOOTING.md](./reference/TROUBLESHOOTING.md) | Something renders wrong | -### IgrTabs: Content vs Navigation +## Verify before you write -- **Content panels**: Use `IgrTab` with inline content (label via `label` prop or `slot="label"`) -- **Navigation (router)**: Use **only `IgrTab`** with label-only (no inline content) -- See [JSX-PATTERNS.md](./reference/JSX-PATTERNS.md) +Component APIs change between versions. Prefer the `igniteui-cli` MCP server (`get_doc`, `get_api_reference`, `search_api`) over recall for prop names, slot names, event names, and enum values — see [MCP.md](./reference/MCP.md). Without MCP, read the installed `.d.ts` files under `node_modules/igniteui-webcomponents/components//` (or `igniteui-webcomponents-grids/grids/lib/`), which carry `@slot`, `@csspart`, `@fires`, and `@cssproperty` annotations. -### Events - -- Events are `CustomEvent` objects, not React `SyntheticEvent` -- Access data via `e.target` or `e.detail` -- See [EVENT-HANDLING.md](./reference/EVENT-HANDLING.md) - -### Refs - -- Use `useRef(null)` with the component type: -- See [REFS-FORMS.md](./reference/REFS-FORMS.md) - -### Charts, Gauges, Maps & Grid Lite - -- **Charts/Gauges/Maps require explicit registration**: `IgrCategoryChartModule.register()` -- **All require sized container**: `min-width`, `min-height`, or `flex-grow` -- **Grid Lite** requires both `igniteui-react` and `igniteui-grid-lite` packages, import from `igniteui-react/grid-lite` -- See [CHARTS-GRIDS.md](./reference/CHARTS-GRIDS.md) - ---- +## Related skills -## Best Practices - -1. **Start with the MIT package** (`igniteui-react`) — it covers most common UI needs -2. **Import theme CSS first** — components need it to render correctly -3. **Register chart/gauge/map modules** — call `.register()` at module level -4. **Wrap charts/gauges/maps in sized containers** — they need explicit dimensions -5. **Use named imports** — enables tree-shaking -6. **Handle events as `CustomEvent`** — not `React.SyntheticEvent` -7. **Use refs sparingly** — prefer declarative props -8. **Check slot names** in the docs -9. **Never add `width` to grid columns by default** — `IgrGridLiteColumn` defaults to `minmax(136px, 1fr)` (responsive) and `IgrColumn` auto-sizes. Adding explicit pixel widths leaves empty space and breaks responsiveness. Only set `width` when the user explicitly requests it. If some columns have explicit widths, leave at least one column without a `width` to fill remaining space. +- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — brand colors, dark mode, component tokens +- [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md) — code splitting heavy families +- [grid-lite-to-igr-grid-migration](../grid-lite-to-igr-grid-migration/SKILL.md) — Grid Lite → premium `IgrGrid` diff --git a/skills/igniteui-react-components/reference/CHARTS-GRIDS.md b/skills/igniteui-react-components/reference/CHARTS-GRIDS.md deleted file mode 100644 index d1a7c48..0000000 --- a/skills/igniteui-react-components/reference/CHARTS-GRIDS.md +++ /dev/null @@ -1,398 +0,0 @@ -# Charts, Gauges, Maps & Grid Lite - -## Overview -This reference gives high-level guidance on charts and grids, their key features, and common API members. For detailed documentation, call `get_doc` and `get_api_reference` from `igniteui-cli` with the specific chart, or grid component, or feature you're interested in. - -## Module Registration - -> **⚠️ IMPORTANT:** Unlike core UI components (from `igniteui-react`), chart, gauge, and map components from `igniteui-react-charts`, `igniteui-react-gauges`, and `igniteui-react-maps` **require explicit module registration** before use. You must import the corresponding `*Module` class and call `.register()` at the module level (outside the component function). -> -> **Grid Lite** (`IgrGridLite` from `igniteui-react/grid-lite`) is a React wrapper component that works like any other React component — no `.register()` needed, but requires both `igniteui-react` and `igniteui-grid-lite` packages installed. - -### Registration Syntax - -```tsx -import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; - -// ⚠️ REQUIRED — register the module before using the component -IgrCategoryChartModule.register(); -``` - -### Common Module Registrations - -| Component | Module Import | Registration | -|---|---|---| -| `IgrCategoryChart` | `IgrCategoryChartModule` | `IgrCategoryChartModule.register()` | -| `IgrDataChart` | `IgrDataChartCoreModule` + category/annotation modules (see [Complete Data Chart Example](#complete-data-chart-example)) | Multiple `.register()` calls required | -| `IgrPieChart` | `IgrPieChartModule` | `IgrPieChartModule.register()` | -| `IgrFinancialChart` | `IgrFinancialChartModule` | `IgrFinancialChartModule.register()` | -| `IgrRadialGauge` | `IgrRadialGaugeModule` | `IgrRadialGaugeModule.register()` | -| `IgrLinearGauge` | `IgrLinearGaugeModule` | `IgrLinearGaugeModule.register()` | -| `IgrGeographicMap` | `IgrGeographicMapModule` | `IgrGeographicMapModule.register()` | -| `IgrGridLite` | (no registration needed) | N/A — works like standard React component | - -## Container Sizing (REQUIRED) - -> **⚠️ CRITICAL:** Charts, gauges, maps, and Grid Lite **require an explicit-sized container** to render. They inherit their dimensions from the parent element — if the parent has no height/width, the component will not be visible. Always wrap these components in a container with explicit `min-width`, `min-height`, or `flex-grow` styling. - -```css -/* Chart container CSS */ -.chart-container { - min-width: 400px; - min-height: 300px; - flex-grow: 1; - flex-basis: 0; -} - -/* Ensure the chart fills its container */ -.chart-container > * { - height: 100%; - width: 100%; -} -``` - -## Complete Chart Example - -> Call `get_doc('react', 'column-chart')` for full `IgrCategoryChart` and `IgrDataChart` usage, prop tables, and code examples. Call `get_doc('react', 'chart-features')` for axes, annotations, animations, markers, and tooltips. - -The minimum pattern — register the module at file scope, then wrap the component in a sized container: - -```tsx -import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; -import styles from './dashboard-view.module.css'; - -// Register the chart module (required, called once at module level) -IgrCategoryChartModule.register(); - -export default function DashboardView() { - const salesData = [ - { month: 'Jan', revenue: 12500 }, - { month: 'Feb', revenue: 18200 }, - { month: 'Mar', revenue: 15800 }, - ]; - - return ( -
- -
- ); -} -``` - -## Complete Data Chart Example - -> **⚠️ IMPORTANT:** `IgrDataChart` requires registering **multiple modules** depending on the series type used. For bar charts, register the modules shown below. If you miss any module, the chart or axis types will silently fail to render. - -### Module Registration for Bar Charts - -```tsx -import { - IgrLegendModule, - IgrDataChartCoreModule, - IgrDataChartCategoryCoreModule, - IgrDataChartCategoryModule, - IgrDataChartInteractivityModule, - IgrDataChartVerticalCategoryModule, - IgrDataChartAnnotationModule, -} from 'igniteui-react-charts'; - -// Register all required modules once at module level (outside any component) -IgrLegendModule.register(); -IgrDataChartCoreModule.register(); -IgrDataChartCategoryCoreModule.register(); -IgrDataChartCategoryModule.register(); -IgrDataChartInteractivityModule.register(); -IgrDataChartVerticalCategoryModule.register(); -IgrDataChartAnnotationModule.register(); -``` - -| Module | Purpose | -|---|---| -| `IgrDataChartCoreModule` | Core chart infrastructure | -| `IgrDataChartCategoryCoreModule` | Base for category series | -| `IgrDataChartCategoryModule` | Column, Line, Area, Spline etc. | -| `IgrDataChartVerticalCategoryModule` | **Bar series** (horizontal bars) | -| `IgrDataChartInteractivityModule` | Mouse hover, selection | -| `IgrDataChartAnnotationModule` | Tooltip layers, callout layers | -| `IgrLegendModule` | `IgrLegend` component | - -### Axis Choice for Bar Charts - -| Chart Orientation | Category Axis | Value Axis | -|---|---|---| -| Bar (horizontal) | `IgrCategoryYAxis` | `IgrNumericXAxis` | -| Column (vertical) | `IgrCategoryXAxis` | `IgrNumericYAxis` | - -> **Bar charts are horizontal** — categories go on the Y-axis and numeric values on the X-axis. This is the opposite of column charts. - -> For the full `IgrDataChart` API (all series types, axis options, layers), call `get_doc('react', 'bar-chart')` or `get_doc('react', 'column-chart')`. - -### Complete Bar Chart Component (Multiple Series) - -```tsx -import { useRef } from 'react'; -import { - IgrLegendModule, - IgrDataChartCoreModule, - IgrDataChartCategoryCoreModule, - IgrDataChartCategoryModule, - IgrDataChartInteractivityModule, - IgrDataChartVerticalCategoryModule, - IgrDataChartAnnotationModule, - IgrLegend, - IgrDataChart, - IgrCategoryYAxis, - IgrNumericXAxis, - IgrCategoryHighlightLayer, - IgrBarSeries, - IgrDataToolTipLayer, -} from 'igniteui-react-charts'; -import styles from './bar-chart-view.module.css'; - -// Register all required modules once at module level -IgrLegendModule.register(); -IgrDataChartCoreModule.register(); -IgrDataChartCategoryCoreModule.register(); -IgrDataChartCategoryModule.register(); -IgrDataChartInteractivityModule.register(); -IgrDataChartVerticalCategoryModule.register(); -IgrDataChartAnnotationModule.register(); - -interface MovieFranchise { - franchise: string; - totalRevenue: number; // total box office in billions USD - highestGrossing: number; // highest single film in billions USD -} - -const movieData: MovieFranchise[] = [ - { franchise: 'Marvel Universe', totalRevenue: 22.55, highestGrossing: 2.80 }, - { franchise: 'Star Wars', totalRevenue: 10.32, highestGrossing: 2.07 }, - { franchise: 'Harry Potter', totalRevenue: 9.19, highestGrossing: 1.34 }, - { franchise: 'Avengers', totalRevenue: 7.76, highestGrossing: 2.80 }, - { franchise: 'Spider Man', totalRevenue: 7.22, highestGrossing: 1.28 }, - { franchise: 'James Bond', totalRevenue: 7.12, highestGrossing: 1.11 }, -]; - -export default function BarChartView() { - const legendRef = useRef(null); - - return ( -
-

Highest Grossing Movie Franchises

- - {/* Legend must be rendered before the chart so the ref is populated */} - - -
- - {/* - * IgrCategoryYAxis — category axis for horizontal bar charts. - * - label: field name that supplies the axis labels. - * - dataSource: the data array (required on the axis for bar charts). - * - isInverted: renders top-to-bottom instead of bottom-to-top. - * - gap / overlap: control bar spacing (gap) and multi-series overlap. - */} - - - {/* IgrNumericXAxis — value axis; start at 0 per bar chart best practices */} - - - {/* Highlight the hovered category row across all series */} - - - {/* First series — total franchise revenue */} - - - {/* Second series — highest grossing single film */} - - - {/* Rich tooltip layer — shows all series values on hover */} - - -
-
- ); -} -``` - -```css -/* bar-chart-view.module.css */ -.chart-wrapper { - display: flex; - flex-direction: column; - min-width: 500px; -} - -.legend-title { - font-size: 1rem; - font-weight: 600; - text-align: center; - margin-bottom: 0.5rem; -} - -.chart-container { - min-height: 400px; - flex-grow: 1; - flex-basis: 0; -} - -/* Make the chart fill its container */ -.chart-container > * { - height: 100%; - width: 100%; -} -``` - -## Complete Grid Lite Example - -> **⚠️ IMPORTANT:** Grid Lite (`IgrGridLite` from `igniteui-react/grid-lite`) requires installing both `igniteui-react` and `igniteui-grid-lite` packages. It's a React wrapper component (uses `Igr` prefix) and works like any standard React component — no `.register()` needed. - -**Installation:** -```bash -npm install igniteui-react igniteui-grid-lite -``` - -**Usage:** -```tsx -import { IgrGridLite } from 'igniteui-react/grid-lite'; -import { useGetCustomers } from '../hooks/northwind-hooks'; -import styles from './master-view.module.css'; - -export default function MasterView() { - const { northwindCustomers } = useGetCustomers(); - - return ( -
- -
- ); -} -``` - -```css -/* master-view.module.css */ -.grid-lite { - min-width: 400px; - height: 600px; - flex-grow: 1; - flex-basis: 0; -} -``` - -## Grid Lite Example with Column Configurations and Templates - -Use `IgrGridLiteColumn` to define columns explicitly with typed `dataType` and optional `cellTemplate` for custom rendering. Set `autoGenerate={false}` (or omit it) when providing explicit columns. - -```tsx -import { IgrGridLite, IgrGridLiteColumn, type IgrCellContext } from 'igniteui-react/grid-lite'; -import styles from './order-list.module.css'; - -interface Order { - id: number; - customer: string; - total: number; - date: Date; - status: 'pending' | 'shipped' | 'delivered'; -} - -const orders: Order[] = [ - { id: 1, customer: 'Alice', total: 149.99, date: new Date('2024-03-01'), status: 'delivered' }, - { id: 2, customer: 'Bob', total: 89.50, date: new Date('2024-03-10'), status: 'shipped' }, - { id: 3, customer: 'Carol', total: 220.00, date: new Date('2024-03-15'), status: 'pending' }, -]; - -// Simple cell templates — render JSX based on the cell value or row data -const currencyTemplate = (ctx: IgrCellContext) => ( - ${(ctx.value as number).toFixed(2)} -); - -const dateTemplate = (ctx: IgrCellContext) => ( - {(ctx.value as Date).toLocaleDateString()} -); - -const statusTemplate = (ctx: IgrCellContext) => { - const colors: Record = { - pending: 'orange', - shipped: 'blue', - delivered: 'green', - }; - return {ctx.value}; -}; - -export default function OrderList() { - return ( -
- - {/* dataType ensures correct sorting and filtering behavior */} - - - {/* Columns with custom cell templates */} - - - - -
- ); -} -``` - -```css -/* order-list.module.css */ -.grid-lite { - min-width: 400px; - height: 600px; - flex-grow: 1; - flex-basis: 0; -} -``` - -## Column Width Rule (Grid Lite and Advanced Grids) - -> **⚠️ Do NOT set `width` on columns unless the user explicitly asks for specific column widths.** -> -> - `IgrGridLiteColumn` defaults to `minmax(136px, 1fr)` — columns are already responsive and fill all available space. -> - `IgrColumn` (in `IgrGrid`, `IgrTreeGrid`, `IgrHierarchicalGrid`) also auto-sizes by default. -> - Adding explicit pixel widths causes a fixed layout that leaves empty space on the right side of the grid. -> - If widths are set on some columns, leave at least one column without a `width` so it expands to fill the remaining space. - -> **Column configuration notes:** -> - `dataType` accepts `"string"` (default), `"number"`, `"boolean"` — set it explicitly so sorting and filtering work correctly for each column type. -> - `cellTemplate` receives an `IgrCellContext` where `ctx.value` is the cell value and `ctx.row.data` is the full row object. -> - When using `cellTemplate`, define the function outside the component (or memoize it) to avoid unnecessary re-renders. diff --git a/skills/igniteui-react-components/reference/COMPONENT-CATALOGUE.md b/skills/igniteui-react-components/reference/COMPONENT-CATALOGUE.md deleted file mode 100644 index 2c73a1a..0000000 --- a/skills/igniteui-react-components/reference/COMPONENT-CATALOGUE.md +++ /dev/null @@ -1,161 +0,0 @@ -# Component Catalogue - -## Overview -This reference gives high-level guidance on Ignite UI for React components, their key features, and common use cases. For a full list of components, call `list_components` from `igniteui-cli` with the specific chart, or grid component, or feature you're interested in. - ---- - -## Step-by-Step: Choosing Components for a UI - -Follow these steps when a user describes a UI requirement: - -### Step 1 — Identify UI patterns - -Break the described UI into atomic patterns. Examples: -- "A booking form" → date input, text inputs, button, maybe a calendar picker -- "An admin dashboard" → navbar, nav drawer, cards, data grid, charts -- "A notification center" → snackbar or toast, badge, list -- "A settings page" → tabs or accordion, switch, input, select, button - -### Step 2 — Map patterns to components - -Call `list_components('react')` to discover available components, optionally filtered by keyword (e.g., `filter: 'date'` for date-related components). When in doubt: - -| If the user needs… | Prefer… | Over… | -|---|---|---| -| Simple static list | `IgrList` | Data Grid | -| Basic dropdown | `IgrSelect` | `IgrCombo` | -| Searchable or multi-select dropdown | `IgrCombo` | `IgrSelect` | -| Tabular data with basic display | `IgrGridLite` (grid-lite) | `IgrGrid` (commercial) | -| Tabular data, advanced features needed | `IgrGrid` | `IgrGridLite` (grid-lite) | -| Single dismissible message | `IgrToast` | `IgrSnackbar` | -| Message requiring user action | `IgrSnackbar` | `IgrToast` | -| Collapsible single section | `IgrExpansionPanel` | `IgrAccordion` | -| Multiple collapsible sections | `IgrAccordion` | `IgrExpansionPanel` | -| Stepped wizard UI | `IgrStepper` | `IgrTabs` | -| Content tabs / view switching (inline content) | `IgrTabs` (content in `IgrTab`) | `IgrStepper` | -| Tab-based navigation (with React Router) | `IgrTabs` (label-only) | `IgrTabs` (with content) | - -### Step 3 — Check the package - -Confirm which package provides the component: - -- **MIT components** (inputs, layout, notifications, scheduling, chat) → `igniteui-react` -- **Lightweight grid** (Grid Lite) → `igniteui-react/grid-lite` *(MIT, requires both `igniteui-react` and `igniteui-grid-lite` packages)* -- **Advanced grids** (Data Grid, Tree Grid, Hierarchical Grid, Pivot Grid) → `igniteui-react-grids` *(commercial)* -- **Charts** → `igniteui-react-charts` *(commercial)* -- **Maps** → `igniteui-react-maps` *(commercial)* -- **Gauges** → `igniteui-react-gauges` *(commercial)* - -### Step 4 — Look up component documentation - -Call `get_doc('react', '')` with the doc name from `list_components` results to get full usage documentation, import paths, prop tables, event signatures, and code examples. Use `search_docs('', 'react')` for feature-based questions (e.g., `"date picker range selection"`). - -### Step 5 — Provide a starter code snippet - -Once components are identified, give the user a minimal working React snippet. Example for an admin dashboard shell: - -```tsx -import { IgrNavbar, IgrNavDrawer, IgrNavDrawerItem, IgrCard, IgrCardHeader, IgrCardContent } from 'igniteui-react'; -import 'igniteui-webcomponents/themes/light/bootstrap.css'; - -function Dashboard() { - return ( - <> - -

My Dashboard

-
- - - - 🏠 - Home - - - ⚙️ - Settings - - - -
- - -

Summary

-
- Dashboard content here -
-
- - ); -} -``` - ---- - -## Common UI Scenarios → Recommended Component Sets - -### Login / Authentication Form - -- `IgrInput` — email and password fields -- `IgrCheckbox` — "Remember me" -- `IgrButton` — submit -- `IgrSnackbar` — error/success feedback - -### User Profile / Settings Page - -- `IgrAvatar` — profile picture -- `IgrTabs` — section navigation (Profile, Security, Notifications) -- `IgrInput` / `IgrTextarea` — editable fields -- `IgrSwitch` — feature toggles -- `IgrSelect` — preference dropdowns -- `IgrButton` — save/cancel actions - -### Data Table / Admin List View - -- `IgrInput` — search bar -- `IgrCombo` — filter dropdowns -- `IgrGridLite` (grid-lite) or `IgrGrid` — tabular data -- `IgrButton` / `IgrIconButton` — actions -- `IgrDialog` — confirm delete modal -- `IgrBadge` — status indicators - -### Booking / Reservation Form - -- `IgrDateRangePicker` — check-in / check-out -- `IgrInput` — guest details -- `IgrSelect` — room type -- `IgrStepper` — multi-step booking flow -- `IgrButton` — next / confirm -- `IgrToast` — booking confirmation - -### Analytics / Reporting Dashboard - -- `IgrNavbar` — top bar -- `IgrNavDrawer` — side navigation -- `IgrCard` — KPI summary cards -- `IgrTabs` or `IgrTileManager` — section layout -- `IgrGrid` or `IgrPivotGrid` — detailed data tables -- `IgrCategoryChart` — charts (from `igniteui-react-charts`) -- `IgrLinearProgress` / `IgrCircularProgress` — loading indicators - -### Master-Detail with Tab Navigation (React Router) - -- `IgrNavbar` — top bar -- `IgrTabs` — **navigation only** (label-only, no inline content); each `IgrTab` triggers a route change -- React Router `` — renders the routed child view below the tabs -- Active tab synced to the current route via `selected` prop - -> **⚠️ Important — Tabs for navigation vs. tabs for content:** -> - **Tabs as content panels** (`IgrTabs` with content in `IgrTab`): Content is rendered inside each tab. Use when the tab content is inline and does not require routing. -> - **Tabs as navigation** (`IgrTabs` with label-only tabs): Tabs act as route links. The routing outlet (``) renders the content. **Do NOT add inline content in `IgrTab` in this case** — use only the `label` prop or `slot="label"`. See [JSX-PATTERNS.md](./JSX-PATTERNS.md) for a full React Router example. - ---- - -## Searching the Documentation - -Use MCP tools for up-to-date component discovery and API lookup: - -- `list_components('react')` — browse the full component catalogue, optionally narrowed with a filter keyword -- `get_doc('react', '')` — full documentation, prop tables, and code examples for a component -- `search_docs('', 'react')` — full-text search for features or behaviors (e.g., `"date picker range selection"`) -- `search_api('', 'react')` — look up specific classes, properties, or methods diff --git a/skills/igniteui-react-components/reference/COMPONENTS.md b/skills/igniteui-react-components/reference/COMPONENTS.md new file mode 100644 index 0000000..da42bf1 --- /dev/null +++ b/skills/igniteui-react-components/reference/COMPONENTS.md @@ -0,0 +1,65 @@ +# Choosing Components + +Ask the MCP server for the authoritative list: `list_components({ framework: 'react', filter: 'date' })`. This file only records the picks that are easy to get wrong. + +## Disambiguation + +| Requirement | Use | Not | +|---|---|---| +| Static list of rows | `IgrList` | a grid | +| Plain dropdown | `IgrSelect` | `IgrCombo` | +| Searchable or multi-select dropdown | `IgrCombo` | `IgrSelect` | +| Flat tabular data, display only | `IgrGridLite` | `IgrGrid` | +| Editing, selection, paging, grouping, summaries, export | `IgrGrid` | `IgrGridLite` | +| Parent/child rows | `IgrTreeGrid` | `IgrGrid` | +| Auto-dismissing message | `IgrToast` | `IgrSnackbar` | +| Message with an action | `IgrSnackbar` | `IgrToast` | +| One collapsible section | `IgrExpansionPanel` | `IgrAccordion` | +| Several collapsible sections | `IgrAccordion` | `IgrExpansionPanel` | +| Linear wizard with validation per step | `IgrStepper` | `IgrTabs` | +| View switching | `IgrTabs` | `IgrStepper` | + +`IgrGridLite` has no editing, selection, paging, grouping, summaries, pinning, or export. If the requirement lists any of those, it is `IgrGrid`. + +## Pattern → components + +- **Form / login** — `IgrInput`, `IgrCheckbox`, `IgrSelect` + `IgrSelectItem`, `IgrRadioGroup` + `IgrRadio`, `IgrSwitch`, `IgrSlider`, `IgrButton` +- **Dates** — `IgrDatePicker`, `IgrDateRangePicker`, `IgrDateTimeInput`, `IgrCalendar` +- **App shell** — `IgrNavbar`, `IgrNavDrawer` + `IgrNavDrawerItem`, `IgrTabs`, `IgrSplitter`, `IgrTileManager` +- **Cards** — `IgrCard`, `IgrCardHeader`, `IgrCardMedia`, `IgrCardContent`, `IgrCardActions` +- **Status** — `IgrBadge`, `IgrChip`, `IgrAvatar`, `IgrIcon`, `IgrLinearProgress`, `IgrCircularProgress` +- **Overlays** — `IgrDialog`, `IgrToast`, `IgrSnackbar`, `IgrTooltip`, `IgrDropdown` +- **Charts** (`igniteui-react-charts`) — `IgrCategoryChart` (line/area/column), `IgrPieChart`, `IgrFinancialChart`, `IgrSparkline`, `IgrDataChart` for multi-series/multi-axis control +- **Gauges** (`igniteui-react-gauges`) — `IgrLinearGauge`, `IgrRadialGauge`, `IgrBulletGraph` +- **Maps** (`igniteui-react-maps`) — `IgrGeographicMap` plus `IgrGeographicSymbolSeries` / `…ProportionalSymbolSeries` / `…ShapeSeries` +- **AI chat** — `IgrChat` (markdown rendering via `createChatMarkdownRenderer` from `igniteui-react/extras`) + +## `IgrTabs`: content vs navigation + +These are different, and mixing them is the most common `IgrTabs` bug. + +**Content panels** — content lives inside each `IgrTab`: + +```tsx + + + + +``` + +Use a `slot="label"` child instead of the `label` prop when the header needs an icon or custom markup. + +**Router navigation** — tabs are label-only; the router renders content *outside* `IgrTabs`. Inline content here renders in addition to the routed view and pushes it off screen. + +```tsx +import type { IgrTabComponentEventArgs } from 'igniteui-react'; + + navigate(pathFor(e.detail.label))}> + {tabs.map(t => ( + + ))} + + +``` + +`IgrTabs`' `onChange` detail is the selected `IgrTab` element itself, so `e.detail.label`, `e.detail.selected`, and `e.detail.disabled` are available. diff --git a/skills/igniteui-react-components/reference/DATAVIZ.md b/skills/igniteui-react-components/reference/DATAVIZ.md new file mode 100644 index 0000000..333e0e9 --- /dev/null +++ b/skills/igniteui-react-components/reference/DATAVIZ.md @@ -0,0 +1,90 @@ +# Charts, Gauges, Maps, and Grids + +## Two rules cover most failures + +**1. Charts, gauges, and maps require module registration.** These live in the older `igniteui-react-charts` / `-gauges` / `-maps` packages, which are not auto-registering wrappers. Call `.register()` once at module scope, outside the component. A missing registration fails silently — the chart, an axis, or a series simply does not appear. + +**2. Charts, gauges, maps, and grids size themselves from their parent.** A parent with no resolved height renders them at zero. Give the container real dimensions and let the component fill it. + +```css +.viz { + min-height: 320px; + flex-grow: 1; + flex-basis: 0; +} +.viz > * { width: 100%; height: 100%; } +``` + +Inside a flexible CSS Grid track, also set `min-height: 0` on the cell, or the track refuses to shrink and the chart overflows. + +## Registration + +```tsx +import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; + +IgrCategoryChartModule.register(); // module scope, once + +export default function Trend({ data }: { data: Point[] }) { + return ( +
+ +
+ ); +} +``` + +One module per component: `IgrCategoryChartModule`, `IgrPieChartModule`, `IgrFinancialChartModule`, `IgrSparklineModule`, `IgrLinearGaugeModule`, `IgrRadialGaugeModule`, `IgrBulletGraphModule`, `IgrGeographicMapModule`. + +`IgrDataChart` is the exception — it needs one module per capability, and each missing one drops a feature silently: + +| Module | Provides | +|---|---| +| `IgrDataChartCoreModule` | the chart itself (always) | +| `IgrDataChartCategoryCoreModule` | category axis base (always, with category series) | +| `IgrDataChartCategoryModule` | column, line, area, spline series | +| `IgrDataChartVerticalCategoryModule` | bar series (horizontal) | +| `IgrDataChartInteractivityModule` | hover, selection, highlight layers | +| `IgrDataChartAnnotationModule` | tooltip and callout layers | +| `IgrLegendModule` | `IgrLegend` | + +Bar charts are horizontal: categories on `IgrCategoryYAxis`, values on `IgrNumericXAxis` — the reverse of a column chart. The category axis needs its own `dataSource` in addition to the series'. Pass a legend by ref (`` rendered before the chart, then `legend={legend.current ?? undefined}`). + +Note: `igniteui-react-charts` components are not the `igc-*` wrappers, so their visuals are set through props (`brushes`, `outlines`, `markerTypes`, `xAxisLabelTextColor`, …), not through `--ig-*` design tokens. + +## Grid Lite + +MIT, needs both `igniteui-react` and `igniteui-grid-lite` installed, imports from `igniteui-react/grid-lite`, and needs no registration. + +```tsx +import { IgrGridLite, IgrGridLiteColumn, type IgrCellContext } from 'igniteui-react/grid-lite'; + +const money = (ctx: IgrCellContext) => ${(ctx.value as number).toFixed(2)}; + +
+ + + + + +
+``` + +- `dataType` is `'string' | 'number' | 'boolean'` and drives sorting and filtering; set it explicitly. +- `cellTemplate` / `headerTemplate` receive `IgrCellContext` / `IgrHeaderContext` — `ctx.value`, `ctx.row.data`, `ctx.row.index`, `ctx.column.field`. Define templates outside the component or memoize them. +- Sorting expressions are `{ key, direction: 'ascending' | 'descending' }`. +- `autoGenerate` defaults to `false`. Set it and pass no column children to derive columns from the data; explicit columns always win. + +## Column widths + +**Do not set `width` on `IgrGridLiteColumn` or `IgrColumn` unless the user asked for specific widths.** Both are fluid by default (`IgrGridLiteColumn` falls back to `minmax(136px, 1fr)`). Fixed pixel widths pin the layout and leave dead space to the right of the last column. If some columns genuinely need a fixed width, leave at least one without one so it absorbs the remainder. + +## Premium grid essentials + +`igniteui-react-grids`, no registration, needs its own theme CSS (`igniteui-react-grids/grids/themes//.css`) on top of the base theme. + +- `height` is required for row virtualization; `primaryKey` is required for editing, selection, and row-targeted APIs. +- Cell templates use `bodyTemplate` with `IgrCellTemplateContext` (`ctx.cell.value`, `ctx.cell.row.data`) — not Grid Lite's `cellTemplate`/`ctx.value`. +- Header templates use `headerTemplate` with `IgrColumnTemplateContext` (`ctx.column.header`). +- Filtering needs `allowFiltering` on the grid *and* `filterable` on each column. + +For anything beyond this, see [grid-lite-to-igr-grid-migration](../../grid-lite-to-igr-grid-migration/SKILL.md) or `get_doc({ framework: 'react', name: 'grid-editing' })`. diff --git a/skills/igniteui-react-components/reference/EVENT-HANDLING.md b/skills/igniteui-react-components/reference/EVENT-HANDLING.md deleted file mode 100644 index c6d3bb0..0000000 --- a/skills/igniteui-react-components/reference/EVENT-HANDLING.md +++ /dev/null @@ -1,72 +0,0 @@ -# Event Handling - -## How Events Work - -Ignite UI React wrappers map web component custom events to React-style `onXxx` callback props. The event name is converted from the web component event name to a camelCase `on`-prefixed prop. - -```tsx -import { IgrButton, IgrInput, IgrCheckbox } from 'igniteui-react'; - -function MyForm() { - const handleClick = (event: CustomEvent) => { - console.log('Button clicked'); - }; - - const handleInput = (event: CustomEvent) => { - // event.target is the underlying web component element (e.g., igc-input) - console.log('Input value:', (event.target as any).value); - }; - - const handleChange = (event: CustomEvent) => { - console.log('Checkbox changed:', event.detail); - }; - - return ( - <> - - Submit - - - Accept terms - - ); -} -``` - -## Common Event Props - -> For component-specific event signatures and detail types, call `get_api_reference('react', '', 'events')` — e.g. `get_api_reference('react', 'IgrCombo', 'events')`. - -| Component | Event Prop | Fires When | -|---|---|---| -| `IgrButton` | `onClick` | Button is clicked | -| `IgrInput` | `onInput` | Value changes (each keystroke) | -| `IgrInput` | `onChange` | Value committed (blur / Enter) | -| `IgrCheckbox` | `onChange` | Checked state changes | -| `IgrSwitch` | `onChange` | Toggle state changes | -| `IgrSelect` | `onChange` | Selection changes | -| `IgrCombo` | `onChange` | Selection changes | -| `IgrSlider` | `onInput` | Slider value changes (live) | -| `IgrSlider` | `onChange` | Slider value committed | -| `IgrDialog` | `onClosing` | Dialog is about to close | -| `IgrDialog` | `onClosed` | Dialog has closed | -| `IgrTabs` | `onChange` | Active tab changes | -| `IgrCalendar` | `onChange` | Selected date changes | -| `IgrDatePicker` | `onChange` | Selected date changes | - -## TypeScript Event Types - -When using TypeScript, event handlers receive the underlying `CustomEvent`: - -```tsx -import { IgrInput } from 'igniteui-react'; - -function SearchBar() { - const handleInput = (e: CustomEvent) => { - const value = (e.target as HTMLInputElement).value; - console.log('Search:', value); - }; - - return ; -} -``` diff --git a/skills/igniteui-react-components/reference/INSTALLATION.md b/skills/igniteui-react-components/reference/INSTALLATION.md deleted file mode 100644 index bfa70d9..0000000 --- a/skills/igniteui-react-components/reference/INSTALLATION.md +++ /dev/null @@ -1,139 +0,0 @@ -# Installation & Setup - -## Install the Package - -```bash -# Core UI components (MIT) -npm install igniteui-react - -# If you need the lightweight grid (MIT) -# Requires BOTH packages - igniteui-react and igniteui-grid-lite -npm install igniteui-react igniteui-grid-lite - -# If you need advanced grids (commercial) -npm install igniteui-react-grids - -# If you need charts (commercial) -npm install igniteui-react-charts - -# If you need gauges (commercial) -npm install igniteui-react-gauges - -# If you need maps (commercial) -npm install igniteui-react-maps -``` - -## Peer Dependencies - -`igniteui-react` requires `react` and `react-dom` (v18+ or v19+). These are typically already in your project: - -```bash -npm install react react-dom -``` - -## Import a Theme (REQUIRED) - -> **CRITICAL:** Components will render without styles, with broken icons and missing visuals if the theme CSS is not imported. **Always import the theme CSS before using any Ignite UI component.** - -Import one theme CSS file in your entry point (`main.tsx`, `index.tsx`, or `App.tsx`). The theme CSS must be imported **in every file that uses Ignite UI components** if your framework does not have a single global entry point (e.g., Next.js — see below). - -```tsx -// main.tsx or index.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -``` - -Available themes: - -| Import | Theme | -|---|---| -| `igniteui-webcomponents/themes/light/bootstrap.css` | Bootstrap Light | -| `igniteui-webcomponents/themes/dark/bootstrap.css` | Bootstrap Dark | -| `igniteui-webcomponents/themes/light/material.css` | Material Light | -| `igniteui-webcomponents/themes/dark/material.css` | Material Dark | -| `igniteui-webcomponents/themes/light/fluent.css` | Fluent Light | -| `igniteui-webcomponents/themes/dark/fluent.css` | Fluent Dark | -| `igniteui-webcomponents/themes/light/indigo.css` | Indigo Light | -| `igniteui-webcomponents/themes/dark/indigo.css` | Indigo Dark | - -Grid theme CSS files follow the same pattern under `igniteui-react-grids/grids/themes/`. - -**For grids**, you **must also** import the grid theme CSS. Without it, the grid will be missing styles and icons will show as placeholders: - -```tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; -``` - -## Next.js Setup - -In Next.js, there is no single `main.tsx` entry point. Import the theme CSS **in each client component file** that uses Ignite UI components, or in a shared layout component: - -```tsx -// app/components/DataTable.tsx -'use client'; - -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; - -import { IgrGrid, IgrColumn, IgrPaginator } from 'igniteui-react-grids'; - -export default function DataTable({ data }: { data: any[] }) { - return ( - - - - - - ); -} -``` - -Alternatively, import themes once in a root layout: - -```tsx -// app/layout.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; - -export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - {children} - - ); -} -``` - -## Minimal App Example (Vite / CRA) - -```tsx -// main.tsx -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import App from './App'; - -ReactDOM.createRoot(document.getElementById('root')!).render( - - - -); -``` - -```tsx -// App.tsx -import { IgrButton, IgrInput } from 'igniteui-react'; - -function App() { - return ( -
- - Submit -
- ); -} - -export default App; -``` - -> **No `defineComponents()` needed.** React wrappers auto-register. See [CHARTS-GRIDS.md](./reference/CHARTS-GRIDS.md) for exceptions (charts, gauges, maps). diff --git a/skills/igniteui-react-components/reference/JSX-PATTERNS.md b/skills/igniteui-react-components/reference/JSX-PATTERNS.md deleted file mode 100644 index 47acbbf..0000000 --- a/skills/igniteui-react-components/reference/JSX-PATTERNS.md +++ /dev/null @@ -1,187 +0,0 @@ -# JSX Usage Patterns - -## Props vs HTML Attributes - -Ignite UI React components accept props just like any React component. Use JSX expression syntax for dynamic values: - -```tsx -// ✅ Correct — JSX expression - - -Submit - -// ❌ Wrong — string for numeric/boolean values - -``` - -## Children vs Slots - -Ignite UI components use the web component **slot** mechanism under the hood. In JSX, pass children to the default slot and use the `slot` attribute to target named slots: - -```tsx - - {/* Default slot — button label */} - Click Me - - - - -

Card Title

-

Card subtitle

-
- -

Default slot content inside the card body.

-
- - Cancel - Confirm - -
- - - 📊 - Dashboard - -``` - -> **Tip:** Check the component documentation for available slot names. Common slots include `start`, `end`, `prefix`, `suffix`, `header`, `content`, `icon`, `title`, `subtitle`. - -## Render Props (Grids & Complex Components) - -Some components like the Data Grid support **render props** for custom cell rendering: - -```tsx -import { IgrBadge } from 'igniteui-react'; -import { IgrGrid, IgrColumn } from 'igniteui-react-grids'; - -function UserGrid({ users }: { users: User[] }) { - return ( - - - - ( - {ctx.cell.value} - )} - /> - - ); -} -``` - -## IgrTabs — Content Panels vs Navigation - -`IgrTabs` supports two distinct usage patterns. Choosing the wrong one is a common mistake. - -### Pattern 1: Tabs with Content Panels (inline content) - -Use `IgrTab` with inline content when the tabbed content is rendered inline — no routing involved. The tab label can be set via a `label` prop or via a `slot="label"` element: - -```tsx -import { IgrTabs, IgrTab } from 'igniteui-react'; - -// Simple text labels using the label prop -function SettingsPage() { - return ( - - -

Profile settings content here

-
- -

Security settings content here

-
- -

Notification preferences content here

-
-
- ); -} -``` - -**Alternative: Using slot="label" for complex headers (e.g., with icons):** - -```tsx -import { IgrTabs, IgrTab, IgrIcon } from 'igniteui-react'; - -function SettingsPage() { - return ( - - - - - Profile - -

Profile settings content here

-
- - - - Security - -

Security settings content here

-
- - - - Notifications - -

Notification preferences content here

-
-
- ); -} -``` - -### Pattern 2: Tabs as Navigation (with React Router — NO inline content) - -> **⚠️ CRITICAL:** When using `IgrTabs` for navigation with React Router (or any router), **do NOT include inline content in `IgrTab`**. Only render tab labels (via `label` prop or `slot="label"`), and let the router's `` handle the content below the tabs. - -```tsx -import { IgrTabs, IgrTab } from 'igniteui-react'; -import { useNavigate, useLocation, Outlet } from 'react-router-dom'; - -const tabs = [ - { path: '/dashboard', label: 'Dashboard' }, - { path: '/orders', label: 'Orders' }, - { path: '/customers', label: 'Customers' }, -]; - -function MainLayout() { - const navigate = useNavigate(); - const location = useLocation(); - - const handleTabChange = (e: CustomEvent) => { - const selectedLabel = (e.detail as any).label as string; - const tab = tabs.find(t => t.label === selectedLabel); - if (tab) navigate(tab.path); - }; - - return ( -
- {/* Tabs for navigation — label prop only, no inline content */} - - {tabs.map((tab) => ( - - ))} - - - {/* Router outlet renders the routed view */} -
- -
-
- ); -} -``` - -**Key rules for tabs-as-navigation:** -- ✅ Use only `IgrTab` with label prop or `slot="label"` — no inline content -- ✅ Sync the active tab to the current route using the `selected` prop -- ✅ Handle `onChange` to call `navigate()` for route changes -- ✅ Use `` (or the equivalent in your router) for content rendering diff --git a/skills/igniteui-react-components/reference/MCP-SERVER.md b/skills/igniteui-react-components/reference/MCP-SERVER.md deleted file mode 100644 index c617bb4..0000000 --- a/skills/igniteui-react-components/reference/MCP-SERVER.md +++ /dev/null @@ -1,77 +0,0 @@ -# Setting Up the Ignite UI CLI MCP Server - -> **Part of the [`igniteui-react-components`](../SKILL.md) skill hub.** - -## Contents - -- [VS Code](#vs-code) -- [Cursor](#cursor) -- [Claude Desktop](#claude-desktop) -- [WebStorm / JetBrains IDEs](#webstorm--jetbrains-ides) -- [Verifying the Setup](#verifying-the-setup) - -The Ignite UI CLI MCP server enables AI assistants to generate production-ready theming code. It must be configured in your editor before the theming tools become available. - -## VS Code - -Create or edit `.vscode/mcp.json` in your project: - -```json -{ - "servers": { - "igniteui-cli": { - "command": "npx", - "args": ["-y", "igniteui-cli", "mcp"] - } - } -} -``` - -This works whether `igniteui-cli` is installed locally in `node_modules` or needs to be pulled from the npm registry — `npx -y` handles both cases. - -## Cursor - -Create or edit `.cursor/mcp.json`: - -```json -{ - "mcpServers": { - "igniteui-cli": { - "command": "npx", - "args": ["-y", "igniteui-cli", "mcp"] - } - } -} -``` - -## Claude Desktop - -Edit the Claude Desktop config file: -- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` -- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` - -```json -{ - "mcpServers": { - "igniteui-cli": { - "command": "npx", - "args": ["-y", "igniteui-cli", "mcp"] - } - } -} -``` - -## WebStorm / JetBrains IDEs - -1. Go to **Settings → Tools → AI Assistant → MCP Servers** -2. Click **+ Add MCP Server** -3. Set Command to `npx` and Arguments to `-y igniteui-cli mcp` -4. Click OK and restart the AI Assistant - -## Verifying the Setup - -After configuring the MCP server, ask your AI assistant: - -> "List all available Ignite UI components" - -If the MCP server is running, the `list_components` tool will return all available components for the detected framework. diff --git a/skills/igniteui-react-components/reference/MCP.md b/skills/igniteui-react-components/reference/MCP.md new file mode 100644 index 0000000..9972052 --- /dev/null +++ b/skills/igniteui-react-components/reference/MCP.md @@ -0,0 +1,43 @@ +# Ignite UI CLI MCP Server + +Provides authoritative component docs and API reference. Prefer it over recall for prop, slot, event, and enum names. + +## Tools + +All tools take a named-argument object. **The platform argument is named differently across tools** — doc tools use `framework`, API tools use `platform`. Both accept `angular | react | webcomponents | blazor`; always pass `react`. + +| Tool | Arguments | +|---|---| +| `list_components` | `framework`, `filter?` (substring over name/keywords/summary) | +| `get_doc` | `framework`, `name` (kebab-case doc name from `list_components`/`search_docs`, no `.md`) | +| `search_docs` | `query` (full-text; `grid*` prefix matching supported), `framework` | +| `search_api` | `query`, `platform?` (omit to search all platforms) | +| `get_api_reference` | `platform`, `component`, `section?` (`properties \| methods \| events \| all`), `member?` | +| `get_project_setup_guide` | `framework?` | + +``` +list_components({ framework: 'react', filter: 'date' }) +get_doc({ framework: 'react', name: 'grid-editing' }) +get_api_reference({ platform: 'react', component: 'IgrCombo', section: 'events' }) +search_api({ query: 'row selection', platform: 'react' }) +``` + +Pass the doc `name` field from `list_components` to `get_doc`, not the human-readable title. Use `section` on `get_api_reference` to keep responses small. Narrow filters beat broad ones — `filter: 'list view'` rather than `'list'`. + +## Setup + +If `list_components` is unavailable, add the server config, then tell the user to reload the editor so the tools activate. Do not block on it — this skill works without MCP; fall back to the installed `.d.ts` files under `node_modules/igniteui-webcomponents/components/` and `node_modules/igniteui-webcomponents-grids/grids/lib/`, which carry `@slot`, `@csspart`, `@fires`, and `@cssproperty` annotations. + +VS Code — `.vscode/mcp.json`: + +```json +{ + "servers": { + "igniteui-cli": { "command": "npx", "args": ["-y", "igniteui-cli", "mcp"] } + } +} +``` + +Cursor (`.cursor/mcp.json`) and Claude Desktop (`%APPDATA%\Claude\claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS) use the same entry under an `mcpServers` key instead of `servers`. JetBrains: **Settings → Tools → AI Assistant → MCP Servers**, command `npx`, arguments `-y igniteui-cli mcp`. + +`npx -y` resolves whether or not `igniteui-cli` is already installed locally. diff --git a/skills/igniteui-react-components/reference/REFS-FORMS.md b/skills/igniteui-react-components/reference/REFS-FORMS.md deleted file mode 100644 index 7d0825a..0000000 --- a/skills/igniteui-react-components/reference/REFS-FORMS.md +++ /dev/null @@ -1,232 +0,0 @@ -# Refs & Forms - -## Refs & Imperative API - -Use `useRef` to access the underlying web component element and call imperative methods (e.g., showing/hiding a dialog, focusing an input). -Components from `igniteui-react`, `igniteui-react-grids` and `igniteui-react-dockmanager` are React Function Components forward the native element to `useRef` and expose alias with the same name for accessing the custom element API: - -```tsx -import { useRef } from 'react'; -import { IgrDialog, IgrButton, IgrInput } from 'igniteui-react'; - -function MyPage() { - const dialogRef = useRef(null); - const inputRef = useRef(null); - - const openDialog = () => { - // Access the underlying web component and call its methods - dialogRef.current?.show(); - }; - - const focusInput = () => { - inputRef.current?.focus(); - }; - - return ( - <> - - Open Dialog - - - -

Are you sure?

- dialogRef.current?.hide()}> - Close - -
- - - Focus Input - - - - ); -} -``` - -> **Tip:** The ref gives you direct access to the web component's DOM element. You can call any method documented in the web component API. - - -## Uncontrolled Components - -`igniteui-react` Form elements like Inputs, Select, Checkbox, etc., integrate with the native form handling through Element internals, allowing to take advantage of the native state management and validation to create intuitive, straightforward forms. Use the `name` attribute to register the field value with `FormData`: - -```tsx -import { IgrInput, IgrSelect, IgrSelectItem, IgrButton } from 'igniteui-react'; - -function SimpleForm() { - const handleSubmit = (e: React.SubmitEvent) => { - // e.preventDefault(); // optionally prevent default submit for custom handling - const formData = new FormData(e.currentTarget); - console.log(formData.get('name')); // input value - console.log(formData.get('role')); // selected option value - }; - - return ( -
- - - User - Admin - Editor - - - Submit - - - ); -} -``` - -## Controlled Components with `useState` - -Wire up Ignite UI form components with React state for controlled behavior: - -```tsx -import { useState } from 'react'; -import { IgrInput, IgrCheckbox, IgrSelect, IgrSelectItem, IgrCheckboxChangeEventArgsDetail } from 'igniteui-react'; - -function ProfileForm() { - const [name, setName] = useState(''); - const [newsletter, setNewsletter] = useState(false); - const [role, setRole] = useState('user'); - - return ( -
- ) => setName(e.detail) } - /> - - ) => - setNewsletter(e.detail.checked) - } - > - Subscribe to newsletter - - - ) => - setRole(e.detail.value) - } - > - User - Admin - Editor - - - ); -} -``` - -## React Hook Form Integration - -Ignite UI components are form-associated web components. You can integrate them with React Hook Form using `Controller`: - -```tsx -import { useForm, Controller } from 'react-hook-form'; -import { IgrInput, IgrCheckbox, IgrButton, IgrCheckboxChangeEventArgsDetail } from 'igniteui-react'; - -interface FormData { - email: string; - acceptTerms: boolean; -} - -function SignUpForm() { - const { control, handleSubmit, formState: { errors } } = useForm(); - - const onSubmit = (data: FormData) => { - console.log(data); - }; - - return ( -
- ( - ) => - field.onChange(e.detail) - } - onBlur={() => field.onBlur()} - invalid={!!errors.email} - /> - )} - /> - {errors.email && {errors.email.message}} - - ( - ) => - field.onChange(e.detail.checked) - } - > - I accept the terms and conditions - - )} - /> - - - Sign Up - - - ); -} -``` - -## TypeScript - -### Importing Component Types - -Each component exports its props interface. Import and use them for type-safe code: - -```tsx -import { IgrButton, IgrInput } from 'igniteui-react'; -import type { ComponentProps } from 'react'; - -// Get the props type for a component -type ButtonProps = ComponentProps; -type InputProps = ComponentProps; - -// Use in your own components -interface FormFieldProps { - label: string; - inputProps?: Partial; -} - -function FormField({ label, inputProps }: FormFieldProps) { - return ( -
- -
- ); -} -``` - -### Auto-complete - -IDEs with TypeScript support will provide auto-complete for all `Igr*` component props. Make sure your `tsconfig.json` includes: - -```json -{ - "compilerOptions": { - "jsx": "react-jsx", - "moduleResolution": "bundler" - } -} -``` diff --git a/skills/igniteui-react-components/reference/TROUBLESHOOTING.md b/skills/igniteui-react-components/reference/TROUBLESHOOTING.md index 9bc5c6a..e9ecfcc 100644 --- a/skills/igniteui-react-components/reference/TROUBLESHOOTING.md +++ b/skills/igniteui-react-components/reference/TROUBLESHOOTING.md @@ -1,147 +1,19 @@ # Troubleshooting -## Issue: Components render without styles - -**Cause:** Missing theme CSS import. Without the theme CSS, components will render with broken layouts, missing icons (showing placeholders), and no visual styling. - -**Solution:** Add the theme CSS import **before** any component usage. In Vite/CRA apps, add it to your entry point. In Next.js, add it to each client component file or the root layout: - -```tsx -// Always required for core components -import 'igniteui-webcomponents/themes/light/bootstrap.css'; - -// Also required when using grids (IgrGrid, IgrTreeGrid, etc.) -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; -``` - -**Next.js example:** - -```tsx -'use client'; - -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; - -import { IgrNavbar, IgrButton } from 'igniteui-react'; -import { IgrGrid, IgrColumn, IgrPaginator } from 'igniteui-react-grids'; -``` - -## Issue: Grid renders but icons show as placeholders and styles are missing - -**Cause:** The grid theme CSS (`igniteui-react-grids/grids/themes/...`) is not imported. The base theme CSS alone is not enough for grids. - -**Solution:** Import **both** theme CSS files: - -```tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Base theme -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; // Grid theme -``` - -## Issue: Grid Lite does not render or compilation error - -**Cause:** `IgrGridLite` is a React wrapper component from `igniteui-react/grid-lite`. It requires **both** `igniteui-react` and `igniteui-grid-lite` packages to be installed. It uses the `Igr` prefix (like all other Ignite UI React wrappers) and does **not** require any `.register()` call. - -**Solution:** - -1. Install both required packages: `npm install igniteui-react igniteui-grid-lite` -2. Import `IgrGridLite` from `igniteui-react/grid-lite` -3. Wrap in a sized container (see [CHARTS-GRIDS.md](./CHARTS-GRIDS.md) for a full example) - -## Issue: `IgrGridLite` is confused with `IgrGrid` from `igniteui-react-grids` - -**Solution:** These are different components: -- `igniteui-react/grid-lite` → lightweight MIT grid (`IgrGridLite`, React wrapper — no `.register()` needed, requires both `igniteui-react` and `igniteui-grid-lite` packages) -- `igniteui-react-grids` → full-featured commercial grids (`IgrGrid`, `IgrTreeGrid`, etc. — React wrappers) - -Import from the correct package for your needs: - -```tsx -// Lightweight grid (MIT, React wrapper, no registration needed) -import { IgrGridLite } from 'igniteui-react/grid-lite'; - -// Full-featured grid (commercial, React wrapper) -import { IgrGrid } from 'igniteui-react-grids'; -``` - -## Issue: Events fire but have unexpected shape - -**Cause:** Ignite UI events are `CustomEvent` objects from the underlying web component, not React `SyntheticEvent` objects. - -**Solution:** Type the handler parameter as `CustomEvent` and access `.detail` for event-specific data or `.target` for the element: - -```tsx -const handleChange = (e: CustomEvent) => { - const target = e.target as HTMLElement; - const detail = e.detail; - // Use target or detail as appropriate -}; -``` - -## Issue: Component methods not accessible - -**Solution:** Use `useRef` with the component type: - -```tsx -const dialogRef = useRef(null); - -// Call imperative method -dialogRef.current?.show(); -``` - -## Issue: Chart / gauge / map does not render or is invisible - -**Cause:** Two common causes: -1. The corresponding module was not registered (e.g., `IgrCategoryChartModule.register()` was not called) -2. The parent container has no explicit dimensions — these components inherit size from their container and will be invisible if the container has zero height/width - -**Solution:** - -1. **Register the module** at the top level of the file (outside the component): - -```tsx -import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; -IgrCategoryChartModule.register(); -``` - -2. **Wrap the chart in a sized container** with explicit dimensions: - -```css -.chart-container { - min-width: 400px; - min-height: 300px; - flex-grow: 1; - flex-basis: 0; -} -.chart-container > * { height: 100%; width: 100%; } -``` - -```tsx -
- -
-``` - -## Issue: IgrTabs used for navigation fills the entire view with content - -**Cause:** Inline content was included in `IgrTab` elements when using tabs for navigation with React Router. The tab content areas take up space and push the routed content out of view. - -**Solution:** When using `IgrTabs` for navigation, use **only the label** (via `label` prop or `slot="label"`) — do NOT include inline content. Let the router's `` render the content: - -```tsx -// ✅ Correct — navigation tabs with label-only (no inline content) - - - - - - -// ❌ Wrong — inline content creates unwanted space when used for navigation - - -

This content will show and take up space!

{/* Don't do this for navigation */} -
- -

This content will show and take up space!

{/* Don't do this for navigation */} -
-
-``` +| Symptom | Cause | Fix | +|---|---|---| +| Components render unstyled, icons show as placeholder boxes | No theme CSS | Import `igniteui-webcomponents/themes//.css` before use; in Next.js, in `app/layout.tsx` or each `'use client'` file | +| Grid unstyled but other components fine | Grid theme CSS missing — the base theme does not cover grids | Also import `igniteui-react-grids/grids/themes//.css` | +| Theme overrides do nothing | Override CSS imported before the theme | Import overrides *after* the theme | +| `--ig-primary-h` / `-s` / `-l` overrides do nothing | Those tokens do not exist | Override the shade: `--ig-primary-500: #0d6efd` — other shades derive from it | +| CSS rules never match | Selector uses the React name | Target the element: `igc-button`, not `IgrButton`; `::part()` for internals | +| Chart / gauge / map invisible | Module not registered, or container has no height | `.register()` at module scope; size the container | +| A chart series or axis silently missing | `IgrDataChart` capability module not registered | Register the module for that series/layer type | +| Grid Lite fails to resolve | `igniteui-grid-lite` not installed (optional peer) | `npm install igniteui-grid-lite`; import from `igniteui-react/grid-lite` | +| Grid renders no rows | No `height` on the grid | Set `height` — row virtualization needs it | +| Dead space right of the last column | Explicit `width` on every column | Remove widths, or leave one column without one | +| Event handler gets `undefined` | Reading React `SyntheticEvent` fields | It is a `CustomEvent`; read `e.detail` (or `e.target`) | +| Navigation tabs push routed content off screen | Inline content inside router-driven `IgrTab` | Label-only tabs; render the route outlet outside `IgrTabs` | +| Filter UI never appears | Only `filterable` set | `allowFiltering` on the grid *and* `filterable` on the column | +| `*Module.register()` reported as deprecated | `igniteui-react` / `-grids` / `grid-lite` / `-dockmanager` auto-register | Delete the call — it is only needed for charts, gauges, and maps | +| Child renders in the wrong place | Wrong or misspelled `slot` name | Confirm the name via `get_doc` or the `@slot` annotations in the component `.d.ts` | diff --git a/skills/igniteui-react-components/reference/USAGE.md b/skills/igniteui-react-components/reference/USAGE.md new file mode 100644 index 0000000..98a7961 --- /dev/null +++ b/skills/igniteui-react-components/reference/USAGE.md @@ -0,0 +1,85 @@ +# Writing `Igr*` JSX + +## Props and slots + +Props behave like any React component — pass expressions, not strings, for numbers and booleans (``, not `value="50"`). + +Children go to the default slot; named slots use the `slot` attribute on the child: + +```tsx + + + +

Title

+

Subtitle

+
+ Body + + Cancel + Confirm + +
+``` + +Slot names are per-component (`start`, `end`, `prefix`, `suffix`, `helper-text`, `title`, `subtitle`, `thumbnail`, `label`, `icon`, `content`, …). Confirm them with `get_doc` or the `@slot` annotations in the component's `.d.ts` — guessing a slot name silently renders the child into the default slot. + +## Events + +The web component's `igcFoo` becomes the `onFoo` prop. Handlers receive the `CustomEvent`, so payloads live on `e.detail`. + +Each event has a generated type pair: `IgrEventArgs` is `CustomEventEventArgsDetail>`. Use the `…EventArgs` alias: + +```tsx +import { + IgrCheckbox, type IgrCheckboxChangeEventArgs, + IgrInput, type IgrComponentValueChangedEventArgs, +} from 'igniteui-react'; + + setChecked(e.detail.checked)}> + Subscribe + + + setQuery(e.detail)} /> +``` + +Frequently used events — `onInput` (per keystroke) and `onChange` (committed) on `IgrInput`; `onChange` on `IgrCheckbox`, `IgrSwitch`, `IgrSelect`, `IgrCombo`, `IgrRadioGroup`, `IgrTabs`, `IgrCalendar`, `IgrDatePicker`; `onInput`/`onChange` on `IgrSlider`; `onClosing`/`onClosed` on `IgrDialog`. Detail shapes differ per component — `get_api_reference({ platform: 'react', component: 'IgrCombo', section: 'events' })`. + +## Refs + +The exported name is both the component and its element type, so `useRef` gives you the custom element and its imperative API: + +```tsx +const dialog = useRef(null); +await dialog.current?.show(); // show/hide/toggle return Promise + + +

Are you sure?

+ dialog.current?.hide()}>Close +
+``` + +## Forms + +Inputs, select, checkbox, switch, and radio are form-associated custom elements, so uncontrolled forms work natively — give each a `name` and read `FormData`. Native validation (`required`, `pattern`, …) participates too. + +```tsx +const onSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const data = new FormData(e.currentTarget); + data.get('name'); +}; + +
+ + + Admin + + Submit + +``` + +Controlled: pass `value`/`checked` and update from `e.detail`. With React Hook Form, wrap in `Controller` and map `field.onChange(e.detail)` — components are not native ``s, so `register()` alone will not track them. + +## TypeScript + +`ComponentProps` extracts the prop type when you wrap a component. For editor completion, keep `"jsx": "react-jsx"` and `"moduleResolution": "bundler"` in `tsconfig.json`. diff --git a/skills/igniteui-react-customize-theme/SKILL.md b/skills/igniteui-react-customize-theme/SKILL.md index bd83764..2b78018 100644 --- a/skills/igniteui-react-customize-theme/SKILL.md +++ b/skills/igniteui-react-customize-theme/SKILL.md @@ -1,184 +1,132 @@ --- name: igniteui-react-customize-theme -description: This skill customizes Ignite UI for React component styling using CSS custom properties and the full theming system and should be used when applying brand colors, dark mode, component-level overrides, or scoped themes in a React application +description: Theme Ignite UI for React with CSS custom properties — brand palette, dark mode, size/spacing/roundness, per-component tokens, and scoped themes, optionally via the igniteui-theming MCP server. Use when applying brand colors, switching light/dark, overriding a component's appearance (grid headers, buttons, avatars), or when theme overrides are not taking effect. user-invocable: true --- -# Ignite UI for React — Theming Skill +# Ignite UI for React — Theming -## Prerequisites +## How the palette actually works -- A React project with `igniteui-react` installed -- A theme CSS file imported in your entry point (see [igniteui-react-components](../igniteui-react-components/SKILL.md)) -- The **Ignite UI Theming MCP server** (`igniteui-theming`) +Every palette role (`primary`, `secondary`, `surface`, `gray`, `info`, `success`, `warn`, `error`) exposes shades `50`–`900` plus a `-contrast` variant per shade. **Shades other than `500` are derived from `500` via relative color functions** — the theme CSS defines them as `hsl(from var(--ig-primary-500) h calc(s * …) calc(l * …))`. -> **AGENT INSTRUCTION — MCP Server Setup (REQUIRED)** -> -> Before using any theming tools, you MUST verify the MCP server is available -> by calling `detect_platform`. If the tool is not available or the call fails, -> you MUST automatically configure it by following the setup process steps described below. -> -> After writing the file, inform the user that the MCP server has been -> configured and they may need to reload the editor for the tools to activate. -> Start the MCP server and wait for that MCP server to start before continuing the theming related work. -> Do NOT skip this step or ask the user to do it manually. +So to rebrand, override the `500` shade and everything else follows: -## Description - -This skill teaches AI agents how to theme Ignite UI for React applications. One approach is supported: - -- **CSS custom properties** — works in any project without additional build tooling - -The skill also covers component-level theming, layout controls (spacing, sizing, roundness), and how to use the **Ignite UI Theming MCP server** for AI-assisted code generation — all in a React application context. - -## Example Usage - -- "How do I change the primary color in my Ignite UI React app?" -- "Apply a dark theme to my React app" -- "Customize the grid header colors" -- "How do I scope a theme to a specific section of my React app?" -- "Set up Material Design theming for Ignite UI components" - -## Setting Up the Theming MCP Server - -> **Full setup instructions for VS Code, Cursor, Claude Desktop, and JetBrains IDEs are in [`reference/MCP-SERVER.md`](./reference/MCP-SERVER.md).** Read that file for editor-specific configuration steps and verification. - -## Related Skills - -- [igniteui-react-components](../igniteui-react-components/SKILL.md) — Choose the right components and set up your React project -- [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md) — Optimize after theming - -## When to Use - -- Applying custom brand colors or a dark theme to an Ignite UI React app -- Overriding individual component styles (e.g., grid header color, button appearance) -- Switching between light and dark mode in a React app -- Scoping different themes to different sections of a React app -- Setting up the Ignite UI Theming MCP server for AI-assisted theming - ---- - -## Content Guide - -This skill is organized into focused sections. Refer to the appropriate file for detailed instructions: - -| Topic | File | When to Use | -|---|---|---| -| CSS Theming | [CSS-THEMING.md](./reference/CSS-THEMING.md) | Pre-built themes, CSS custom properties, scoped overrides, layout controls, light/dark switching | -| MCP Server | [MCP-SERVER.md](./reference/MCP-SERVER.md) | AI-assisted theming code generation | -| Troubleshooting | [TROUBLESHOOTING.md](./reference/TROUBLESHOOTING.md) | Common issues and solutions | +```css +/* src/index.css — imported AFTER the theme CSS */ +:root { + --ig-primary-500: #0d6efd; + --ig-secondary-500: #ff9800; +} +``` ---- +**There are no `--ig-primary-h` / `-s` / `-l` tokens.** Writing them is a silent no-op — a common and hard-to-spot mistake. The same applies to `--ig-surface-h`, `--ig-gray-h`, and every other `-h`/`-s`/`-l` name. -## Quick Start +Always reference palette tokens rather than literals in your own CSS: `var(--ig-primary-500)`, `var(--ig-primary-500-contrast)` for text on top of it. `50` is lightest, `900` darkest. -### 1. Import a Pre-built Theme (REQUIRED) +## Order matters ```tsx // main.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import 'igniteui-webcomponents/themes/light/bootstrap.css'; // theme +import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; // grid theme, if using grids +import './index.css'; // your overrides — last ``` -**For grids**, also import: - -```tsx -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; -``` +Design systems: `bootstrap` (default), `material`, `fluent`, `indigo`; each in `light` and `dark`. -### 2. Override with CSS Custom Properties +## Global layout knobs ```css -/* src/index.css */ :root { - --ig-primary-h: 211deg; - --ig-primary-s: 100%; - --ig-primary-l: 50%; + --ig-size: 2; /* 1 small, 2 medium, 3 large */ + --ig-spacing: 1; /* 0.5 compact … 2 spacious; also -inline / -block variants */ + --ig-radius-factor: 1; /* 0 square … 1 fully rounded */ } ``` -```tsx -// main.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Theme first -import './index.css'; // Overrides second -``` +All three cascade, so they scope to a subtree or a single element: `igc-button { --ig-size: 1; }`. ---- +## Component-level overrides + +Selectors target the **rendered element**, never the React name: -## Theming Architecture +```css +igc-avatar { + --ig-avatar-background: var(--ig-primary-500); + --ig-avatar-color: var(--ig-primary-500-contrast); +} -The Ignite UI theming system is built on **palette**, **typography**, **elevations**, and per-component **schemas**. Use the MCP theming tools at the right stage: +igc-input::part(input) { font-size: 1.1rem; } /* ::part() reaches shadow DOM internals */ +``` -- **`create_palette`** — when the user provides brand colors; generates luminance-safe shades for all palette roles -- **`create_theme`** — generates the complete global theme CSS; call after `create_palette` -- **`create_typography`** — when the user wants to change fonts, type scale, or weights -- **`create_elevations`** — when the user wants to adjust shadow depth -- **`get_component_design_tokens`** - before writing any component-level CSS; retrieves the current token names for a specific component -- **`set_size`**, **`set_spacing`**, or **`set_roundness`** - adjust component size, content spacing, and roundness. +**Component token names are per-component and not guessable.** `igc-avatar` has `--ig-avatar-background`, but `igc-button` exposes only typographic tokens (`--ig-button-font-size`, …) and has no `--ig-button-foreground`. Before writing any component token, get the real list: `get_component_design_tokens({ component: 'button' })`, or read the `@cssproperty` annotations in `node_modules/igniteui-webcomponents/components//*.d.ts`. If a component exposes no token for what you need, use `::part()`. -### Design Systems +## Scoping -- **Bootstrap** (default), **Material**, **Fluent**, **Indigo** -- Each has light and dark variants +Palette tokens cascade, so a scoped theme is just custom properties on a container: ---- +```css +.admin { --ig-primary-500: #7c4dff; } +``` -## Key Concepts +## Dark mode -### CSS Custom Properties +The theme CSS also declares `--ig-theme` and `--ig-theme-variant` on `:root`. Components read those **once, globally**, from `document.documentElement` to pick their shadow-DOM styles. Two consequences: -Override tokens in your CSS: +- **The variant cannot be scoped to a subtree.** Overriding `--ig-theme-variant` on a wrapper does nothing. Dark mode is an app-wide switch. +- **Swapping the stylesheet is not enough at runtime** — the value is cached. Call `configureTheme`, which is re-exported from `igniteui-react`, to update it and notify mounted components: -```css -:root { --ig-primary-h: 211deg; } -.admin-panel { --ig-primary-h: 260deg; } +```tsx +import { configureTheme } from 'igniteui-react'; + +configureTheme('bootstrap', 'dark'); // design system, variant ``` -### Component-Level Theming +Prefer a real dark theme file (`themes/dark/bootstrap.css`) over hand-overriding palette tokens: it re-tunes surface, gray, elevations, and every component schema. See [CSS-THEMING.md](./reference/CSS-THEMING.md) for the switching patterns. -Target web component tag names in CSS: +When choosing colors for a dark palette, `surface` must be dark (luminance ≤ 0.5) and the `gray` base must be **light**. Gray shades are generated to contrast *against* the surface, so the gray base is always inverted relative to the variant — reversing it produces unreadable text. -```css -igc-button { --ig-button-foreground: var(--ig-secondary-500); } -``` +## Using the `igniteui-theming` MCP server -### CSS `::part()` Selectors +Optional but preferred when available — it generates palettes with luminance-safe shades and correct contrast. Verify with `detect_platform`; if missing, add the config below and tell the user to reload the editor. Pass `platform: 'react'`. -```css -igc-input::part(input) { font-size: 1.1rem; } -``` +| Stage | Tool | +|---|---| +| Brand colors → palette | `create_palette` (`primary`, `secondary`, `surface`, `gray`, `info`, `success`, `warn`, `error`, `variant`) | +| Multiple surface depths or several accent families | `create_custom_palette` | +| Fonts, type scale | `create_typography` | +| Shadow depth | `create_elevations` | +| Full global theme | `create_theme` (`primaryColor`, `secondaryColor`, `surfaceColor`, `variant`, `designSystem`, `fontFamily`) | +| Discover a component's tokens | `get_component_design_tokens` (`component`) | +| Component override block | `create_component_theme` (`component`, `tokens`, `selector`, `variant`, `designSystem`) | +| Resolve a palette color | `get_color` (`color`, `variant`, `contrast`, `opacity`) | +| Size / spacing / roundness | `set_size`, `set_spacing`, `set_roundness` | +| Guidance documents | `read_resource` (`uri`), e.g. `theming://guidance/colors/rules` | -### Layout Controls +All tools take named arguments. There is no `get_theming_guidance` tool — guidance is read through `read_resource`. -```css -:root { - --ig-size: 2; /* 1=small, 2=medium, 3=large */ - --ig-spacing: 1; /* 0.5=compact, 1=default, 2=spacious */ - --ig-radius-factor: 1; /* 0=square, 1=max radius */ +Sequence: `create_palette` → `create_typography` / `create_elevations` → `create_theme` → per component `get_component_design_tokens` → `create_component_theme` with only the tokens that differ from the global theme. Read any luminance warning the tools return instead of ignoring it; if one generated surface color cannot express every depth in the design, use `create_custom_palette` or define your own `--surface-1` / `--surface-2` semantic variables. + +**Never overwrite an existing stylesheet.** Propose generated theme code as an edit the user reviews. + +VS Code — `.vscode/mcp.json` (Cursor and Claude Desktop use the same entry under `mcpServers`): + +```json +{ + "servers": { + "igniteui-theming": { + "command": "npx", + "args": ["-y", "igniteui-theming", "igniteui-theming-mcp"] + } + } } ``` -### Light/Dark Switching +## Reference -See [CSS-THEMING.md](./reference/CSS-THEMING.md) for approaches: class toggle, media query, or stylesheet swap. +- [CSS-THEMING.md](./reference/CSS-THEMING.md) — scoping patterns, CSS Modules, light/dark switching, inline overrides ---- +## Related skills -## Best Practices - -1. **Import theme CSS first**, then your custom overrides -2. **Use palette tokens** (`var(--ig-primary-500)`) for all colors — never hardcode hex values -3. **Use CSS custom properties on `:root`** for global theme adjustments -4. **Scope overrides with CSS classes** for different sections -5. **Use `::part()` selectors** to style shadow DOM internals -6. **In CSS selectors, use web component tag names** (`igc-button`), not React names (`IgrButton`) -7. **Test both light and dark themes** -8. **Use the MCP server** for AI-assisted theme generation when available - -## Key Rules - -1. **Never overwrite existing files directly** — propose theme code as an update for user review -2. **Always call `detect_platform` first** when using MCP tools -3. **Always call `get_component_design_tokens` before `create_component_theme`** -4. **Palette shades**: 50 = lightest, 900 = darkest -5. **Surface color must match variant** — light color for `light`, dark for `dark` -6. **Never hardcode colors after palette generation** +- [igniteui-react-components](../igniteui-react-components/SKILL.md) — components, theme CSS setup, slots and events diff --git a/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md b/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md index 77e5f2f..c927661 100644 --- a/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md +++ b/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md @@ -1,267 +1,100 @@ -# CSS Theming +# CSS Theming Patterns -This guide covers theming Ignite UI for React using CSS custom properties — works in any project without additional build tooling. +Read [../SKILL.md](../SKILL.md) first — it covers the token model (`--ig-primary-500` and derived shades), import order, and why `-h`/`-s`/`-l` tokens do not exist. -## Pre-built Themes +## Scoping overrides -Import a pre-built CSS file in your React entry point: - -```tsx -// main.tsx or index.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -``` - -> **CRITICAL:** Theme CSS imports are **required** for components to render correctly. - -**For grids**, you **must also** import the grid theme CSS: - -```tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; -``` - -### Available Pre-built CSS Files - -| Import path | Theme | -|---|---| -| `igniteui-webcomponents/themes/light/bootstrap.css` | Bootstrap Light | -| `igniteui-webcomponents/themes/dark/bootstrap.css` | Bootstrap Dark | -| `igniteui-webcomponents/themes/light/material.css` | Material Light | -| `igniteui-webcomponents/themes/dark/material.css` | Material Dark | -| `igniteui-webcomponents/themes/light/fluent.css` | Fluent Light | -| `igniteui-webcomponents/themes/dark/fluent.css` | Fluent Dark | -| `igniteui-webcomponents/themes/light/indigo.css` | Indigo Light | -| `igniteui-webcomponents/themes/dark/indigo.css` | Indigo Dark | - -Grid theme CSS files follow the same pattern under `igniteui-react-grids/grids/themes/`. - -### Next.js - -In Next.js, import the theme CSS in each client component file or in a shared root layout: - -```tsx -// app/layout.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; - -export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - {children} - - ); -} -``` - -## Custom Theme via CSS Custom Properties - -After importing a pre-built theme, override individual design tokens with CSS custom properties. - -### Global Overrides (in your CSS file) +Palette tokens are ordinary custom properties, so any of these work. Prefer a class over inline styles. ```css -/* src/index.css */ -:root { - --ig-primary-h: 211deg; - --ig-primary-s: 100%; - --ig-primary-l: 50%; - - --ig-secondary-h: 33deg; - --ig-secondary-s: 100%; - --ig-secondary-l: 50%; -} -``` - -Import it in your entry point: - -```tsx -// main.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Theme first -import './index.css'; // Overrides — must come after the theme import -``` - -### Scoped Overrides - -Use a CSS class to scope theme overrides to a specific container: - -```css -/* src/AdminPanel.css */ -.admin-panel { - --ig-primary-h: 260deg; - --ig-primary-s: 60%; - --ig-primary-l: 45%; -} -``` - -```tsx -// AdminPanel.tsx -import './AdminPanel.css'; -import { IgrButton, IgrInput } from 'igniteui-react'; - -function AdminPanel() { - return ( -
- - Save -
- ); -} +/* plain class */ +.admin-panel { --ig-primary-500: #7c4dff; } ``` -### CSS Modules - ```css -/* AdminPanel.module.css */ -.panel { - --ig-primary-h: 260deg; - --ig-primary-s: 60%; - --ig-primary-l: 45%; -} +/* CSS Modules */ +.panel { --ig-primary-500: #7c4dff; } ``` ```tsx import styles from './AdminPanel.module.css'; -import { IgrButton } from 'igniteui-react'; -function AdminPanel() { - return ( -
- Save -
- ); -} +
+ Save +
``` -### Inline Styles on a Wrapper - -For truly dynamic one-off overrides: +Inline styles need a cast, since TypeScript's `CSSProperties` does not accept custom property names: ```tsx -
- Custom Color Button +
+
``` -> **Note:** TypeScript requires the `as React.CSSProperties` cast. Prefer CSS classes when possible. +## Light / dark switching -## Component-Level Theming +Both `themes/light/*.css` and `themes/dark/*.css` define their tokens on `:root`, so importing both means the later import wins globally — you cannot scope one to a subtree. Pick one of these instead. -Override individual component appearance using CSS custom properties. +**Static, follow the OS.** No JavaScript, but the variant is fixed at load, so components that read `--ig-theme-variant` see whatever matched first. -> **AGENT INSTRUCTION**: Before writing component-level token overrides, call `get_component_design_tokens` with the component name (e.g., `"avatar"`, `"button"`, `"grid"`) to retrieve the current, correct token names. Token names vary by component and can change between versions. Use only tokens returned by that call — do not guess or reuse tokens from other components. - -```css -/* Target the Ignite UI web component tag name */ -igc-avatar { - --ig-avatar-background: var(--ig-primary-500); - --ig-avatar-color: var(--ig-primary-500-contrast); -} - -igc-button { - --ig-button-foreground: var(--ig-secondary-500); -} +```html + + ``` -> **IMPORTANT — No Hardcoded Colors** -> -> ✅ **Right:** `--ig-avatar-background: var(--ig-primary-500);` -> ❌ **Wrong:** `--ig-avatar-background: #E91E63;` +**Runtime toggle.** Swap the active stylesheet *and* call `configureTheme` so mounted components restyle: -### CSS `::part()` Selectors +```tsx +import { useEffect, useState } from 'react'; +import { configureTheme, type Theme, type ThemeVariant } from 'igniteui-react'; -Use `::part()` selectors to style shadow DOM internal elements: +export function useIgTheme(design: Theme = 'bootstrap') { + const [variant, setVariant] = useState('light'); -```css -igc-input::part(input) { - font-size: 1.1rem; -} + useEffect(() => { + const link = document.getElementById('ig-theme') as HTMLLinkElement | null; + if (link) link.href = `/themes/${variant}/${design}.css`; + configureTheme(design, variant); + }, [variant, design]); -igc-card::part(header) { - padding: 1rem; + return [variant, setVariant] as const; } ``` -> **Note:** In CSS, use web component tag names (`igc-input`), not React component names (`IgrInput`). +`Theme` is `'bootstrap' | 'material' | 'fluent' | 'indigo'` and `ThemeVariant` is `'light' | 'dark'`; both are re-exported from `igniteui-react`. -## Layout Controls +Serve the CSS from your own build output or public directory — do not point a `` at `node_modules`, which is not deployed. -### Sizing +**Partial dark surfaces.** If only one panel must look dark, do not fight the global variant. Define semantic variables for the depths you need and use them in your own CSS, leaving Ignite UI components on the app-wide variant: ```css -:root { --ig-size: 2; } /* 1 = small, 2 = medium, 3 = large */ -igc-button { --ig-size: 1; } +.dark-panel { + --surface-1: var(--ig-gray-900); + --surface-2: var(--ig-gray-800); + background: var(--surface-1); + color: var(--ig-gray-50); +} ``` -### Spacing +## Component internals -```css -:root { --ig-spacing: 1; } /* 0.5 = compact, 1 = default, 2 = spacious */ -.compact-section { --ig-spacing: 0.75; } -``` - -### Roundness +When a component exposes no custom property for what you need, reach for `::part()`: ```css -:root { --ig-radius-factor: 1; } /* 0 = square, 1 = maximum radius */ -igc-avatar { --ig-radius-factor: 0.5; } +igc-input::part(input) { font-size: 1.1rem; } +igc-card::part(header) { padding: 1rem; } ``` -## Switching Between Light and Dark Themes +Available parts are listed as `@csspart` annotations in `node_modules/igniteui-webcomponents/components//*.d.ts`. Parts are stable API; descendant selectors into the shadow DOM are not available at all. + +## Grid themes -### Approach 1: CSS class toggle +Grids need a second stylesheet alongside the base theme, matched on both variant and design system: ```tsx -import { useState } from 'react'; import 'igniteui-webcomponents/themes/light/bootstrap.css'; -import './theme-overrides.css'; - -function App() { - const [isDark, setIsDark] = useState(false); - - return ( -
- -
- ); -} -``` - -```css -/* theme-overrides.css */ -.dark-theme { - --ig-surface-h: 0deg; - --ig-surface-s: 0%; - --ig-surface-l: 7%; - - --ig-gray-h: 0deg; - --ig-gray-s: 0%; - --ig-gray-l: 100%; -} -``` - -### Approach 2: CSS media query - -```css -@media (prefers-color-scheme: dark) { - :root { - --ig-surface-h: 0deg; - --ig-surface-s: 0%; - --ig-surface-l: 7%; - } -} +import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; ``` -### Approach 3: Dynamically swap theme stylesheet - -```tsx -import { useEffect } from 'react'; - -function useTheme(variant: 'light' | 'dark', design = 'bootstrap') { - useEffect(() => { - const link = document.getElementById('igc-theme') as HTMLLinkElement; - if (link) { - link.href = `node_modules/igniteui-webcomponents/themes/${variant}/${design}.css`; - } - }, [variant, design]); -} -``` +Grid tokens are prefixed per component, e.g. `--ig-grid-header-background`, `--ig-grid-content-background`, `--ig-grid-row-even-background`. Confirm names with `get_component_design_tokens({ component: 'grid' })` rather than guessing. diff --git a/skills/igniteui-react-customize-theme/reference/MCP-SERVER.md b/skills/igniteui-react-customize-theme/reference/MCP-SERVER.md deleted file mode 100644 index eae57e7..0000000 --- a/skills/igniteui-react-customize-theme/reference/MCP-SERVER.md +++ /dev/null @@ -1,67 +0,0 @@ -# Ignite UI Theming MCP Server - -The Ignite UI Theming MCP server enables AI assistants to generate production-ready theming code. It must be configured in your editor before the theming tools become available. - -> **AGENT INSTRUCTION — MCP Server Setup (REQUIRED)** -> -> Before using any theming tools, you MUST verify the MCP server is available -> by calling `detect_platform`. If the tool is not available or the call fails, -> configure it by following the setup steps below. - -## VS Code Setup - -Create or edit `.vscode/mcp.json` in your project: - -```json -{ - "servers": { - "igniteui-theming": { - "command": "npx", - "args": ["-y", "igniteui-theming", "igniteui-theming-mcp"] - } - } -} -``` - -## Cursor Setup - -Create or edit `.cursor/mcp.json`: - -```json -{ - "mcpServers": { - "igniteui-theming": { - "command": "npx", - "args": ["-y", "igniteui-theming", "igniteui-theming-mcp"] - } - } -} -``` - -## Claude Desktop Setup - -Edit the Claude Desktop config file: -- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` -- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` - -```json -{ - "mcpServers": { - "igniteui-theming": { - "command": "npx", - "args": ["-y", "igniteui-theming", "igniteui-theming-mcp"] - } - } -} -``` - -## WebStorm / JetBrains IDEs Setup - -1. Go to **Settings → Tools → AI Assistant → MCP Servers** -2. Click **+ Add MCP Server** -3. Set Command to `npx` and Arguments to `igniteui-theming igniteui-theming-mcp` -4. Click OK and restart the AI Assistant - -## File Safety Rule - -> **IMPORTANT — File Safety Rule**: When generating theme code, **never overwrite existing style files directly**. Always propose changes as an update and let the user review before writing to disk. diff --git a/skills/igniteui-react-customize-theme/reference/TROUBLESHOOTING.md b/skills/igniteui-react-customize-theme/reference/TROUBLESHOOTING.md deleted file mode 100644 index 5faef71..0000000 --- a/skills/igniteui-react-customize-theme/reference/TROUBLESHOOTING.md +++ /dev/null @@ -1,35 +0,0 @@ -# Theming Troubleshooting - -## Issue: Theme overrides not taking effect - -**Cause:** Override CSS is loaded before the theme CSS. - -**Solution:** Make sure your custom CSS is imported *after* the theme: - -```tsx -// main.tsx -import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Theme first -import './custom-overrides.css'; // Overrides second -``` - -## Issue: CSS custom properties not recognized by TypeScript in inline styles - -**Solution:** Cast to `React.CSSProperties`: - -```tsx -
-``` - -## Issue: Component-level CSS selectors don't match - -**Cause:** Using React component name instead of web component tag name in CSS. - -**Solution:** Use the underlying web component tag name in CSS selectors: - -```css -/* ✅ Correct — web component tag */ -igc-button { --ig-size: 1; } - -/* ❌ Wrong — React wrapper name */ -IgrButton { --ig-size: 1; } -``` diff --git a/skills/igniteui-react-generate-from-image-design/SKILL.md b/skills/igniteui-react-generate-from-image-design/SKILL.md index c18cae1..e7d33ed 100644 --- a/skills/igniteui-react-generate-from-image-design/SKILL.md +++ b/skills/igniteui-react-generate-from-image-design/SKILL.md @@ -1,229 +1,100 @@ --- name: igniteui-react-generate-from-image-design -description: Implement React application views from design images using Ignite UI for React components. Uses MCP servers (igniteui-cli, igniteui-theming) and tools for component discovery, docs lookup, and theming to choose components, generate theme tokens, and follow React-specific best practices. Triggers when the user provides a design image (screenshot, mockup, wireframe) and wants it built as a working React view with Ignite UI for React. Also triggers when the user asks to "implement this design", "build this UI", "convert this mockup", or "create a page from this image" in an Ignite UI React project. +description: Build a React view from a design image (screenshot, mockup, wireframe) using Ignite UI for React components and generated theme tokens. Use when the user supplies an image and asks to implement this design, build this UI, convert this mockup, or create a page from this screenshot in an Ignite UI React project. user-invocable: true --- -# Implementing Ignite UI React Views from Design Images +# Implementing a React View from a Design Image -## MANDATORY AGENT PROTOCOL +React only — pass `platform: 'react'` / `framework: 'react'` to every MCP call. -Before writing any implementation code, you must complete these steps in order: +## Order of work -1. Analyze the image and identify all visible regions and UI patterns. -2. Read [reference/component-mapping.md](reference/component-mapping.md) and [reference/gotchas.md](reference/gotchas.md). -3. This skill is React-only. Check package routing, theme CSS imports, or licensing only when imports, packages, or theming depend on it. -4. To apply a theme, use the theming workflow from this skill and the dedicated `igniteui-react-customize-theme` skill; use the `igniteui-theming` MCP tools instead of styling from memory. This skill is React-only, so hardcode `platform: "react"` in theme-generation calls. -5. Call `get_doc` for every chosen component family before using it. -6. Only then start coding. +1. **Read the image.** Identify every region, its component, and the layout structure. +2. **Inspect the app.** Existing theme imports, design system, palette overrides, installed packages. +3. **Look up the components you chose** before writing them — `get_doc`, `get_api_reference`. +4. **Theme** — global layer only if the app has none, then per-component tokens. +5. **Implement** the layout, mock data, and view. +6. **Validate** — build, run, compare with the image, iterate. -## Workflow +Steps 3 and 4 use MCP servers where available; both are optional. Without them, read the installed `.d.ts` files (`node_modules/igniteui-webcomponents/components//`) for props, `@slot`, `@csspart`, and `@cssproperty` names, and theme with the palette shades documented in [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md). -1. **Analyze the design image** - Read the image, identify every UI section, component, and layout structure. -2. **Confirm package routing or theme setup if needed** - this skill is React-only; check package routing, theme CSS imports, or licensing only when imports, packages, or theming depend on it. -3. **Discover components** - Call `list_components` with targeted filters to find matching components for each UI pattern. -4. **Look up component docs** - Call `get_doc` for every chosen component family before coding. -5. **Generate theme** - (a) To generate a theme, first extract colors and create a color palette using `create_palette` or `create_custom_palette` depending on the scenario. Then extract elevations and call `create_elevations`. Then extract typography and call `create_typography`. Then call `create_theme` with the palette, elevations, and typography. (b) After a theme exists, prefer design tokens, or scoped semantic CSS variables over raw literals. (c) For every Ignite UI component, call `get_component_design_tokens`, map extracted image tokens to token roles, then call `create_component_theme` with the tokens differing from the global theme for the specific component. -6. **Implement** - Build the screenshot-first layout, data, and view components. -7. **Refine** - Use the `set_size`, `set_spacing`, and `set_roundness` tools to refine the view's visual fidelity against the image, then iterate on implementation and theming until the view matches the design closely. -8. **Validate** - Build, test, run, compare against the image, and fix differences. +## 1. Read the image -## Step 1: Analyze the Design Image +Record, per region: layout role and proportions, component type, colors, type scale, borders/radius/shadow, data shape, and spacing rhythm. -Read the input image carefully. For each visual section, identify: +Resolve layout as CSS Grid rows and columns that preserve the observed *proportions* — do not reverse-engineer exact pixel values or invent breakpoints yet. Get desktop proportions right first, then add stacking rules. -- **Layout structure**: grid rows/columns, sidebar, navbar, content area proportions, and estimated fixed widths or percentages for major regions. -> Note: Do not guess the exact CSS properties at this stage; just identify the high-level structure and relative proportions. Do not try to fit the view into exact breakpoints or pixel values. Try to generate a flexible layout that preserves the observed proportions and can adapt to different screen sizes. You will refine the exact CSS rules in Step 8 after building a first version of the view. -- **Component type**: chart, list, card, map, gauge, table, form, etc. -- **Color palette**: primary, secondary, surface/background, accent, text colors -- **Typography**: font sizes, weights, letter-spacing patterns -- **Surface styling**: borders, border-radius, shadows, elevation, divider treatments -- **Data patterns**: what mock data is needed (time series, lists, KPIs, geographic) -- **Spacing system**: translate observed padding and gaps into a small reusable scale derived from the design +Before coding, state briefly: chosen component per region, any region falling back to plain HTML and why, theme strategy, packages needed, and assumptions you made where the image is ambiguous. -Before writing code, create a decomposition table with one row per visible region containing: +**Start every region from an Ignite UI component.** Fall back to semantic HTML only when the component's DOM structure stays incompatible after CSS overrides and `::part()` are considered, and say so in a comment. Component picks live in [COMPONENTS.md](../igniteui-react-components/reference/COMPONENTS.md); use `list_components({ framework: 'react', filter: '' })` to discover more. Narrow filters work better — `'list view'`, not `'list'`. -| Region | Visual role | Candidate component | Custom CSS required | Data type | -|---|---|---|---|---| -| Example: sidebar item list | repeated rows with icon + label | `IgrList` | yes - item height, icon size | domain-appropriate mock data | -| Example: top bar | brand + tabs + search | `IgrNavbar` | yes - multi-zone flex layout | n/a | -| Example: side panel | always-visible navigation | `IgrNavDrawer` | yes - width, item styling | n/a | +Judgement calls that recur: -Start every region with the most appropriate Ignite UI component from [reference/component-mapping.md](reference/component-mapping.md). Only fall back to plain semantic HTML when the component DOM structure is fundamentally incompatible with the design after CSS overrides are considered. Document the reason for any plain-HTML fallback in a code comment. +- `IgrNavbar` for a top bar; plain `
` if the design's zones fight the slot structure. +- `IgrNavDrawer` for a sidebar — set open/mini to match fixed, collapsible, or icon-only navigation; plain `
}> - -

Lazy loaded dialog content

-
- - )} - - ); -} +import { IgrButton, IgrCard } from 'igniteui-react'; // ✅ tree-shakes +import * as IgniteUI from 'igniteui-react'; // ❌ defeats tree-shaking +import { IgcButtonComponent } from 'igniteui-webcomponents'; // ❌ bypasses the wrapper ``` -### Lazy Loading a Heavy Page Component - -This is the recommended approach for code-splitting: wrap entire page components that use heavy Ignite UI components. +Never import from `igniteui-webcomponents` (or `igniteui-webcomponents-grids`) directly. It pulls a second copy of the element definitions alongside the wrappers and skips the auto-registration the wrapper performs. -```tsx -// App.tsx -import { BrowserRouter, Routes, Route } from 'react-router-dom'; -import { lazy, Suspense } from 'react'; +## Splitting the heavy families -const HomePage = lazy(() => import('./pages/Home')); -const DashboardPage = lazy(() => import('./pages/Dashboard')); -const AnalyticsPage = lazy(() => import('./pages/Analytics')); - -function App() { - return ( - - Loading...
}> - - } /> - } /> - } /> - - - - ); -} -``` +Lazy-load at the **route or panel** boundary, not the component. `IgrGrid` and the DV charts are only worth splitting when the whole view that uses them is deferred. ```tsx -// pages/Dashboard.tsx — only loaded when navigating to /dashboard -import { IgrGrid, IgrColumn } from 'igniteui-react-grids'; -import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; - -export default function Dashboard() { - return ( - - - - - ); -} +const Dashboard = lazy(() => import('./pages/Dashboard')); // grid + its theme CSS +const Analytics = lazy(() => import('./pages/Analytics')); // charts + registration ``` -```tsx -// pages/Analytics.tsx — only loaded when navigating to /analytics -import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; - -IgrCategoryChartModule.register(); +Two Ignite-UI-specific details: -export default function Analytics() { - return ; -} -``` +- **Keep the grid theme CSS import inside the lazy chunk** (`import 'igniteui-react-grids/grids/themes/light/bootstrap.css'` in `Dashboard.tsx`), so the grid stylesheet is not in the initial payload. The base theme CSS stays in the entry point — every page needs it. +- **Keep `.register()` calls inside the lazy chunk too.** Chart, gauge, and map modules must register at module scope of the file that uses them; hoisting the registration to the entry point pulls the whole DV package back into the initial bundle. -**Result:** The grid and chart bundles are only downloaded when the user navigates to those routes. +For manual chunking, give each family its own chunk so a page needing charts does not download grids: ---- - -## Analyzing Your Bundle - -### Using Vite's Rollup Visualizer - -```bash -npm install --save-dev rollup-plugin-visualizer -``` - -```typescript +```ts // vite.config.ts -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; -import { visualizer } from 'rollup-plugin-visualizer'; - -export default defineConfig({ - plugins: [ - react(), - visualizer({ - open: true, - gzipSize: true, - brotliSize: true, - }) - ] -}); -``` - -```bash -npm run build -# Opens stats.html automatically — inspect which igniteui-react modules are included -``` - -### Using Webpack Bundle Analyzer - -```bash -npm install --save-dev webpack-bundle-analyzer -``` - -```javascript -// webpack.config.js (or CRA with react-app-rewired) -const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); - -module.exports = { - plugins: [ - new BundleAnalyzerPlugin({ - analyzerMode: 'static', - openAnalyzer: false, - reportFilename: 'bundle-report.html' - }) - ] -}; -``` - -### Using source-map-explorer - -```bash -npm install --save-dev source-map-explorer -``` - -```json -{ - "scripts": { - "analyze": "source-map-explorer 'dist/**/*.js'" - } -} -``` - -```bash -npm run build -npm run analyze -``` - -**What to look for:** Check if `igniteui-react-grids` or `igniteui-react-charts` appear in the initial bundle even though they're only used on specific routes. - ---- - -## Audit Your Component Usage - -### 1. Find What Components You're Actually Using - -```bash -# Search for Igr component usage in your source files -grep -roh "Igr[A-Z][a-zA-Z]*" src/ --include="*.tsx" --include="*.ts" | sort | uniq - -# Example output: -# IgrButton -# IgrCard -# IgrInput -``` - -### 2. Compare with Your Imports - -```bash -# Find all import statements from igniteui-react packages -grep -r "from 'igniteui-react" src/ --include="*.tsx" --include="*.ts" -``` - -### 3. Remove Unused Imports - -```tsx -// Before: 5 components imported -import { IgrButton, IgrInput, IgrCard, IgrSelect, IgrCombo } from 'igniteui-react'; - -// After audit: only 3 are actually used in JSX -import { IgrButton, IgrInput, IgrCard } from 'igniteui-react'; -``` - ---- - -## Build Configuration Optimizations - -### Vite Configuration - -```typescript -// vite.config.ts -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; - -export default defineConfig({ - plugins: [react()], - build: { - minify: 'terser', - terserOptions: { - compress: { - drop_console: true, - drop_debugger: true - } - }, - rollupOptions: { - output: { - manualChunks: { - 'igniteui-core': ['igniteui-react'], - // Only include if you use these packages: - // 'igniteui-grids': ['igniteui-react-grids'], - // 'igniteui-charts': ['igniteui-react-charts'], - } - } - }, - chunkSizeWarningLimit: 600, - }, - optimizeDeps: { - include: ['igniteui-react'] - } -}); -``` - -### Webpack Configuration - -```javascript -// webpack.config.js -module.exports = { - optimization: { - splitChunks: { - chunks: 'all', - cacheGroups: { - igniteui: { - test: /[\\/]node_modules[\\/]igniteui-react[\\/]/, - name: 'igniteui', - priority: 20, - }, - igniteuiGrids: { - test: /[\\/]node_modules[\\/]igniteui-react-grids[\\/]/, - name: 'igniteui-grids', - priority: 20, - } - } +build: { + rollupOptions: { + output: { + manualChunks: { + 'ig-core': ['igniteui-react'], + 'ig-grids': ['igniteui-react-grids'], // only if actually installed + 'ig-charts': ['igniteui-react-charts'], + }, }, - minimize: true, }, - mode: 'production', -}; -``` - ---- - -## Best Practices Checklist - -- [ ] **Install only the packages you need** — don't install `igniteui-react-grids` if you only use buttons and inputs -- [ ] **Use named imports** — `import { IgrButton } from 'igniteui-react'`, not `import * as` -- [ ] **Don't import from `igniteui-webcomponents` directly** — use the `igniteui-react` wrappers -- [ ] **Lazy load heavy components** — use `React.lazy` + `Suspense` for grids, charts, and dialogs -- [ ] **Split by routes** — load component-heavy pages only when navigated to -- [ ] **Audit your imports regularly** — remove unused components -- [ ] **Analyze your bundle** — use bundle analyzer tools to verify tree-shaking is working -- [ ] **Minify in production** — ensure build tool minification is enabled -- [ ] **Use compression** — enable gzip/brotli on your server - ---- - -## Common Issues & Solutions - -### Issue: Bundle still large after using named imports - -**Investigate:** -1. Check if you're importing from `igniteui-webcomponents` instead of `igniteui-react` -2. Verify tree-shaking is working (check build output with a bundle analyzer) -3. Look for barrel imports (`import * as`) -4. Check if large packages like `igniteui-react-grids` are in the initial bundle instead of being lazy loaded - -### Issue: Lazy loaded component flashes or shows fallback too long - -**Solution:** Preload the component on hover or route prefetch: - -```tsx -const DashboardPage = lazy(() => import('./pages/Dashboard')); - -// Preload on hover -function NavLink() { - const preload = () => { import('./pages/Dashboard'); }; - return Dashboard; } ``` -### Issue: Tree-shaking not working - -**Cause:** Using `require()` instead of `import`, or a build tool that doesn't support ES module tree-shaking. - -**Solution:** Ensure your project uses ES modules: +## Auditing -```json -// tsconfig.json -{ - "compilerOptions": { - "module": "esnext", - "moduleResolution": "bundler" - } -} +```bash +# components referenced in JSX +grep -rhoE "