igniteui-theming 25.1.0 → 25.2.0

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.
Files changed (128) hide show
  1. package/dist/index.d.ts +75 -0
  2. package/dist/index.js +12 -0
  3. package/dist/json/components/bootstrap.json +1 -0
  4. package/dist/json/components/fluent.json +1 -0
  5. package/dist/json/components/indigo.json +1 -0
  6. package/dist/json/components/material.json +1 -0
  7. package/{json → dist/json}/components/themes.json +31 -1
  8. package/dist/mcp/generators/css.d.ts +7 -4
  9. package/dist/mcp/generators/css.js +129 -104
  10. package/dist/mcp/generators/sass.js +227 -254
  11. package/dist/mcp/index.js +259 -323
  12. package/dist/mcp/knowledge/color-usage.js +524 -502
  13. package/dist/mcp/knowledge/colors.js +61 -50
  14. package/dist/mcp/knowledge/component-metadata.js +697 -598
  15. package/dist/mcp/knowledge/component-themes.js +70 -57
  16. package/dist/mcp/knowledge/custom-palettes.js +4 -9
  17. package/dist/mcp/knowledge/docs/colors/guidance.js +4 -0
  18. package/dist/mcp/knowledge/docs/colors/usage.js +4 -0
  19. package/dist/mcp/knowledge/docs/layout/functions/border-radius.js +4 -0
  20. package/dist/mcp/knowledge/docs/layout/functions/pad.js +4 -0
  21. package/dist/mcp/knowledge/docs/layout/functions/sizable.js +4 -0
  22. package/dist/mcp/knowledge/docs/layout/mixins/sizable.js +4 -0
  23. package/dist/mcp/knowledge/docs/layout/mixins/sizing.js +4 -0
  24. package/dist/mcp/knowledge/docs/layout/mixins/spacing.js +4 -0
  25. package/dist/mcp/knowledge/docs/layout/overview.js +4 -0
  26. package/dist/mcp/knowledge/docs/setup/platform.js +4 -0
  27. package/dist/mcp/knowledge/elevations.d.ts +1 -1
  28. package/dist/mcp/knowledge/elevations.js +26 -12
  29. package/dist/mcp/knowledge/index.js +23 -87
  30. package/dist/mcp/knowledge/layout-docs.d.ts +1 -1
  31. package/dist/mcp/knowledge/multipliers.js +5 -0
  32. package/dist/mcp/knowledge/palettes.js +29 -17
  33. package/dist/mcp/knowledge/platforms/angular.js +98 -120
  34. package/dist/mcp/knowledge/platforms/blazor.js +39 -34
  35. package/dist/mcp/knowledge/platforms/common.js +83 -68
  36. package/dist/mcp/knowledge/platforms/index.js +265 -242
  37. package/dist/mcp/knowledge/platforms/react.js +43 -35
  38. package/dist/mcp/knowledge/platforms/webcomponents.js +266 -292
  39. package/dist/mcp/knowledge/sass-api.js +1 -0
  40. package/dist/mcp/knowledge/typography.js +13 -5
  41. package/dist/mcp/resources/index.js +1 -0
  42. package/dist/mcp/resources/presets.js +409 -508
  43. package/dist/mcp/theming/dist/json/colors/meta/multipliers.js +50 -0
  44. package/dist/mcp/theming/dist/json/colors/presets/palettes.js +85 -0
  45. package/dist/mcp/theming/dist/json/components/themes.js +5792 -0
  46. package/dist/mcp/theming/dist/json/elevations/indigo.js +29 -0
  47. package/dist/mcp/theming/dist/json/elevations/material.js +3 -0
  48. package/dist/mcp/theming/dist/json/typography/presets/typescales.js +621 -0
  49. package/dist/mcp/tools/descriptions.js +98 -154
  50. package/dist/mcp/tools/handlers/color.js +58 -56
  51. package/dist/mcp/tools/handlers/component-theme.js +163 -225
  52. package/dist/mcp/tools/handlers/component-tokens.js +159 -219
  53. package/dist/mcp/tools/handlers/custom-palette.js +138 -179
  54. package/dist/mcp/tools/handlers/elevations.js +27 -28
  55. package/dist/mcp/tools/handlers/index.js +11 -0
  56. package/dist/mcp/tools/handlers/layout.js +125 -176
  57. package/dist/mcp/tools/handlers/palette.js +105 -120
  58. package/dist/mcp/tools/handlers/platform.js +289 -311
  59. package/dist/mcp/tools/handlers/resource.js +22 -31
  60. package/dist/mcp/tools/handlers/theme.js +86 -103
  61. package/dist/mcp/tools/handlers/typography.js +29 -30
  62. package/dist/mcp/tools/index.js +13 -0
  63. package/dist/mcp/tools/schemas.js +239 -218
  64. package/dist/mcp/utils/color.js +277 -239
  65. package/dist/mcp/utils/preprocessing.js +57 -30
  66. package/dist/mcp/utils/result.js +43 -45
  67. package/dist/mcp/utils/sass.js +271 -191
  68. package/dist/mcp/utils/theming-resolve.d.ts +19 -0
  69. package/dist/mcp/utils/theming-resolve.js +57 -0
  70. package/dist/mcp/utils/types.js +96 -53
  71. package/dist/mcp/validators/custom-palette.js +218 -243
  72. package/dist/mcp/validators/index.js +3 -0
  73. package/dist/mcp/validators/palette.js +231 -229
  74. package/dist/tailwind/utilities/bootstrap.css +1 -0
  75. package/dist/tailwind/utilities/fluent.css +1 -0
  76. package/dist/tailwind/utilities/indigo.css +1 -0
  77. package/dist/tailwind/utilities/material.css +1 -0
  78. package/package.json +45 -64
  79. package/sass/json/README.md +12 -7
  80. package/sass/themes/_mixins.scss +1 -0
  81. package/sass/themes/components/button-group/_button-group-theme.scss +42 -0
  82. package/sass/themes/components/grid/_grid-theme.scss +1 -1
  83. package/sass/themes/schemas/components/dark/_button-group.scss +173 -50
  84. package/sass/themes/schemas/components/dark/_grid.scss +0 -16
  85. package/sass/themes/schemas/components/light/_button-group.scss +221 -99
  86. package/sass/themes/schemas/components/light/_grid.scss +14 -20
  87. package/LICENSE +0 -21
  88. package/README.md +0 -391
  89. package/dist/mcp/json/colors/presets/palettes.json.js +0 -13
  90. package/dist/mcp/json/components/themes.json.js +0 -143
  91. package/dist/mcp/json/elevations/indigo.json.js +0 -8
  92. package/dist/mcp/json/elevations/material.json.js +0 -8
  93. package/dist/mcp/json/typography/presets/typescales.json.js +0 -17
  94. package/dist/mcp/knowledge/docs/colors/guidance.md.js +0 -4
  95. package/dist/mcp/knowledge/docs/colors/usage.md.js +0 -4
  96. package/dist/mcp/knowledge/docs/layout/functions/border-radius.md.js +0 -4
  97. package/dist/mcp/knowledge/docs/layout/functions/pad.md.js +0 -4
  98. package/dist/mcp/knowledge/docs/layout/functions/sizable.md.js +0 -4
  99. package/dist/mcp/knowledge/docs/layout/mixins/sizable.md.js +0 -4
  100. package/dist/mcp/knowledge/docs/layout/mixins/sizing.md.js +0 -4
  101. package/dist/mcp/knowledge/docs/layout/mixins/spacing.md.js +0 -4
  102. package/dist/mcp/knowledge/docs/layout/overview.md.js +0 -4
  103. package/dist/mcp/knowledge/docs/setup/platform.md.js +0 -4
  104. package/dist/mcp/vite-env.d.ts +0 -18
  105. package/index.js +0 -5
  106. package/json/components/bootstrap.json +0 -1
  107. package/json/components/fluent.json +0 -1
  108. package/json/components/indigo.json +0 -1
  109. package/json/components/material.json +0 -1
  110. package/tailwind/utilities/bootstrap.css +0 -1
  111. package/tailwind/utilities/fluent.css +0 -1
  112. package/tailwind/utilities/indigo.css +0 -1
  113. package/tailwind/utilities/material.css +0 -1
  114. /package/{json → dist/json}/colors/meta/multipliers.json +0 -0
  115. /package/{json → dist/json}/colors/meta/palette.json +0 -0
  116. /package/{json → dist/json}/colors/presets/palettes.json +0 -0
  117. /package/{json → dist/json}/elevations/indigo.json +0 -0
  118. /package/{json → dist/json}/elevations/material.json +0 -0
  119. /package/{json → dist/json}/typography/presets/typescales.json +0 -0
  120. /package/{tailwind → dist/tailwind}/themes/base.css +0 -0
  121. /package/{tailwind → dist/tailwind}/themes/dark/bootstrap.css +0 -0
  122. /package/{tailwind → dist/tailwind}/themes/dark/fluent.css +0 -0
  123. /package/{tailwind → dist/tailwind}/themes/dark/indigo.css +0 -0
  124. /package/{tailwind → dist/tailwind}/themes/dark/material.css +0 -0
  125. /package/{tailwind → dist/tailwind}/themes/light/bootstrap.css +0 -0
  126. /package/{tailwind → dist/tailwind}/themes/light/fluent.css +0 -0
  127. /package/{tailwind → dist/tailwind}/themes/light/indigo.css +0 -0
  128. /package/{tailwind → dist/tailwind}/themes/light/material.css +0 -0
