@siemens-iris/iris-core@0.10.0 (marketing foundation) vs
@siemens/ix@5.2.0 (product foundation) — structural analysis of token systems,
theme switching, and component theming.
| Aspect | iris-core @0.10.0 | @siemens/ix @5.2.0 |
|---|---|---|
| Token prefix | --iris-* |
--theme-* |
| Token tiers | 2 tiers: primitives → semantic → components bind semantic directly | 3 tiers: primitives → semantic → component tokens → components |
| Semantic token count | 663 --iris-* (× 5 scopes = 3,376 declarations) |
~240 --theme-* per theme (× 2 schemas) |
| Component-level tokens | 1 (--iris-action-content-color) |
25 --theme-color-component-* + 41 SCSS modules |
| Theme switch mechanism | Single CSS class: .iris-ui-theme-{light,dark,sand,wireframe} |
Two HTML attributes: [data-ix-theme=family][data-ix-color-schema=dark|light] |
| Theme dimensionality | 1D — four named modes (flat list) | 2D — family × schema (orthogonal, extensible) |
| Component theming surface | Scattered — components bind ~40 semantic tokens directly; override surface = hunt for the right token | Explicit — component tokens form the documented API; override one --theme-btn-* prop |
| State handling | Hardcoded in each component's CSS (:hover { background: var(--iris-action-fill-1-hover) }) |
State modifiers as tokens: --theme-btn-primary--background--hover |
| Per-component SCSS export | None — scss/ has only token layers + 1 mixin |
41 modules at scss/theme/core/components/*.scss |
| Component CSS distribution | Shadow-only — no exported light-DOM classes | Shadow-only — but variable modules enable re-theming without class access |
| Encapsulation | Shadow DOM (Stencil) — identical model | Shadow DOM (Stencil) — identical model |
| CSS file structure | Monolithic iris.css (185 KB, no @layer) |
Per-theme files (classic-dark.css, classic-light.css) |
| Token duplication | ~5× duplication — :root + 4 mode classes repeat the full token set | 2× per family — one file per schema (dark/light), no duplication within a file |
| Typography delivery | 84 utility classes (.iris-sans-*, .iris-slab-*) always shipped |
Token-only — no utility classes shipped |
| Consumer brand theme | Override --iris-* on :root or under a mode class |
Author a new theme family emitting --theme-*; ThemeSwitcher selects it |
--iris-button-* contract.--theme-color-component-* props + 41 per-component SCSS modules declaring the mapping.--iris-<component>-* tier; components bind only those; defaults resolve from semantic.scss/ has only token layers. No scss/components/button.scss.scss/theme/core/components/ — 41 modules with @mixin setVars.scss/components/<name>/_variables.scss + _styles.scss.:hover, :active, :disabled colours are inline in each component's shadow CSS.--theme-btn-primary--background--hover.--iris-button-fill-hover defaulting from semantic.[data-ix-theme=family] × [data-ix-color-schema=dark|light].data-* attributes.iris.css emits every token × every mode in one file (5× duplication).classic-dark.css / classic-light.css — load only what's needed.@layer.iris and iX serve different contexts (marketing vs product) and will remain separate packages. The goal is structural alignment — the same architectural tiers, so that shared tooling, theme tokens, and consumer patterns work across both without learning two different models.
| Step | What | Ticket |
|---|---|---|
| 1 | Add component-token tier (--iris-<component>-* defaulting from semantic) | DESYS-434 |
| 2 | Per-component SCSS modules (scss/components/<name>/) | DESYS-1287 |
| 3 | Namespaced light-DOM class distribution (the $namespace dual-output) | DESYS-1287 |
| 4 | Layered CSS delivery (@layer, per-theme files, tree-shakeable) | DESYS-434 |
| 5 | Consider 2D theme model (data-* family × schema) | Future |