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,229 +1,169 @@
1
- import "../../knowledge/colors.js";
2
- import { hasVariants, getVariants, isCompoundComponent, getCompoundComponentInfo, getTokenDerivationsForChild, getComponentSelector } from "../../knowledge/component-metadata.js";
3
- import { resolveComponentTheme, searchComponents, COMPONENT_NAMES } from "../../knowledge/component-themes.js";
4
- import "../../knowledge/custom-palettes.js";
5
- import "../../utils/types.js";
6
- import "../../knowledge/palettes.js";
7
- import "node:fs";
8
- import "node:path";
1
+ import { getComponentSelector, getCompoundComponentInfo, getTokenDerivationsForChild, getVariants, hasVariants, isCompoundComponent } from "../../knowledge/component-metadata.js";
2
+ import { COMPONENT_NAMES, resolveComponentTheme, searchComponents } from "../../knowledge/component-themes.js";
3
+ import "../../knowledge/index.js";
4
+ //#region src/tools/handlers/component-tokens.ts
9
5
  async function handleGetComponentDesignTokens(params) {
10
- const { component } = params;
11
- const normalizedName = component.toLowerCase().trim();
12
- const formatSelectorList = (selectors) => {
13
- if (!selectors || selectors.length === 0) {
14
- return "N/A";
15
- }
16
- const selectorText = Array.isArray(selectors) ? selectors.join(" | ") : selectors;
17
- return `\`${selectorText}\``;
18
- };
19
- const getScopeSelectorForPlatform = (compoundInfo, componentName, scopeName, platform) => {
20
- const selectorPlatform = platform === "angular" ? "angular" : "webcomponents";
21
- if (scopeName === "inline") {
22
- const selectors = getComponentSelector(componentName, platform);
23
- return formatSelectorList(
24
- selectors.length > 0 ? selectors.length === 1 ? selectors[0] : selectors : null
25
- );
26
- }
27
- const scope = compoundInfo.additionalScopes?.[scopeName];
28
- if (!scope) {
29
- return "N/A";
30
- }
31
- return formatSelectorList(scope[selectorPlatform]);
32
- };
33
- const resolveChildScopeName = (compoundInfo, childThemeName, platform) => {
34
- const scopePlatform = platform === "angular" ? "angular" : "webcomponents";
35
- const childScope = compoundInfo?.childScopes?.[childThemeName];
36
- return childScope?.[scopePlatform] ?? "inline";
37
- };
38
- const resolution = resolveComponentTheme(normalizedName);
39
- const theme = resolution?.theme;
40
- if (!theme) {
41
- if (resolution?.error) {
42
- return {
43
- content: [
44
- {
45
- type: "text",
46
- text: `**Error:** ${resolution.error}
6
+ const { component } = params;
7
+ const normalizedName = component.toLowerCase().trim();
8
+ const formatSelectorList = (selectors) => {
9
+ if (!selectors || selectors.length === 0) return "N/A";
10
+ return `\`${Array.isArray(selectors) ? selectors.join(" | ") : selectors}\``;
11
+ };
12
+ const getScopeSelectorForPlatform = (compoundInfo, componentName, scopeName, platform) => {
13
+ const selectorPlatform = platform === "angular" ? "angular" : "webcomponents";
14
+ if (scopeName === "inline") {
15
+ const selectors = getComponentSelector(componentName, platform);
16
+ return formatSelectorList(selectors.length > 0 ? selectors.length === 1 ? selectors[0] : selectors : null);
17
+ }
18
+ const scope = compoundInfo.additionalScopes?.[scopeName];
19
+ if (!scope) return "N/A";
20
+ return formatSelectorList(scope[selectorPlatform]);
21
+ };
22
+ const resolveChildScopeName = (compoundInfo, childThemeName, platform) => {
23
+ const scopePlatform = platform === "angular" ? "angular" : "webcomponents";
24
+ return (compoundInfo?.childScopes?.[childThemeName])?.[scopePlatform] ?? "inline";
25
+ };
26
+ const resolution = resolveComponentTheme(normalizedName);
27
+ const theme = resolution?.theme;
28
+ if (!theme) {
29
+ if (resolution?.error) return {
30
+ content: [{
31
+ type: "text",
32
+ text: `**Error:** ${resolution.error}
47
33
 
48
34
  Use a valid component name or update component metadata to point to a valid theme.`
49
- }
50
- ],
51
- isError: true
52
- };
53
- }
54
- const suggestions = searchComponents(normalizedName);
55
- const componentList = suggestions.length > 0 ? suggestions.slice(0, 10) : COMPONENT_NAMES.slice(0, 20);
56
- return {
57
- content: [
58
- {
59
- type: "text",
60
- text: `Component "${component}" not found.
35
+ }],
36
+ isError: true
37
+ };
38
+ const suggestions = searchComponents(normalizedName);
39
+ const componentList = suggestions.length > 0 ? suggestions.slice(0, 10) : COMPONENT_NAMES.slice(0, 20);
40
+ return { content: [{
41
+ type: "text",
42
+ text: `Component "${component}" not found.
61
43
 
62
44
  ${suggestions.length > 0 ? "**Similar components:**" : "**Available components (partial list):**"}
63
45
  ${componentList.map((c) => `- ${c}`).join("\n")}
64
46
 
65
- ${suggestions.length === 0 ? `
66
- Total available: ${COMPONENT_NAMES.length} components. Use a more specific name to search.` : ""}
47
+ ${suggestions.length === 0 ? `\nTotal available: ${COMPONENT_NAMES.length} components. Use a more specific name to search.` : ""}
67
48
 
68
49
  **Tip:** For button variants, use specific names like "flat-button", "contained-button", "outlined-button", or "fab-button".`
69
- }
70
- ]
71
- };
72
- }
73
- const PLATFORM_GROUPS = [
74
- { label: "Angular", platform: "angular" },
75
- { label: "Web Components", platform: "webcomponents" },
76
- { label: "Blazor", platform: "blazor" },
77
- { label: "React", platform: "react" }
78
- ];
79
- const responseParts = [];
80
- responseParts.push(
81
- `Implement a theme for the \`${normalizedName}\` component using the following guidance.`
82
- );
83
- responseParts.push("");
84
- responseParts.push(`**Theme Function:** \`${theme.themeFunctionName}()\``);
85
- responseParts.push("");
86
- if (hasVariants(normalizedName)) {
87
- const variants = getVariants(normalizedName);
88
- responseParts.push("**Note:** This component has variant-specific themes:");
89
- responseParts.push(variants.map((v) => `- \`${v}\``).join("\n"));
90
- responseParts.push("");
91
- responseParts.push(
92
- "Consider using the specific variant theme for more targeted styling."
93
- );
94
- responseParts.push("");
95
- }
96
- if (isCompoundComponent(normalizedName)) {
97
- const compoundInfo = getCompoundComponentInfo(normalizedName);
98
- if (compoundInfo) {
99
- responseParts.push("**Compound Component:**");
100
- responseParts.push(compoundInfo.description);
101
- responseParts.push("");
102
- responseParts.push("**Steps:**");
103
- responseParts.push(
104
- "1. Choose your platform and use the matching scopes below."
105
- );
106
- responseParts.push(
107
- "2. For each related theme: call `get_component_design_tokens`, then `create_component_theme` using the selector for that platform scope."
108
- );
109
- responseParts.push(
110
- "3. Apply `@include tokens(child-theme(...))` inside the scope selector."
111
- );
112
- responseParts.push("");
113
- const allScopeNames = [
114
- "inline",
115
- ...Object.keys(compoundInfo.additionalScopes ?? {})
116
- ];
117
- for (const group of PLATFORM_GROUPS) {
118
- responseParts.push(`**${group.label}:**`);
119
- const scopeRows = allScopeNames.map((scopeName) => {
120
- const selectorText = getScopeSelectorForPlatform(
121
- compoundInfo,
122
- normalizedName,
123
- scopeName,
124
- group.platform
125
- );
126
- return { scopeName, selectorText };
127
- }).filter((row) => row.selectorText !== "N/A");
128
- if (scopeRows.length > 0) {
129
- responseParts.push("| Scope | Selector |");
130
- responseParts.push("| --- | --- |");
131
- responseParts.push(
132
- scopeRows.map((row) => `| ${row.scopeName} | ${row.selectorText} |`).join("\n")
133
- );
134
- responseParts.push("");
135
- }
136
- responseParts.push(`**Related themes (${group.label})**`);
137
- responseParts.push("| Theme | Scope | Selector |");
138
- responseParts.push("| --- | --- | --- |");
139
- responseParts.push(
140
- compoundInfo.relatedThemes.map((relatedTheme) => {
141
- const scopeName = resolveChildScopeName(
142
- compoundInfo,
143
- relatedTheme,
144
- group.platform
145
- );
146
- const selectorText = getScopeSelectorForPlatform(
147
- compoundInfo,
148
- normalizedName,
149
- scopeName,
150
- group.platform
151
- );
152
- return `| \`${relatedTheme}\` | ${scopeName} | ${selectorText} |`;
153
- }).join("\n")
154
- );
155
- responseParts.push("");
156
- }
157
- const derivationRows = compoundInfo.relatedThemes.flatMap(
158
- (relatedTheme) => {
159
- const derivations = getTokenDerivationsForChild(
160
- normalizedName,
161
- relatedTheme
162
- );
163
- return Object.entries(derivations).map(([token, derivation]) => {
164
- const transformDesc = derivation.transform === "identity" ? `same as \`${derivation.from}\`` : `\`${derivation.transform}\` of \`${derivation.from}\``;
165
- return `| \`${relatedTheme}\` | \`${token}\` | ${transformDesc} |`;
166
- });
167
- }
168
- );
169
- responseParts.push("**Token derivations:**");
170
- if (derivationRows.length > 0) {
171
- responseParts.push("| Theme | Token | Derivation |");
172
- responseParts.push("| --- | --- | --- |");
173
- responseParts.push(derivationRows.join("\n"));
174
- } else {
175
- responseParts.push("None.");
176
- }
177
- responseParts.push("");
178
- if (compoundInfo.guidance) {
179
- responseParts.push("**Guidance:**");
180
- responseParts.push(compoundInfo.guidance);
181
- responseParts.push("");
182
- }
183
- }
184
- }
185
- if (theme.primaryTokens && theme.primaryTokens.length > 0) {
186
- responseParts.push("**Primary Tokens:**");
187
- for (const pt of theme.primaryTokens) {
188
- responseParts.push(`- \`$${pt.name}\` — ${pt.description}`);
189
- }
190
- if (theme.primaryTokensSummary) {
191
- responseParts.push("");
192
- responseParts.push(theme.primaryTokensSummary);
193
- }
194
- responseParts.push("");
195
- }
196
- if (theme.tokens.length > 0) {
197
- responseParts.push(`**Available Tokens (${theme.tokens.length}):**`);
198
- responseParts.push("");
199
- responseParts.push("| Token Name | Type | Description |");
200
- responseParts.push("|------------|------|-------------|");
201
- for (const token of theme.tokens) {
202
- const cleanDesc = token.description.replace(/\s+/g, " ").trim();
203
- responseParts.push(
204
- `| \`${token.name}\` | ${token.type} | ${cleanDesc} |`
205
- );
206
- }
207
- responseParts.push("");
208
- } else {
209
- responseParts.push(
210
- "**No customizable tokens available for this component.**"
211
- );
212
- responseParts.push("");
213
- }
214
- responseParts.push("---");
215
- responseParts.push(
216
- "**Next step:** Use `create_component_theme` with the tokens above to generate Sass/CSS code."
217
- );
218
- return {
219
- content: [
220
- {
221
- type: "text",
222
- text: responseParts.join("\n")
223
- }
224
- ]
225
- };
50
+ }] };
51
+ }
52
+ const PLATFORM_GROUPS = [
53
+ {
54
+ label: "Angular",
55
+ platform: "angular"
56
+ },
57
+ {
58
+ label: "Web Components",
59
+ platform: "webcomponents"
60
+ },
61
+ {
62
+ label: "Blazor",
63
+ platform: "blazor"
64
+ },
65
+ {
66
+ label: "React",
67
+ platform: "react"
68
+ }
69
+ ];
70
+ const responseParts = [];
71
+ responseParts.push(`Implement a theme for the \`${normalizedName}\` component using the following guidance.`);
72
+ responseParts.push("");
73
+ responseParts.push(`**Theme Function:** \`${theme.themeFunctionName}()\``);
74
+ responseParts.push("");
75
+ if (hasVariants(normalizedName)) {
76
+ const variants = getVariants(normalizedName);
77
+ responseParts.push("**Note:** This component has variant-specific themes:");
78
+ responseParts.push(variants.map((v) => `- \`${v}\``).join("\n"));
79
+ responseParts.push("");
80
+ responseParts.push("Consider using the specific variant theme for more targeted styling.");
81
+ responseParts.push("");
82
+ }
83
+ if (isCompoundComponent(normalizedName)) {
84
+ const compoundInfo = getCompoundComponentInfo(normalizedName);
85
+ if (compoundInfo) {
86
+ responseParts.push("**Compound Component:**");
87
+ responseParts.push(compoundInfo.description);
88
+ responseParts.push("");
89
+ responseParts.push("**Steps:**");
90
+ responseParts.push("1. Choose your platform and use the matching scopes below.");
91
+ responseParts.push("2. For each related theme: call `get_component_design_tokens`, then `create_component_theme` using the selector for that platform scope.");
92
+ responseParts.push("3. Apply `@include tokens(child-theme(...))` inside the scope selector.");
93
+ responseParts.push("");
94
+ const allScopeNames = ["inline", ...Object.keys(compoundInfo.additionalScopes ?? {})];
95
+ for (const group of PLATFORM_GROUPS) {
96
+ responseParts.push(`**${group.label}:**`);
97
+ const scopeRows = allScopeNames.map((scopeName) => {
98
+ return {
99
+ scopeName,
100
+ selectorText: getScopeSelectorForPlatform(compoundInfo, normalizedName, scopeName, group.platform)
101
+ };
102
+ }).filter((row) => row.selectorText !== "N/A");
103
+ if (scopeRows.length > 0) {
104
+ responseParts.push("| Scope | Selector |");
105
+ responseParts.push("| --- | --- |");
106
+ responseParts.push(scopeRows.map((row) => `| ${row.scopeName} | ${row.selectorText} |`).join("\n"));
107
+ responseParts.push("");
108
+ }
109
+ responseParts.push(`**Related themes (${group.label})**`);
110
+ responseParts.push("| Theme | Scope | Selector |");
111
+ responseParts.push("| --- | --- | --- |");
112
+ responseParts.push(compoundInfo.relatedThemes.map((relatedTheme) => {
113
+ const scopeName = resolveChildScopeName(compoundInfo, relatedTheme, group.platform);
114
+ return `| \`${relatedTheme}\` | ${scopeName} | ${getScopeSelectorForPlatform(compoundInfo, normalizedName, scopeName, group.platform)} |`;
115
+ }).join("\n"));
116
+ responseParts.push("");
117
+ }
118
+ const derivationRows = compoundInfo.relatedThemes.flatMap((relatedTheme) => {
119
+ const derivations = getTokenDerivationsForChild(normalizedName, relatedTheme);
120
+ return Object.entries(derivations).map(([token, derivation]) => {
121
+ return `| \`${relatedTheme}\` | \`${token}\` | ${derivation.transform === "identity" ? `same as \`${derivation.from}\`` : `\`${derivation.transform}\` of \`${derivation.from}\``} |`;
122
+ });
123
+ });
124
+ responseParts.push("**Token derivations:**");
125
+ if (derivationRows.length > 0) {
126
+ responseParts.push("| Theme | Token | Derivation |");
127
+ responseParts.push("| --- | --- | --- |");
128
+ responseParts.push(derivationRows.join("\n"));
129
+ } else responseParts.push("None.");
130
+ responseParts.push("");
131
+ if (compoundInfo.guidance) {
132
+ responseParts.push("**Guidance:**");
133
+ responseParts.push(compoundInfo.guidance);
134
+ responseParts.push("");
135
+ }
136
+ }
137
+ }
138
+ if (theme.primaryTokens && theme.primaryTokens.length > 0) {
139
+ responseParts.push("**Primary Tokens:**");
140
+ for (const pt of theme.primaryTokens) responseParts.push(`- \`$${pt.name}\` — ${pt.description}`);
141
+ if (theme.primaryTokensSummary) {
142
+ responseParts.push("");
143
+ responseParts.push(theme.primaryTokensSummary);
144
+ }
145
+ responseParts.push("");
146
+ }
147
+ if (theme.tokens.length > 0) {
148
+ responseParts.push(`**Available Tokens (${theme.tokens.length}):**`);
149
+ responseParts.push("");
150
+ responseParts.push("| Token Name | Type | Description |");
151
+ responseParts.push("|------------|------|-------------|");
152
+ for (const token of theme.tokens) {
153
+ const cleanDesc = token.description.replace(/\s+/g, " ").trim();
154
+ responseParts.push(`| \`${token.name}\` | ${token.type} | ${cleanDesc} |`);
155
+ }
156
+ responseParts.push("");
157
+ } else {
158
+ responseParts.push("**No customizable tokens available for this component.**");
159
+ responseParts.push("");
160
+ }
161
+ responseParts.push("---");
162
+ responseParts.push("**Next step:** Use `create_component_theme` with the tokens above to generate Sass/CSS code.");
163
+ return { content: [{
164
+ type: "text",
165
+ text: responseParts.join("\n")
166
+ }] };
226
167
  }
227
- export {
228
- handleGetComponentDesignTokens
229
- };
168
+ //#endregion
169
+ export { handleGetComponentDesignTokens };