@@ -1,26 +1,39 @@
1
1
  import { getComponentSelector } from "../knowledge/component-metadata.js";
2
2
  import { getComponentTheme } from "../knowledge/component-themes.js";
3
- import { generateAngularThemeSass } from "../knowledge/platforms/angular.js";
4
3
  import { SCHEMAS } from "../knowledge/platforms/common.js";
5
4
  import { generateWebComponentsThemeSass } from "../knowledge/platforms/webcomponents.js";
6
5
  import { TYPOGRAPHY_PRESETS } from "../knowledge/typography.js";
7
- import { generateUseStatement, toVariableName, generatePresetImports, generateHeader, quoteFontFamily } from "../utils/sass.js";
8
- import { generateElevationsCode, generatePaletteCode, generateTypographyCode } from "../utils/sass.js";
6
+ import { generateHeader, generatePresetImports, generateUseStatement, quoteFontFamily, toVariableName } from "../utils/sass.js";
7
+ import { generateAngularThemeSass } from "../knowledge/platforms/angular.js";
8
+ //#region src/generators/sass.ts
9
+ /**
10
+ * Sass code generator for Ignite UI Theming.
11
+ * Generates valid Sass code that uses the igniteui-theming library.
12
+ *
13
+ * Supported platforms:
14
+ * - Angular: Uses `igniteui-angular/theming` with `core()` and `theme()` mixins
15
+ * - Web Components: Uses `igniteui-theming` directly with individual mixins
16
+ * - Blazor: Uses `igniteui-theming` directly with individual mixins
17
+ * - React: Uses `igniteui-theming` directly with individual mixins
18
+ */
19
+ /**
20
+ * Generate a palette definition.
21
+ */
9
22
  function generatePalette(input) {
10
- const variant = input.variant ?? "light";
11
- const name = input.name ? toVariableName(input.name) : `custom-${variant}`;
12
- const varName = `$${name}-palette`;
13
- const paletteArgs = [
14
- `$primary: ${input.primary}`,
15
- `$secondary: ${input.secondary}`,
16
- `$surface: ${input.surface}`
17
- ];
18
- if (input.gray) paletteArgs.push(`$gray: ${input.gray}`);
19
- if (input.info) paletteArgs.push(`$info: ${input.info}`);
20
- if (input.success) paletteArgs.push(`$success: ${input.success}`);
21
- if (input.warn) paletteArgs.push(`$warn: ${input.warn}`);
22
- if (input.error) paletteArgs.push(`$error: ${input.error}`);
23
- const code = `${generateHeader(`${variant} palette with primary color ${input.primary}`)}
23
+ const variant = input.variant ?? "light";
24
+ const varName = `$${input.name ? toVariableName(input.name) : `custom-${variant}`}-palette`;
25
+ const paletteArgs = [
26
+ `$primary: ${input.primary}`,
27
+ `$secondary: ${input.secondary}`,
28
+ `$surface: ${input.surface}`
29
+ ];
30
+ if (input.gray) paletteArgs.push(`$gray: ${input.gray}`);
31
+ if (input.info) paletteArgs.push(`$info: ${input.info}`);
32
+ if (input.success) paletteArgs.push(`$success: ${input.success}`);
33
+ if (input.warn) paletteArgs.push(`$warn: ${input.warn}`);
34
+ if (input.error) paletteArgs.push(`$error: ${input.error}`);
35
+ return {
36
+ code: `${generateHeader(`${variant} palette with primary color ${input.primary}`)}
24
37
  ${generateUseStatement(input.platform, input.licensed)}
25
38
 
26
39
  // Custom ${variant} palette
@@ -30,27 +43,26 @@ ${varName}: palette(
30
43
 
31
44
  // Apply the palette (generates CSS custom properties)
32
45
  @include palette(${varName});
33
- `;
34
- return {
35
- code,
36
- description: `Generated a ${variant} color palette with primary color ${input.primary}`,
37
- variables: [varName]
38
- };
46
+ `,
47
+ description: `Generated a ${variant} color palette with primary color ${input.primary}`,
48
+ variables: [varName]
49
+ };
39
50
  }
