@igniteui/angular-templates 21.1.14100-alpha.2 → 21.1.14100-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/SKILL.md +68 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/charts.md +457 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/data-display.md +360 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/directives.md +272 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/feedback.md +149 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/form-controls.md +313 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/layout-manager.md +420 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/layout.md +225 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-components/references/setup.md +166 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/SKILL.md +110 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/references/data-operations.md +445 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/references/editing.md +491 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/references/features.md +234 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/references/paging-remote.md +397 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/references/state.md +314 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/references/structure.md +299 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-grids/references/types.md +507 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-theming/SKILL.md +439 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-theming/references/common-patterns.md +45 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-theming/references/contributing.md +471 -0
- package/igx-ts/projects/_base/files/__dot__claude/skills/igniteui-angular-theming/references/mcp-setup.md +77 -0
- package/igx-ts/projects/_base/files/__dot__vscode/mcp.json +2 -2
- package/package.json +2 -2
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
# Contributing to Component Themes and SCSS
|
|
2
|
+
|
|
3
|
+
This reference covers how to contribute to the **in-repo Sass theming source** of Ignite UI for Angular.
|
|
4
|
+
|
|
5
|
+
> **Scope boundary**: This guide covers the files inside
|
|
6
|
+
> `projects/igniteui-angular/core/src/core/styles/`. Schema files (the
|
|
7
|
+
> `$light-avatar`, `$dark-avatar`, etc. Sass maps) live in the separate
|
|
8
|
+
> `igniteui-theming` npm package and are **not modified here**. If a new
|
|
9
|
+
> design token needs to be added to a schema, that work happens in the
|
|
10
|
+
> `igniteui-theming` repository and is consumed here as a package update.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Architecture at a Glance
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
projects/igniteui-angular/core/src/core/styles/
|
|
18
|
+
base/ ← shared functions, mixins, component registry
|
|
19
|
+
components/ ← per-component theme + structural SCSS (55 dirs)
|
|
20
|
+
_index.scss ← @forward barrel for all *-theme files
|
|
21
|
+
<component>/
|
|
22
|
+
_<name>-theme.scss ← theme mixin: emits CSS custom props + placeholders
|
|
23
|
+
_<name>-component.scss ← structural mixin: BEM selectors + @extend placeholders
|
|
24
|
+
themes/
|
|
25
|
+
_core.scss ← core() mixin: @use + @include every *-component mixin
|
|
26
|
+
generators/
|
|
27
|
+
_base.scss ← theme() mixin: calls every *-theme() function (defines the material theme)
|
|
28
|
+
_bootstrap.scss ← bootstrap-light-theme() / bootstrap-dark-theme()
|
|
29
|
+
_fluent.scss ← fluent-light-theme() / fluent-dark-theme()
|
|
30
|
+
_indigo.scss ← indigo-light-theme() / indigo-dark-theme()
|
|
31
|
+
presets/ ← compilable entry-point SCSS files (one per variant)
|
|
32
|
+
spec/ ← sass-true unit tests
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The `base/_index.scss` re-exports everything from `igniteui-theming/sass/` that
|
|
36
|
+
component files need (`tokens`, `var-get`, `sizable`, `rem`, BEM mixins, etc.),
|
|
37
|
+
so every component file only needs one import:
|
|
38
|
+
|
|
39
|
+
```scss
|
|
40
|
+
@use '../../base' as *;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## The Two-File Pattern
|
|
46
|
+
|
|
47
|
+
Every component has exactly two SCSS files. **Never merge them.**
|
|
48
|
+
|
|
49
|
+
| File | Mixin name | Responsibility |
|
|
50
|
+
| ------------------------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
51
|
+
| `_<name>-theme.scss` | `@mixin <name>($theme)` | Calls `tokens($theme, $mode: 'scoped')`, reads `$variant`, defines `%placeholder` selectors with all visual styles |
|
|
52
|
+
| `_<name>-component.scss` | `@mixin component` | Defines BEM selectors using `b/e/m` mixins, registers the component, extends placeholders |
|
|
53
|
+
|
|
54
|
+
### Why two files?
|
|
55
|
+
|
|
56
|
+
The theme mixin is called once per palette/schema combination inside `theme()` in
|
|
57
|
+
`generators/_base.scss`. The component structural mixin is called once globally
|
|
58
|
+
inside `core()` in `themes/_core.scss`. Keeping them separate ensures structural
|
|
59
|
+
CSS is emitted only once regardless of how many theme overrides a consumer applies.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Theme File Anatomy (`_<name>-theme.scss`)
|
|
64
|
+
|
|
65
|
+
```scss
|
|
66
|
+
@use 'sass:map';
|
|
67
|
+
@use '../../base' as *;
|
|
68
|
+
// Import animation easings only if the component uses transitions
|
|
69
|
+
@use 'igniteui-theming/sass/animations/easings' as *;
|
|
70
|
+
|
|
71
|
+
/// @deprecated Use the `tokens` mixin instead.
|
|
72
|
+
/// @see {mixin} tokens
|
|
73
|
+
/// @param {Map} $theme - The theme used to style the component.
|
|
74
|
+
@mixin <name>($theme) {
|
|
75
|
+
// 1. Emit all theme tokens as CSS custom properties on the host element
|
|
76
|
+
@include tokens($theme, $mode: 'scoped');
|
|
77
|
+
|
|
78
|
+
// 2. Read variant and theme-variant for conditional styling
|
|
79
|
+
$variant: map.get($theme, '_meta', 'theme'); // 'material' | 'fluent' | 'bootstrap' | 'indigo'
|
|
80
|
+
$theme-variant: map.get($theme, '_meta', 'variant'); // 'light' | 'dark'
|
|
81
|
+
|
|
82
|
+
// 3. Define placeholder selectors — one per logical visual state or element
|
|
83
|
+
%<name>-display {
|
|
84
|
+
@include sizable();
|
|
85
|
+
--component-size: var(--ig-size, #{var-get($theme, 'default-size')});
|
|
86
|
+
|
|
87
|
+
// All colors come from var-get, never from hard-coded hex values
|
|
88
|
+
color: var-get($theme, 'color');
|
|
89
|
+
background: var-get($theme, 'background');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 4. Variant-specific overrides — only when behavior genuinely differs
|
|
93
|
+
@if $variant == 'indigo' {
|
|
94
|
+
%<name>-display {
|
|
95
|
+
// indigo-specific styles
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Key rules for theme files:**
|
|
102
|
+
|
|
103
|
+
- Call `@include tokens($theme, $mode: 'scoped')` first — always, without exception. This emits
|
|
104
|
+
all design tokens as `--ig-<name>-*` CSS custom properties.
|
|
105
|
+
- Use `var-get($theme, 'token-name')` for every color, size, and spacing value.
|
|
106
|
+
Never write hard-coded hex, RGB, HSL, or pixel values for anything that has a
|
|
107
|
+
corresponding design token.
|
|
108
|
+
- Name placeholders `%<block>` for the root, `%<block>__<element>` for
|
|
109
|
+
elements, and `%<block>--<modifier>` for modifiers.
|
|
110
|
+
- Use `@if $variant == '<name>'` only when the design genuinely differs across
|
|
111
|
+
design systems. Prefer token differences (handled by the schema) over
|
|
112
|
+
branching in the theme mixin.
|
|
113
|
+
- Read both `$variant` (design system name) and `$theme-variant` (light/dark)
|
|
114
|
+
— use the one appropriate to your condition.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Component File Anatomy (`_<name>-component.scss`)
|
|
119
|
+
|
|
120
|
+
```scss
|
|
121
|
+
@use '../../base' as *;
|
|
122
|
+
@use 'sass:string';
|
|
123
|
+
|
|
124
|
+
/// @access private
|
|
125
|
+
@mixin component {
|
|
126
|
+
@include b(igx-<name>) {
|
|
127
|
+
// Register this component in the global component registry.
|
|
128
|
+
// Use bem--selector-to-string(&) to extract the block name.
|
|
129
|
+
$this: bem--selector-to-string(&);
|
|
130
|
+
@include register-component(
|
|
131
|
+
$name: string.slice($this, 2, -1),
|
|
132
|
+
$deps: (
|
|
133
|
+
igx-icon,
|
|
134
|
+
// list every component this one visually depends on
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Extend the root placeholder from the theme file
|
|
139
|
+
@extend %<name>-display !optional;
|
|
140
|
+
|
|
141
|
+
// Elements
|
|
142
|
+
@include e(suffix) {
|
|
143
|
+
@extend %<name>__suffix !optional;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Modifiers (boolean)
|
|
147
|
+
@include m(disabled) {
|
|
148
|
+
@extend %<name>--disabled !optional;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Element with modifier (combined)
|
|
152
|
+
@include e(label, $m: 'focused') {
|
|
153
|
+
@extend %<name>__label--focused !optional;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Key rules for component files:**
|
|
160
|
+
|
|
161
|
+
- Always call `register-component` inside the root `b()` block with the
|
|
162
|
+
component's BEM block name as `$name`. The `$deps` list must include every
|
|
163
|
+
other Ignite UI component whose theme this component visually relies on (e.g.,
|
|
164
|
+
if the component renders `igx-icon` internally, list `igx-icon`).
|
|
165
|
+
- Use `!optional` on every `@extend`. Theme mixin placeholders are only defined
|
|
166
|
+
when a theme is applied; without `!optional`, Sass errors in partial builds.
|
|
167
|
+
- Never put visual styles (colors, fonts, sizes, box shadows) in the component
|
|
168
|
+
file. Structural layout (`display`, `position`, `width`, `flex`) that is truly
|
|
169
|
+
independent of the theme belongs here; everything else belongs in the theme file.
|
|
170
|
+
- Do not import `igniteui-theming` modules directly — all BEM mixins and
|
|
171
|
+
utilities come through `../../base`.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## BEM Naming Convention
|
|
176
|
+
|
|
177
|
+
CSS classes follow BEM Two Dashes style. See
|
|
178
|
+
[`css-naming-convention.md`](../../../../css-naming-convention.md) for the full
|
|
179
|
+
spec. Quick reference:
|
|
180
|
+
|
|
181
|
+
| BEM entity | Pattern | Example |
|
|
182
|
+
| ------------------ | ----------------------------------- | -------------------------- |
|
|
183
|
+
| Block | `igx-<name>` | `igx-avatar` |
|
|
184
|
+
| Element | `igx-<name>__<element>` | `igx-avatar__image` |
|
|
185
|
+
| Modifier | `igx-<name>--<modifier>` | `igx-avatar--circle` |
|
|
186
|
+
| Element + modifier | `igx-<name>__<element>--<modifier>` | `igx-avatar__item--selected` |
|
|
187
|
+
|
|
188
|
+
BEM mixin usage in component files:
|
|
189
|
+
|
|
190
|
+
```scss
|
|
191
|
+
@include b(igx-avatar) { ... } // → .igx-avatar
|
|
192
|
+
@include e(image) { ... } // → .igx-avatar__image
|
|
193
|
+
@include m(circle) { ... } // → .igx-avatar--circle
|
|
194
|
+
@include e(item, $m: 'selected') { ... } // → .igx-avatar__item--selected
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Placeholder names must resemble the BEM selectors they represent(if present):
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
%avatar-display ← root display placeholder (named -display, not bare block)
|
|
201
|
+
%avatar__image ← element placeholder
|
|
202
|
+
%avatar--circle ← modifier placeholder
|
|
203
|
+
%avatar__item--selected ← element+modifier placeholder
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Registration: Where New Components Must Be Wired
|
|
209
|
+
|
|
210
|
+
Adding a new component requires changes in **three** files beyond the two new SCSS files themselves:
|
|
211
|
+
|
|
212
|
+
### 1. `components/_index.scss` — expose the theme mixin
|
|
213
|
+
|
|
214
|
+
```scss
|
|
215
|
+
// Add alphabetically:
|
|
216
|
+
@forward '<name>/<name>-theme';
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 2. `themes/_core.scss` — emit structural CSS
|
|
220
|
+
|
|
221
|
+
```scss
|
|
222
|
+
// At the top, @use the component file:
|
|
223
|
+
@use '../components/<name>/<name>-component' as <name>;
|
|
224
|
+
|
|
225
|
+
// Inside the core() mixin body, call it:
|
|
226
|
+
@include <name>.component();
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### 3. `themes/generators/_base.scss` — wire the theme into the global theme
|
|
230
|
+
|
|
231
|
+
Inside the `theme-internal` mixin body, follow the existing pattern:
|
|
232
|
+
|
|
233
|
+
```scss
|
|
234
|
+
@if is-used('igx-<name>', $exclude) {
|
|
235
|
+
$<name>-theme-map: <name>-theme(
|
|
236
|
+
$schema: $schema,
|
|
237
|
+
);
|
|
238
|
+
$<name>-theme-map: meta.call($theme-handler, $<name>-theme-map);
|
|
239
|
+
@include <name>($<name>-theme-map);
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Also add the same block to each of the variant-specific generator files
|
|
244
|
+
(`_bootstrap.scss`, `_fluent.scss`, `_indigo.scss`) if the component has
|
|
245
|
+
variant-specific theme overrides.
|
|
246
|
+
|
|
247
|
+
> **Order matters**: Add the new `@if is-used(...)` block in the same relative
|
|
248
|
+
> position as the corresponding `@include <name>.component()` call in `_core.scss`.
|
|
249
|
+
> The two files should stay in the same component order for maintainability.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Adding a New Visual State to an Existing Component
|
|
254
|
+
|
|
255
|
+
When a feature adds a new modifier, element, or interaction state:
|
|
256
|
+
|
|
257
|
+
**1. In `_<name>-theme.scss`** — add a new placeholder:
|
|
258
|
+
|
|
259
|
+
```scss
|
|
260
|
+
%<name>--<new-modifier> {
|
|
261
|
+
background: var-get($theme, '<new-token>');
|
|
262
|
+
color: var-get($theme, '<new-token>-contrast');
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
If the new state requires a new design token, that token must be added to the
|
|
267
|
+
schema in the `igniteui-theming` package first, then consumed here via
|
|
268
|
+
`var-get($theme, '<new-token>')`. DO NOT introduce a hard-coded fallback value
|
|
269
|
+
for a token that should be schema-driven.
|
|
270
|
+
|
|
271
|
+
**2. In `_<name>-component.scss`** — add the corresponding BEM structure and
|
|
272
|
+
extend the new placeholder:
|
|
273
|
+
|
|
274
|
+
```scss
|
|
275
|
+
@include m(<new-modifier>) {
|
|
276
|
+
@extend %<name>--<new-modifier> !optional;
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Variant Branching: When and How
|
|
283
|
+
|
|
284
|
+
Use `@if $variant == '...'` only when the structural or behavioral difference
|
|
285
|
+
cannot be expressed through design tokens alone.
|
|
286
|
+
|
|
287
|
+
```scss
|
|
288
|
+
// Read both axes if needed
|
|
289
|
+
$variant: map.get($theme, '_meta', 'theme'); // design system name
|
|
290
|
+
$theme-variant: map.get($theme, '_meta', 'variant'); // 'light' | 'dark'
|
|
291
|
+
|
|
292
|
+
// Pixel values that differ per design system — acceptable branching
|
|
293
|
+
$chip-padding: (
|
|
294
|
+
comfortable: rem(if($variant != 'indigo', 12px, 7px)),
|
|
295
|
+
cosy: rem(if($variant != 'indigo', 6px, 5px)),
|
|
296
|
+
compact: rem(if($variant != 'indigo', 2px, 3px)),
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
// Property that is absent in some variants — acceptable
|
|
300
|
+
$box-shadow-focus: map.get(
|
|
301
|
+
(
|
|
302
|
+
'material': null,
|
|
303
|
+
'fluent': null,
|
|
304
|
+
'bootstrap': 0 0 0 rem(4px) var-get($theme, 'focus-outline-color'),
|
|
305
|
+
'indigo': 0 0 0 rem(3px) var-get($theme, 'focus-outline-color'),
|
|
306
|
+
),
|
|
307
|
+
$variant
|
|
308
|
+
);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Use a Sass map keyed by variant name when the value differs for all four systems.
|
|
312
|
+
Use `if($variant != 'indigo', ...)` for simple binary differences.
|
|
313
|
+
|
|
314
|
+
Never branch on `$theme-variant` to change structural layout — light/dark
|
|
315
|
+
differences must be expressed entirely through token values in the schema.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## `var-get` vs CSS `var()`
|
|
320
|
+
|
|
321
|
+
| Situation | Use |
|
|
322
|
+
| -------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
323
|
+
| Consuming a token from the current component's theme | `var-get($theme, 'token-name')` |
|
|
324
|
+
| Consuming a global layout token (not component-specific) | `var(--ig-size)`, `var(--ig-spacing)`, `var(--ig-radius-factor)` |
|
|
325
|
+
| Consuming a palette color directly in custom CSS | `var(--ig-primary-500)`, `var(--ig-gray-200)` |
|
|
326
|
+
|
|
327
|
+
`var-get($theme, 'token-name')` resolves to `var(--ig-<component>-token-name)`
|
|
328
|
+
with appropriate fallback chaining. It must only be used inside a theme mixin
|
|
329
|
+
where `$theme` is in scope.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Style Linting and Tests
|
|
334
|
+
|
|
335
|
+
### Linting
|
|
336
|
+
|
|
337
|
+
When touching only SCSS files, run the style linter first:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
npm run lint:styles
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Run the full linter before finishing to catch any TypeScript/template issues
|
|
344
|
+
introduced alongside the style changes:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
npm run lint:lib
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Style Unit Tests
|
|
351
|
+
|
|
352
|
+
SCSS functions and mixins in `base/` have unit tests using
|
|
353
|
+
[sass-true](https://www.oddbird.net/true/). Tests live in:
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
projects/igniteui-angular/core/src/core/styles/spec/
|
|
357
|
+
_index.scss ← barrel: @use the spec files
|
|
358
|
+
_functions.spec.scss ← tests for functions (is-used, is-component, list-diff)
|
|
359
|
+
_mixins.spec.scss ← tests for mixins (register-component, gen-color-class)
|
|
360
|
+
tests.mjs ← Jasmine runner (do not modify)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Run style tests:
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
npm run test:styles
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**When to add a style test:**
|
|
370
|
+
|
|
371
|
+
- You add a new Sass function to `base/_functions.scss`
|
|
372
|
+
- You add a new utility mixin to `base/_mixins.scss`
|
|
373
|
+
- You modify the component registry logic in `register-component` or `is-used`
|
|
374
|
+
|
|
375
|
+
You do **not** need to write style tests for new component theme or component
|
|
376
|
+
structural mixins — those are covered by visual/Karma tests on the Angular
|
|
377
|
+
component side.
|
|
378
|
+
|
|
379
|
+
**Test structure** (sass-true):
|
|
380
|
+
|
|
381
|
+
```scss
|
|
382
|
+
@use 'sass-true' as *;
|
|
383
|
+
@use '../base' as *;
|
|
384
|
+
|
|
385
|
+
@include describe('My Mixin') {
|
|
386
|
+
@include it('should do X') {
|
|
387
|
+
@include assert() {
|
|
388
|
+
@include output() {
|
|
389
|
+
@include my-mixin(args);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
@include expect() {
|
|
393
|
+
// expected CSS output
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## Presets: Compilable Theme Entry Points
|
|
403
|
+
|
|
404
|
+
The `themes/presets/` directory contains one SCSS file per design-system/variant
|
|
405
|
+
combination. Each file is compiled to a standalone CSS file by the build script.
|
|
406
|
+
|
|
407
|
+
If you add a new design system variant (rare, if ever), add a preset file following this
|
|
408
|
+
structure:
|
|
409
|
+
|
|
410
|
+
```scss
|
|
411
|
+
@use '../../themes' as *;
|
|
412
|
+
@include core();
|
|
413
|
+
@include typography($font-family: $<variant>-typeface, $type-scale: $<variant>-type-scale);
|
|
414
|
+
@include theme($schema: $<light|dark>-<variant>-schema, $palette: $<light|dark>-<variant>-palette);
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Compile with:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
npm run build:lib
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
The build script at `scripts/build-styles.mjs` compiles all presets and copies
|
|
424
|
+
the raw SCSS source tree to `dist/igniteui-angular/lib/core/styles/`.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## `igniteui-theming` Package: What Lives There
|
|
429
|
+
|
|
430
|
+
The following are **not** in this repository. They live in the `igniteui-theming`
|
|
431
|
+
package and are consumed as a versioned npm dependency:
|
|
432
|
+
|
|
433
|
+
| Area | What it provides |
|
|
434
|
+
| ------------------------- | -------------------------------------------------------------------- |
|
|
435
|
+
| `sass/bem/` | `b()`, `e()`, `m()`, `mx()`, `bem--selector-to-string()` mixins |
|
|
436
|
+
| `sass/color/` | `palette()`, `color()` functions, palette presets |
|
|
437
|
+
| `sass/elevations/` | `elevations()` mixin, elevation presets |
|
|
438
|
+
| `sass/themes/schemas/` | `$light-avatar`, `$dark-avatar`, etc. — per-component token maps |
|
|
439
|
+
| `sass/themes/components/` | `avatar-theme()`, `button-theme()`, etc. — component theme functions |
|
|
440
|
+
| `sass/utils/` | `tokens()`, `var-get()`, `sizable()`, `rem()`, `pad()` |
|
|
441
|
+
| `sass/typography/` | `type-style()`, `typography()` mixin, type scale presets |
|
|
442
|
+
| `sass/animations/` | Easing variables (`$ease-in-out-quad`, etc.) |
|
|
443
|
+
|
|
444
|
+
When a component's visual change requires a **new design token** (new color,
|
|
445
|
+
new size dimension, new border radius), the token must be added to the
|
|
446
|
+
relevant schema in `igniteui-theming` first and released as a package update.
|
|
447
|
+
Only then can it be consumed here via `var-get($theme, 'new-token')`.
|
|
448
|
+
|
|
449
|
+
If a task calls for adding a new token without a corresponding `igniteui-theming` update available,
|
|
450
|
+
flag this dependency clearly rather than introducing a hard-coded value as a stopgap.
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Quick Checklist: New Component Theme
|
|
455
|
+
|
|
456
|
+
- [ ] `_<name>-theme.scss` created with `@mixin <name>($theme)`, calls `tokens($theme)`, defines all placeholders using `var-get`
|
|
457
|
+
- [ ] `_<name>-component.scss` created with `@mixin component`, calls `register-component` inside the root `b()` block, extends all placeholders with `!optional`
|
|
458
|
+
- [ ] `components/_index.scss` — `@forward '<name>/<name>-theme'` added
|
|
459
|
+
- [ ] `themes/_core.scss` — `@use` added at top, `@include <name>.component()` added in mixin body
|
|
460
|
+
- [ ] `themes/generators/_base.scss` — `@if is-used('igx-<name>', $exclude)` block added
|
|
461
|
+
- [ ] BEM class names follow the Two Dashes convention (`css-naming-convention.md`), covered by the appropriate `b()`, `e()`, and `m()` mixins
|
|
462
|
+
- [ ] No hardcoded hex/RGB/HSL values — all colors come from `var-get($theme, '...')`
|
|
463
|
+
- [ ] `npm run lint:styles` passes
|
|
464
|
+
- [ ] `npm run test:styles` passes (if base functions/mixins were modified)
|
|
465
|
+
|
|
466
|
+
## Quick Checklist: New Visual State on Existing Component
|
|
467
|
+
|
|
468
|
+
- [ ] New placeholder added to `_<name>-theme.scss` using `var-get` for all token references
|
|
469
|
+
- [ ] New `@include m(...)` or `@include e(...)` block added to `_<name>-component.scss` extending the new placeholder with `!optional`
|
|
470
|
+
- [ ] If a new design token is needed, flagged that `igniteui-theming` package must be updated first
|
|
471
|
+
- [ ] `npm run lint:styles` passes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Setting Up the Theming MCP Server
|
|
2
|
+
|
|
3
|
+
> **Part of the [`igniteui-angular-theming`](../SKILL.md) skill hub.**
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [VS Code](#vs-code)
|
|
8
|
+
- [Cursor](#cursor)
|
|
9
|
+
- [Claude Desktop](#claude-desktop)
|
|
10
|
+
- [WebStorm / JetBrains IDEs](#webstorm--jetbrains-ides)
|
|
11
|
+
- [Verifying the Setup](#verifying-the-setup)
|
|
12
|
+
|
|
13
|
+
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.
|
|
14
|
+
|
|
15
|
+
## VS Code
|
|
16
|
+
|
|
17
|
+
Create or edit `.vscode/mcp.json` in your project:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"servers": {
|
|
22
|
+
"igniteui-theming": {
|
|
23
|
+
"command": "npx",
|
|
24
|
+
"args": ["-y", "igniteui-theming", "igniteui-theming-mcp"]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This works whether `igniteui-theming` is installed locally in `node_modules` or needs to be pulled from the npm registry — `npx -y` handles both cases.
|
|
31
|
+
|
|
32
|
+
## Cursor
|
|
33
|
+
|
|
34
|
+
Create or edit `.cursor/mcp.json`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"igniteui-theming": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-y", "igniteui-theming", "igniteui-theming-mcp"]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Claude Desktop
|
|
48
|
+
|
|
49
|
+
Edit the Claude Desktop config file:
|
|
50
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
51
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"mcpServers": {
|
|
56
|
+
"igniteui-theming": {
|
|
57
|
+
"command": "npx",
|
|
58
|
+
"args": ["-y", "igniteui-theming", "igniteui-theming-mcp"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## WebStorm / JetBrains IDEs
|
|
65
|
+
|
|
66
|
+
1. Go to **Settings → Tools → AI Assistant → MCP Servers**
|
|
67
|
+
2. Click **+ Add MCP Server**
|
|
68
|
+
3. Set Command to `npx` and Arguments to `igniteui-theming igniteui-theming-mcp`
|
|
69
|
+
4. Click OK and restart the AI Assistant
|
|
70
|
+
|
|
71
|
+
## Verifying the Setup
|
|
72
|
+
|
|
73
|
+
After configuring the MCP server, ask your AI assistant:
|
|
74
|
+
|
|
75
|
+
> "Detect which Ignite UI platform my project uses"
|
|
76
|
+
|
|
77
|
+
If the MCP server is running, the `detect_platform` tool will analyze your `package.json` and return the detected platform (e.g., `angular`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@igniteui/angular-templates",
|
|
3
|
-
"version": "21.1.14100-alpha.
|
|
3
|
+
"version": "21.1.14100-alpha.4",
|
|
4
4
|
"description": "Templates for Ignite UI for Angular projects and components",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"author": "Infragistics",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@igniteui/cli-core": "^14.10.0-alpha.
|
|
15
|
+
"@igniteui/cli-core": "^14.10.0-alpha.4",
|
|
16
16
|
"typescript": "~5.5.4"
|
|
17
17
|
}
|
|
18
18
|
}
|