UNPKG

igniteui-theming

Version:

A set of Sass variables, mixins, and functions for generating palettes, typography, and elevations used by Ignite UI components.

154 lines (153 loc) 5.68 kB
import { SASS_USE_ASSEMBLY_NOTE } from "../../utils/sass.js"; import { generateTheme } from "../../generators/sass.js"; import { formatCssOutput, generateThemeCss } from "../../generators/css.js"; import { analyzeThemeColorsForPalette, formatPaletteSuitabilityWarnings, formatValidationResult, generatePaletteSuitabilityComments, generateWarningComments, validatePaletteColors } from "../../validators/palette.js"; import "../../validators/index.js"; //#region src/tools/handlers/theme.ts /** * Handler for create_theme tool. */ async function handleCreateTheme(params) { const variant = params.variant ?? "light"; const output = params.output ?? (params.platform === "angular" ? "sass" : "css"); const validation = await validatePaletteColors({ variant, surface: params.surfaceColor }); const suitabilityAnalysis = await analyzeThemeColorsForPalette({ primary: params.primaryColor, secondary: params.secondaryColor, surface: params.surfaceColor }); if (output === "css") return handleCssOutput(params, validation, suitabilityAnalysis); return handleSassOutput(params, validation, suitabilityAnalysis); } async function handleCssOutput(params, validation, suitabilityAnalysis) { try { const result = await generateThemeCss({ platform: params.platform, designSystem: params.designSystem, variant: params.variant, primaryColor: params.primaryColor, secondaryColor: params.secondaryColor, surfaceColor: params.surfaceColor, fontFamily: params.fontFamily, includeTypography: params.includeTypography, includeElevations: params.includeElevations, includeSpacing: params.includeSpacing, name: params.name }); const formattedCss = formatCssOutput(result.css, result.description); const responseParts = [result.description]; responseParts.push(""); responseParts.push("Output format: CSS custom properties"); if (params.platform) { const { PLATFORM_METADATA } = await import("../../knowledge/platforms/index.js"); responseParts.push(""); responseParts.push(`Platform: ${PLATFORM_METADATA[params.platform]?.name ?? params.platform}`); } if (result.angularCaveat) { responseParts.push(""); responseParts.push("⚠️ Angular note: This CSS output contains only CSS custom properties (--ig-* variables). It does not include the component-scoped class styles generated by Angular's core() and theme() mixins. For full Angular theme output use output: \"sass\"."); } const validationText = formatValidationResult(validation); if (validationText) { responseParts.push(""); responseParts.push(validationText); } if (!suitabilityAnalysis.allSuitable) { responseParts.push(""); responseParts.push(formatPaletteSuitabilityWarnings(suitabilityAnalysis)); } responseParts.push(""); responseParts.push("```css"); responseParts.push(formattedCss.trimEnd()); responseParts.push("```"); return { content: [{ type: "text", text: responseParts.join("\n") }] }; } catch (error) { return { content: [{ type: "text", text: `**Error generating CSS theme**\n\n${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } async function handleSassOutput(params, validation, suitabilityAnalysis) { const result = generateTheme({ platform: params.platform, licensed: params.licensed, designSystem: params.designSystem, primaryColor: params.primaryColor, secondaryColor: params.secondaryColor, surfaceColor: params.surfaceColor, variant: params.variant, name: params.name, fontFamily: params.fontFamily, includeTypography: params.includeTypography, includeElevations: params.includeElevations, includeSpacing: params.includeSpacing }); let finalCode = result.code; const allWarningComments = []; if (!validation.isValid) allWarningComments.push(...generateWarningComments(validation)); if (!suitabilityAnalysis.allSuitable) allWarningComments.push(...generatePaletteSuitabilityComments(suitabilityAnalysis)); if (allWarningComments.length > 0) { const lines = finalCode.split("\n"); const useIndex = lines.findIndex((line) => line.startsWith("@use '") || line.startsWith("@use \"")); if (useIndex > 0) { lines.splice(useIndex, 0, ...allWarningComments, ""); finalCode = lines.join("\n"); } } const responseParts = [result.description]; let platformNote = ""; switch (params.platform) { case "angular": platformNote = "Platform: Ignite UI for Angular"; break; case "webcomponents": platformNote = "Platform: Ignite UI for Web Components"; break; case "react": platformNote = "Platform: Ignite UI for React"; break; case "blazor": platformNote = "Platform: Ignite UI for Blazor"; break; case "generic": platformNote = "Platform: Ignite UI Theming (Standalone)"; break; default: platformNote = "Platform: Not specified (generic output). Specify `platform` for optimized code."; break; } responseParts.push(""); responseParts.push(platformNote); const validationText = formatValidationResult(validation); if (validationText) { responseParts.push(""); responseParts.push(validationText); } if (!suitabilityAnalysis.allSuitable) { responseParts.push(""); responseParts.push(formatPaletteSuitabilityWarnings(suitabilityAnalysis)); } responseParts.push(""); responseParts.push(`Variables created/used: ${result.variables.join(", ")}`); responseParts.push(""); responseParts.push("```scss"); responseParts.push(finalCode.trimEnd()); responseParts.push("```"); responseParts.push(SASS_USE_ASSEMBLY_NOTE); return { content: [{ type: "text", text: responseParts.join("\n") }] }; } //#endregion export { handleCreateTheme };