51
+ /**
52
+ * Generate typography setup.
53
+ */
40
54
  function generateTypography(input) {
41
- const designSystem = input.designSystem ?? "material";
42
- const typeScaleVar = `$${designSystem}-type-scale`;
43
- const preset = TYPOGRAPHY_PRESETS[designSystem];
44
- const typeface = input.fontFamily || preset.typeface;
45
- const presetImports = generatePresetImports({
46
- platform: input.platform,
47
- includeTypography: true
48
- });
49
- const imports = [
50
- generateUseStatement(input.platform, input.licensed),
51
- ...presetImports
52
- ].join("\n");
53
- const code = `${generateHeader(`Typography setup using ${designSystem} type scale`)}
55
+ const designSystem = input.designSystem ?? "material";
56
+ const typeScaleVar = `$${designSystem}-type-scale`;
57
+ const preset = TYPOGRAPHY_PRESETS[designSystem];
58
+ const typeface = input.fontFamily || preset.typeface;
59
+ const presetImports = generatePresetImports({
60
+ platform: input.platform,
61
+ includeTypography: true
62
+ });
63
+ const imports = [generateUseStatement(input.platform, input.licensed), ...presetImports].join("\n");
64
+ return {
65
+ code: `${generateHeader(`Typography setup using ${designSystem} type scale`)}
54
66
  ${imports}
55
67
 
56
68
  // Typography setup with ${designSystem} type scale
@@ -58,238 +70,199 @@ ${imports}
58
70
  $font-family: ${quoteFontFamily(typeface)},
59
71
  $type-scale: ${typeScaleVar}
60
72
  );
