- name
- igniteui-wc-customize-component-theme
- description
- Customize Ignite UI Web Components styling using CSS custom properties, optional Sass, and the igniteui-theming MCP server for AI-assisted theming
- user-invocable
- true
# Ignite UI Web Components — Theming Skill
## Description
This skill teaches AI agents how to theme Ignite UI Web Components (and React via `igniteui-react`) applications. Two approaches are supported:
- **CSS custom properties** — works in any project without additional build tooling
- **Sass** — available when the project has Sass configured; provides the full palette/typography/elevation API
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.
## Prerequisites
- A project with `igniteui-webcomponents` (or `igniteui-react`) installed
- The **Ignite UI Theming MCP server** (`igniteui-theming`) available as a tool provider
- **Optional**: Sass configured in the project (enables the Sass-based theming API)
> **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.
## Setting Up the Theming MCP Server
See [references/mcp-setup.md](references/mcp-setup.md) for VS Code, Cursor, Claude Desktop, and WebStorm configuration instructions.
Verify the server is running by calling `detect_platform` — it reads your `package.json` and returns the detected platform (e.g., `webcomponents`).
## Theming Architecture
The theming system is built on four pillars:
| Pillar | Description |
|---|---|
| **Palette** | Color families: `primary`, `secondary`, `surface`, `gray`, `info`, `success`, `warn`, `error` — each with shades 50–900 |
| **Typography** | Font family and type scale (headings, body, captions, etc.) |
| **Elevations** | Box-shadow levels (0–24) |
| **Schema** | Per-component recipes that map palette tokens to component-level CSS custom properties |
Four built-in design systems are available — each with light and dark variants:
| Design System | Variants |
|---|---|
| **Material** | `light/material.css`, `dark/material.css` |
| **Bootstrap** | `light/bootstrap.css`, `dark/bootstrap.css` |
| **Fluent** | `light/fluent.css`, `dark/fluent.css` |
| **Indigo** | `light/indigo.css`, `dark/indigo.css` |
For the full live reference (palette families, design system schemas, variant constraints, and preset palettes) call:
```
read_resource({ uri: "theming://platforms/webcomponents" })
```
Additional guidance resources:
- `read_resource({ uri: "theming://guidance/colors/roles" })` — which components use primary vs secondary vs surface, and which shade (50/500/900) to use where
- `read_resource({ uri: "theming://guidance/colors/rules" })` — surface and gray luminance rules for light/dark variants (why gray is inverted from surface, WCAG contrast thresholds)
## Pre-built Themes
The quickest way to theme an app is to import a pre-built CSS file in your entry point:
```typescript
import 'igniteui-webcomponents/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 |
## Custom Theme via CSS Custom Properties
> No Sass required. Works in any project after importing a pre-built theme.
After importing a pre-built theme, override the `*-500` base shade to change a color family. All other shades (50–900) derive from the 500 value automatically via CSS relative color syntax:
```css
:root {
/* Override the 500 (base) shade — all other shades update automatically */
--ig-primary-500: #1976D2;
--ig-secondary-500: #FF9800;
}
```
To scope overrides to a specific container:
```css
.admin-panel {
--ig-primary-500: #6200EA;
}
```
For dark mode, either import a dark theme CSS file directly or toggle overrides with a class or media query:
```css
@media (prefers-color-scheme: dark) {
:root {
--ig-surface-500: #121212;
--ig-primary-500: #90CAF9; /* lighter tint works better on dark backgrounds */
}
}
/* Or manually with a class */
.dark-theme {
--ig-surface-500: #222;
}
```
## Custom Theme via Sass
> Requires Sass configured in the project. First check whether the project has a Sass setup (e.g., a `styles.scss` entry file, `sass` in `devDependencies`, or a Vite/webpack Sass plugin).
The Sass API for `igniteui-webcomponents` uses `@use 'igniteui-theming'` with individual mixins — **not** the Angular-specific `core()` / `theme()` combined mixins.
Call `create_theme` to generate production-ready Sass for palette + typography + elevations in a single step:
```
create_theme({
platform: "webcomponents",
designSystem: "material", // or "bootstrap", "fluent", "indigo"
primaryColor: "#1976D2",
secondaryColor: "#FF9800",
surfaceColor: "#FAFAFA",
variant: "light",
fontFamily: "'Roboto', sans-serif",
includeTypography: true,
includeElevations: true
})
```
For a dark theme pass a dark `surfaceColor` (e.g. `"#121212"`) and `variant: "dark"` — `create_theme` selects the correct dark schema automatically.
For palette-only generation (when typography/elevations are already set) use `create_palette`. For scoping a theme to a container, pass the generated `@include palette(...)` block inside the target selector.
## Component-Level Theming
Override individual component appearance using component theme functions and the `tokens` mixin.
> **AGENT INSTRUCTION — No Hardcoded Colors (CRITICAL)**
>
> Once a palette has been generated (via `palette()` in Sass or `create_palette` / `create_theme` via MCP),
> **every color reference MUST come from the generated palette tokens** — never hardcode hex/RGB/HSL values.
>
> Use `var(--ig-primary-500)`, `var(--ig-secondary-300)`, `var(--ig-surface-500)`, etc. in CSS,
> or the `get_color` MCP tool to obtain the correct token reference.
>
> **WRONG** (hardcoded hex — breaks theme switching, ignores the palette):
> ```css
> igc-avatar {
> --ig-avatar-background: #E91E63; /* ✗ hardcoded */
> --ig-avatar-color: #FFFFFF; /* ✗ hardcoded */
> }
> ```
>
> **RIGHT — CSS** (palette token — stays in sync with the theme):
> ```css
> igc-avatar {
> --ig-avatar-background: var(--ig-primary-500);
> --ig-avatar-color: var(--ig-primary-500-contrast);
> }
> ```
>
> **RIGHT — Sass** (when Sass is configured):
> ```scss
> $custom-avatar: avatar-theme(
> $schema: $light-material-schema,
> $background: var(--ig-primary-500),
> $color: var(--ig-primary-500-contrast)
> );
> ```
>
> This applies to **all** style code: component themes, custom CSS rules, and inline styles.
> The only place raw hex values belong is the **initial `palette()` call** that seeds the color system.
> Everything downstream must reference the palette.
```css
igc-avatar {
--ig-avatar-background: var(--ig-primary-500);
--ig-avatar-color: var(--ig-primary-500-contrast);
}
```
When Sass is configured, use `create_component_theme` to generate the correct `avatar-theme(...)` + `@include tokens(...)` block:
```
create_component_theme({
platform: "webcomponents",
component: "avatar",
tokens: { "background": "var(--ig-primary-500)", "color": "var(--ig-primary-500-contrast)" }
})
```
Pass `output: "css"` if you want CSS custom properties instead of Sass.
### Discovering Available Tokens
Each component has its own set of design tokens (themeable CSS custom properties). Before theming a component, you must know which tokens exist. Use the **MCP tool** `get_component_design_tokens` to discover them.
### Compound Components
Some components (e.g., `combo`, `grid`, `date-picker`, `select`) are **compound** — they contain internal child components, each requiring their own theme. For example, `date-picker` uses `calendar`, `flat-button`, and `input-group` internally.
Workflow for compound components:
1. Call `get_component_design_tokens` for the parent (e.g., `date-picker`)
2. The response lists related themes and scope selectors
3. Call `create_component_theme` for each child, using the parent's selector as the wrapper
## Layout Controls
Use the MCP layout tools to generate the correct CSS or Sass output:
```
set_size({ size: "medium" }) // global, CSS
set_size({ size: "small", component: "grid" }) // component-scoped, CSS
set_size({ size: "medium", output: "sass" }) // Sass output
set_spacing({ spacing: 0.75 }) // compact, global
set_spacing({ spacing: 0.75, component: "grid" }) // component-scoped
set_roundness({ radiusFactor: 0.5 }) // global
set_roundness({ radiusFactor: 0.0 }) // square
```
All three tools default to CSS output. Add `output: "sass"` when the project has Sass configured.
The underlying CSS custom properties are `--ig-size`, `--ig-spacing`, and `--ig-radius-factor`. You can also set them directly on `:root` or a scoped selector if a one-off override is simpler than a tool call.
## Using the Theming MCP Server
The Ignite UI Theming MCP server provides tools for AI-assisted theme code generation.
> **IMPORTANT — File Safety Rule**: When generating or updating theme code, **never overwrite existing style files directly**. Instead, always **propose the changes as an update** and let the user review and approve before writing to disk. If a `styles.scss` (or any target file) already exists, show the generated code as a diff or suggestion rather than replacing the file contents. This prevents accidental loss of custom styles the user has already written.
Quick tool sequence — for full parameter details, see earlier sections:
| Step | Tool | Purpose |
|---|---|---|
| 1 | `detect_platform` | Always first — auto-detects platform from `package.json` |
| 2 | `create_theme` | Full Sass theme: palette + typography + elevations in one call |
| 3 | `get_component_design_tokens` | Discover valid token names before calling `create_component_theme` |
| 4 | `create_component_theme` | Scoped component override — all token values must use `var(--ig-*)` |
| 5 | `create_palette` | Palette only, when a full Sass theme is not needed |
| 6 | `set_size` / `set_spacing` / `set_roundness` | Layout controls — add `output: "sass"` for Sass output |
| 7 | `get_color` | Resolve color intent to `var(--ig-<family>-<shade>)` token reference |
### Loading Reference Data
Use `read_resource` with these URIs for preset values and documentation:
| URI | Content |
|---|---|
| `theming://presets/palettes` | Preset palette colors |
| `theming://presets/typography` | Typography presets |
| `theming://presets/elevations` | Elevation shadow presets |
| `theming://guidance/colors/usage` | Which shades for which purpose |
| `theming://guidance/colors/roles` | Semantic color roles |
| `theming://guidance/colors/rules` | Light/dark theme rules |
| `theming://platforms/webcomponents` | Web Components platform specifics |
| `theming://platforms` | All supported platforms |
## Referencing Colors in Custom Styles
After a theme is applied, the palette is available as CSS custom properties on `:root`. Use these tokens in all custom CSS — never introduce standalone hex/RGB variables for colors that the palette already provides.
### Correct: Palette Tokens
```css
/* All colors come from the theme — respects palette changes and dark/light switching */
.sidebar {
background: var(--ig-surface-500);
color: var(--ig-gray-900);
border-right: 1px solid var(--ig-gray-200);
}
.accent-badge {
background: var(--ig-secondary-500);
color: var(--ig-secondary-500-contrast);
}
.hero-section {
/* Semi-transparent primary overlay */
background: hsl(from var(--ig-primary-500) h s l / 0.12);
}
```
### Incorrect: Hardcoded Values
```css
/* WRONG — these break when the palette changes and ignore dark/light mode */
.sidebar {
background: #F0F5FA; /* ✗ not a palette token */
color: #333; /* ✗ not a palette token */
}
```
### When Raw Hex Values Are OK
Raw hex values are acceptable **only** in these contexts:
1. **`palette()` call** — the initial seed colors that generate the full palette
2. **`create_palette` / `create_theme` MCP tool inputs** — the base colors passed to the tool
عرض على GitHub