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(origniteui-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 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 whereread_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:
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:
: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:
.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:
@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.scssentry file,sassindevDependencies, 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 orcreate_palette/create_themevia 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 theget_colorMCP tool to obtain the correct token reference.WRONG (hardcoded hex — breaks theme switching, ignores the palette):
igc-avatar { --ig-avatar-background: #E91E63; /* ✗ hardcoded */ --ig-avatar-color: #FFFFFF; /* ✗ hardcoded */ }RIGHT — CSS (palette token — stays in sync with the theme):
igc-avatar { --ig-avatar-background: var(--ig-primary-500); --ig-avatar-color: var(--ig-primary-500-contrast); }RIGHT — Sass (when Sass is configured):
$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.
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:
- Call
get_component_design_tokensfor the parent (e.g.,date-picker) - The response lists related themes and scope selectors
- Call
create_component_themefor 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
/* 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
/* 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:
palette()call — the initial seed colors that generate the full palettecreate_palette/create_themeMCP tool inputs — the base colors passed to the tool- Non-palette decorative values — e.g., a one-off SVG illustration color that intentionally stays fixed regardless of theme
Everything else must use var(--ig-<family>-<shade>) tokens.
Common Patterns
Switching Between Light and Dark Themes — CSS approach
Import the appropriate theme CSS and toggle with a class or media query:
// In your entry point — choose one variant as the default
import 'igniteui-webcomponents/themes/light/bootstrap.css';
/* Override surface base color for dark mode */
.dark-theme {
--ig-surface-500: #121212;
}
@media (prefers-color-scheme: dark) {
:root {
--ig-surface-500: #121212;
--ig-primary-500: #90CAF9; /* lighter tint works better on dark backgrounds */
}
}
Or dynamically swap the stylesheet at runtime:
function setTheme(variant: 'light' | 'dark', design = 'bootstrap') {
const link = document.getElementById('igc-theme') as HTMLLinkElement;
link.href = `node_modules/igniteui-webcomponents/themes/${variant}/${design}.css`;
}
Switching Between Light and Dark Themes — Sass approach
When Sass is configured, generate both theme blocks with create_theme — once with variant: "light" and once with variant: "dark". Use the generated @include palette(...) call inside .dark-theme { } for the dark variant. The tool selects the correct schema automatically for each variant.
Scoping a Theme to a Container — CSS approach
.admin-panel {
--ig-primary-500: #6200EA;
}
Scoping a Theme to a Container — Sass approach
Generate the palette block with create_palette and wrap it in the target container selector manually, or pass a custom selector when using create_component_theme for component-scoped overrides.
Key Rules
- Never overwrite existing files directly — always propose theme code as an update for user review; do not replace existing style files without confirmation
- Always call
detect_platformfirst when using MCP tools - Always call
get_component_design_tokensbeforecreate_component_themeto discover valid token names - Palette shades 50 = lightest, 900 = darkest for all chromatic colors — never invert for dark themes (only gray inverts)
- Surface color must match the variant — light color for
light, dark color fordark - Sass only: Use
create_theme(orcreate_palette/create_typography/create_elevationsindividually) to generate correct Sass — the theming module for Web Components isigniteui-theming, notigniteui-angular/theming; Angular-specificcore()/theme()combined mixins do not apply here - Sass only: Component themes use
create_component_themeto generate@include tokens($theme)inside the correct selector - For compound components, follow the full checklist returned by
get_component_design_tokens— theme each child component with its scoped selector - Never hardcode colors after palette generation — once a palette is created, every color in component themes, custom CSS, and Sass variables must use
var(--ig-<family>-<shade>)palette tokens (e.g.,var(--ig-primary-500),var(--ig-gray-200)). Raw hex/RGB/HSL values are only acceptable in the initialpalette()seed call. This ensures themes remain consistent, switchable (light/dark), and maintainable