61
- `;
62
- return {
63
- code,
64
- description: `Generated typography setup using ${designSystem} design system with font family ${typeface}`,
65
- variables: [typeScaleVar]
66
- };
73
+ `,
74
+ description: `Generated typography setup using ${designSystem} design system with font family ${typeface}`,
75
+ variables: [typeScaleVar]
76
+ };
67
77
  }
78
+ /**
79
+ * Generate elevations setup.
80
+ */
68
81
  function generateElevations(input) {
69
- const preset = input.designSystem ?? "material";
70
- const elevationsVar = `$${preset}-elevations`;
71
- const presetImports = generatePresetImports({
72
- platform: input.platform,
73
- includeElevations: true
74
- });
75
- const imports = [
76
- generateUseStatement(input.platform, input.licensed),
77
- ...presetImports
78
- ].join("\n");
79
- const code = `${generateHeader(`Elevations setup using ${preset} preset`)}
82
+ const preset = input.designSystem ?? "material";
83
+ const elevationsVar = `$${preset}-elevations`;
84
+ const presetImports = generatePresetImports({
85
+ platform: input.platform,
86
+ includeElevations: true
87
+ });
88
+ const imports = [generateUseStatement(input.platform, input.licensed), ...presetImports].join("\n");
89
+ return {
90
+ code: `${generateHeader(`Elevations setup using ${preset} preset`)}
80
91
  ${imports}
81
92
 
82
93
  // Elevations setup with ${preset} shadows
83
94
  @include elevations(${elevationsVar});
84
- `;
85
- return {
86
- code,
87
- description: `Generated elevations setup using ${preset} preset (25 elevation levels)`,
88
- variables: [elevationsVar]
89
- };
95
+ `,
96
+ description: `Generated elevations setup using ${preset} preset (25 elevation levels)`,
97
+ variables: [elevationsVar]
98
+ };
90
99
  }
100
+ /**
101
+ * Generate a complete theme (palette + typography + elevations).
102
+ *
103
+ * Supports two platforms:
104
+ * - `angular`: Uses `igniteui-angular/theming` with `core()` and `theme()` mixins
105
+ * - `webcomponents`: Uses `igniteui-theming` directly with individual mixins
106
+ *
107
+ * If no platform is specified, defaults to generating platform-agnostic code
108
+ * using igniteui-theming directly (similar to webcomponents but simpler).
109
+ */
91
110
  function generateTheme(input) {
92
- const platform = input.platform;
93
- const designSystem = input.designSystem ?? "material";
94
- const variant = input.variant ?? "light";
95
- switch (platform) {
96
- case "angular":
97
- return generateAngularTheme(input, designSystem, variant);
98
- case "webcomponents":
99
- case "react":
100
- case "blazor":
101
- return generateWebComponentsTheme(input, designSystem, variant);
102
- default:
103
- return generateGenericTheme(input, designSystem, variant);
104
- }
111
+ const platform = input.platform;
112
+ const designSystem = input.designSystem ?? "material";
113
+ const variant = input.variant ?? "light";
114
+ switch (platform) {
115
+ case "angular": return generateAngularTheme(input, designSystem, variant);
116
+ case "webcomponents":
117
+ case "react":
118
+ case "blazor": return generateWebComponentsTheme(input, designSystem, variant);
119
+ default: return generateGenericTheme(input, designSystem, variant);
120
+ }
105
121
  }
122
+ /**
123
+ * Generate Angular-specific theme using core() and theme() mixins.
124
+ */
106
125
  function generateAngularTheme(input, designSystem, variant) {
107
- const code = generateAngularThemeSass({
108
- designSystem,
109
- variant,
110
- primaryColor: input.primaryColor,
111
- secondaryColor: input.secondaryColor,
112
- surfaceColor: input.surfaceColor,
113
- customPaletteName: input.name ? `$${toVariableName(input.name)}-palette` : void 0,
114
- fontFamily: input.fontFamily,
115
- includeTypography: input.includeTypography !== false
116
- });
117
- const variables = [];
118
- if (input.name) {
119
- variables.push(`$${toVariableName(input.name)}-palette`);
120
- }
121
- variables.push(`$${variant}-${designSystem}-schema`);
122
- if (input.includeTypography !== false) {
123
- if (!input.fontFamily) {
124
- variables.push(`$${designSystem}-typeface`);
125
- }
126
- variables.push(`$${designSystem}-type-scale`);
127
- }
128
- return {
129
- code,
130
- description: `Generated Angular ${variant} theme based on ${designSystem} design system`,
131
- variables
132
- };
126
+ const code = generateAngularThemeSass({
127
+ designSystem,
128
+ variant,
129
+ primaryColor: input.primaryColor,
130
+ secondaryColor: input.secondaryColor,
131
+ surfaceColor: input.surfaceColor,
132
+ customPaletteName: input.name ? `$${toVariableName(input.name)}-palette` : void 0,
133
+ fontFamily: input.fontFamily,
134
+ includeTypography: input.includeTypography !== false
135
+ });
136
+ const variables = [];
137
+ if (input.name) variables.push(`$${toVariableName(input.name)}-palette`);
138
+ variables.push(`$${variant}-${designSystem}-schema`);
139
+ if (input.includeTypography !== false) {
140
+ if (!input.fontFamily) variables.push(`$${designSystem}-typeface`);
141
+ variables.push(`$${designSystem}-type-scale`);
142
+ }
143
+ return {
144
+ code,
145
+ description: `Generated Angular ${variant} theme based on ${designSystem} design system`,
146
+ variables
147
+ };
133
148
  }
149
+ /**
150
+ * Generate Web Components-specific theme using individual mixins.
151
+ */
134
152
  function generateWebComponentsTheme(input, designSystem, variant) {
135
- const code = generateWebComponentsThemeSass({
136
- designSystem,
137
- variant,
138
- primaryColor: input.primaryColor,
139
- secondaryColor: input.secondaryColor,
140
- surfaceColor: input.surfaceColor,
141
- customPaletteName: input.name ? `$${toVariableName(input.name)}-palette` : void 0,
142
- fontFamily: input.fontFamily,
143
- includeTypography: input.includeTypography !== false,
144
- includeElevations: input.includeElevations !== false,
145
- includeSpacing: input.includeSpacing !== false
146
- });
147
- const variables = [];
148
- if (input.name) {
149
- variables.push(`$${toVariableName(input.name)}-palette`);
150
- } else {
151
- variables.push("$palette");
152
- }
153
- if (input.includeTypography !== false) {
154
- if (!input.fontFamily) {
155
- variables.push("$typeface");
156
- }
157
- variables.push("$type-scale");
158
- }
159
- if (input.includeElevations !== false) {
160
- variables.push(
161
- designSystem === "indigo" ? "$indigo-elevations" : "$material-elevations"
162
- );
163
- }
164
- return {
165
- code,
166
- description: `Generated Web Components ${variant} theme based on ${designSystem} design system`,
167
- variables
168
- };
153
+ const code = generateWebComponentsThemeSass({
154
+ designSystem,
155
+ variant,
156
+ primaryColor: input.primaryColor,
157
+ secondaryColor: input.secondaryColor,
158
+ surfaceColor: input.surfaceColor,
159
+ customPaletteName: input.name ? `$${toVariableName(input.name)}-palette` : void 0,
160
+ fontFamily: input.fontFamily,
161
+ includeTypography: input.includeTypography !== false,
162
+ includeElevations: input.includeElevations !== false,
163
+ includeSpacing: input.includeSpacing !== false
164
+ });
165
+ const variables = [];
166
+ if (input.name) variables.push(`$${toVariableName(input.name)}-palette`);
167
+ else variables.push("$palette");
168
+ if (input.includeTypography !== false) {
169
+ if (!input.fontFamily) variables.push("$typeface");
170
+ variables.push("$type-scale");
171
+ }
172
+ if (input.includeElevations !== false) variables.push(designSystem === "indigo" ? "$indigo-elevations" : "$material-elevations");
173
+ return {
174
+ code,
175
+ description: `Generated Web Components ${variant} theme based on ${designSystem} design system`,
176
+ variables
177
+ };
169
178
  }
179
+ /**
180
+ * Generate platform-agnostic theme (legacy behavior).
181
+ * Uses igniteui-theming directly without platform-specific optimizations.
182
+ */
170
183
  function generateGenericTheme(input, designSystem, variant) {
171
- const themeName = input.name ? toVariableName(input.name) : `${variant}-${designSystem}`;
172
- const paletteVar = `$${themeName}-palette`;
173
- const includeTypography = input.includeTypography !== false;
174
- const includeElevations = input.includeElevations !== false;
175
- const variables = [paletteVar];
176
- const paletteArgs = [`$primary: ${input.primaryColor}`];
177
- if (input.secondaryColor)
178
- paletteArgs.push(`$secondary: ${input.secondaryColor}`);
179
- if (input.surfaceColor) {
180
- paletteArgs.push(`$surface: ${input.surfaceColor}`);
181
- } else {
182
- paletteArgs.push(`$surface: ${variant === "dark" ? "#222222" : "white"}`);
183
- }
184
- const presetImports = generatePresetImports({
185
- platform: input.platform,
186
- includeTypography,
187
- includeElevations
188
- });
189
- const sections = [
190
- generateHeader(
191
- `Complete ${variant} theme based on ${designSystem} design system`
192
- ),
193
- '// NOTE: Specify platform ("angular" or "webcomponents") for optimized output',
194
- generateUseStatement(input.platform, input.licensed),
195
- ...presetImports,
196
- "",
197
- `// ${themeName} palette`,
198
- `${paletteVar}: palette(`,
199
- ` ${paletteArgs.join(",\n ")}`,
200
- ");",
201
- "",
202
- "// Apply the palette",
203
- `@include palette(${paletteVar});`
204
- ];
205
- if (includeTypography) {
206
- const preset = TYPOGRAPHY_PRESETS[designSystem];
207
- const typeface = input.fontFamily || preset.typeface;
208
- const typeScaleVar = `$${designSystem}-type-scale`;
209
- variables.push(typeScaleVar);
210
- sections.push(
211
- "",
212
- "// Typography setup",
213
- "@include typography(",
214
- ` $font-family: ${quoteFontFamily(typeface)},`,
215
- ` $type-scale: ${typeScaleVar}`,
216
- ");"
217
- );
218
- }
219
- if (includeElevations) {
220
- const elevationPreset = designSystem === "indigo" ? "indigo" : "material";
221
- const elevationsVar = `$${elevationPreset}-elevations`;
222
- variables.push(elevationsVar);
223
- sections.push(
224
- "",
225
- "// Elevations setup",
226
- `@include elevations(${elevationsVar});`
227
- );
228
- }
229
- const code = `${sections.join("\n")}
230
- `;
231
- return {
232
- code,
233
- description: `Generated complete ${variant} theme based on ${designSystem} design system (platform-agnostic)`,
234
- variables
235
- };
184
+ const themeName = input.name ? toVariableName(input.name) : `${variant}-${designSystem}`;
185
+ const paletteVar = `$${themeName}-palette`;
186
+ const includeTypography = input.includeTypography !== false;
187
+ const includeElevations = input.includeElevations !== false;
188
+ const variables = [paletteVar];
189
+ const paletteArgs = [`$primary: ${input.primaryColor}`];
190
+ if (input.secondaryColor) paletteArgs.push(`$secondary: ${input.secondaryColor}`);
191
+ if (input.surfaceColor) paletteArgs.push(`$surface: ${input.surfaceColor}`);
192
+ else paletteArgs.push(`$surface: ${variant === "dark" ? "#222222" : "white"}`);
193
+ const presetImports = generatePresetImports({
194
+ platform: input.platform,
195
+ includeTypography,
196
+ includeElevations
197
+ });
198
+ const sections = [
199
+ generateHeader(`Complete ${variant} theme based on ${designSystem} design system`),
200
+ "// NOTE: Specify platform (\"angular\" or \"webcomponents\") for optimized output",
201
+ generateUseStatement(input.platform, input.licensed),
202
+ ...presetImports,
203
+ "",
204
+ `// ${themeName} palette`,
205
+ `${paletteVar}: palette(`,
206
+ ` ${paletteArgs.join(",\n ")}`,
207
+ ");",
208
+ "",
209
+ "// Apply the palette",
210
+ `@include palette(${paletteVar});`
211
+ ];
212
+ if (includeTypography) {
213
+ const preset = TYPOGRAPHY_PRESETS[designSystem];
214
+ const typeface = input.fontFamily || preset.typeface;
215
+ const typeScaleVar = `$${designSystem}-type-scale`;
216
+ variables.push(typeScaleVar);
217
+ sections.push("", "// Typography setup", "@include typography(", ` $font-family: ${quoteFontFamily(typeface)},`, ` $type-scale: ${typeScaleVar}`, ");");
218
+ }
219
+ if (includeElevations) {
220
+ const elevationsVar = `$${designSystem === "indigo" ? "indigo" : "material"}-elevations`;
221
+ variables.push(elevationsVar);
222
+ sections.push("", "// Elevations setup", `@include elevations(${elevationsVar});`);
223
+ }
224
+ return {
225
+ code: `${sections.join("\n")}\n`,
226
+ description: `Generated complete ${variant} theme based on ${designSystem} design system (platform-agnostic)`,
227
+ variables
228
+ };
236
229
  }
230
+ /**
231
+ * Generate Sass code for a component theme.
232
+ */
237
233
  function generateComponentTheme(input) {
238
- const theme = getComponentTheme(input.component);
239
- if (!theme) {
240
- throw new Error(`Unknown component: ${input.component}`);
241
- }
242
- const designSystem = input.designSystem ?? "material";
243
- const variant = input.variant ?? "light";
244
- const themeFn = theme.themeFunctionName;
245
- const themeName = input.name ? `$${toVariableName(input.name)}` : `$custom-${input.component}-theme`;
246
- const schemaVar = SCHEMAS[variant][designSystem];
247
- const tokenArgs = [`$schema: ${schemaVar}`];
248
- for (const [tokenName, value] of Object.entries(input.tokens)) {
249
- const stringValue = typeof value === "number" ? String(value) : value;
250
- tokenArgs.push(`$${tokenName}: ${stringValue}`);
251
- }
252
- const defaultSelectors = getComponentSelector(
253
- input.component,
254
- input.platform
255
- );
256
- const selector = input.selector || (defaultSelectors.length > 0 ? defaultSelectors[0] : input.component);
257
- const sections = [
258
- generateHeader(`Custom ${input.component} theme`),
259
- generateUseStatement(input.platform, input.licensed),
260
- "",
261
- `// Custom ${input.component} theme`,
262
- `${themeName}: ${themeFn}(`
263
- ];
264
- if (tokenArgs.length > 0) {
265
- sections.push(` ${tokenArgs.join(",\n ")}`);
266
- }
267
- sections.push(");");
268
- sections.push("");
269
- sections.push(`// Apply the theme to ${selector}`);
270
- sections.push(`${selector} {`);
271
- sections.push(` @include tokens(${themeName});`);
272
- sections.push("}");
273
- const code = `${sections.join("\n")}
274
- `;
275
- return {
276
- code,
277
- description: `Generated custom ${input.component} theme with ${Object.keys(input.tokens).length} token(s) using ${designSystem} design system (${variant} variant)`,
278
- variables: [themeName]
279
- };
234
+ const theme = getComponentTheme(input.component);
235
+ if (!theme) throw new Error(`Unknown component: ${input.component}`);
236
+ const designSystem = input.designSystem ?? "material";
237
+ const variant = input.variant ?? "light";
238
+ const themeFn = theme.themeFunctionName;
239
+ const themeName = input.name ? `$${toVariableName(input.name)}` : `$custom-${input.component}-theme`;
240
+ const tokenArgs = [`$schema: ${SCHEMAS[variant][designSystem]}`];
241
+ for (const [tokenName, value] of Object.entries(input.tokens)) {
242
+ const stringValue = typeof value === "number" ? String(value) : value;
243
+ tokenArgs.push(`$${tokenName}: ${stringValue}`);
244
+ }
245
+ const defaultSelectors = getComponentSelector(input.component, input.platform);
246
+ const selector = input.selector || (defaultSelectors.length > 0 ? defaultSelectors[0] : input.component);
247
+ const sections = [
248
+ generateHeader(`Custom ${input.component} theme`),
249
+ generateUseStatement(input.platform, input.licensed),
250
+ "",
251
+ `// Custom ${input.component} theme`,
252
+ `${themeName}: ${themeFn}(`
253
+ ];
254
+ if (tokenArgs.length > 0) sections.push(` ${tokenArgs.join(",\n ")}`);
255
+ sections.push(");");
256
+ sections.push("");
257
+ sections.push(`// Apply the theme to ${selector}`);
258
+ sections.push(`${selector} {`);
259
+ sections.push(` @include tokens(${themeName});`);
260
+ sections.push("}");
261
+ return {
262
+ code: `${sections.join("\n")}\n`,
263
+ description: `Generated custom ${input.component} theme with ${Object.keys(input.tokens).length} token(s) using ${designSystem} design system (${variant} variant)`,
264
+ variables: [themeName]
265
+ };
280
266
  }
281
- export {
282
- generateComponentTheme,
283
- generateElevations,
284
- generateElevationsCode,
285
- generateHeader,
286
- generatePalette,
287
- generatePaletteCode,
288
- generatePresetImports,
289
- generateTheme,
290
- generateTypography,
291
- generateTypographyCode,
292
- generateUseStatement,
293
- quoteFontFamily,
294
- toVariableName
295
- };
267
+ //#endregion
268
+ export { generateComponentTheme, generateElevations, generatePalette, generateTheme, generateTypography };