import { ThemeConfig, ThemeColors } from "./ThemeConfig"; // Maps CSS variable names to our ThemeConfig keys const cssVarMap: Record = { "--background": "background", "--foreground": "foreground", "--card": "card", "--card-foreground": "cardForeground", "--popover": "popover", "--popover-foreground": "popoverForeground", "--primary": "primary", "--primary-foreground": "primaryForeground", "--secondary": "secondary", "--secondary-foreground": "secondaryForeground", "--muted": "muted", "--muted-foreground": "mutedForeground", "--accent": "accent", "--accent-foreground": "accentForeground", "--destructive": "destructive", "--destructive-foreground": "destructiveForeground", "--border": "border", "--input": "input", "--ring": "ring", "--sidebar": "sidebar", "--sidebar-background": "sidebarBackground", "--sidebar-foreground": "sidebarForeground", "--sidebar-primary": "sidebarPrimary", "--sidebar-primary-foreground": "sidebarPrimaryForeground", "--sidebar-accent": "sidebarAccent", "--sidebar-accent-foreground": "sidebarAccentForeground", "--sidebar-border": "sidebarBorder", "--sidebar-ring": "sidebarRing", }; export function parseCssConfig(cssText: string): Partial { const config: Partial = { colors: {}, darkColors: {}, }; // Parse :root section for light mode colors const rootMatch = cssText.match(/:root\s*{([^}]*)}/); if (rootMatch) { const rootContent = rootMatch[1]; config.colors = parseColorSection(rootContent); // Parse radius const radiusMatch = rootContent.match(/--radius:\s*([^;]+);/); if (radiusMatch) { const radiusValue = radiusMatch[1].trim(); // Convert px to rem (assuming 16px = 1rem) if (radiusValue.endsWith("px")) { const px = parseFloat(radiusValue); config.radius = `${px / 16}rem`; } else if (radiusValue.endsWith("rem")) { config.radius = radiusValue; } else { config.radius = radiusValue; } } // Parse font-sans (use as default font family) const fontMatch = rootContent.match(/--font-sans:\s*([^;]+);/); if (fontMatch) { config.fontFamily = fontMatch[1].trim(); } } // Parse .dark section for dark mode colors const darkMatch = cssText.match(/\.dark\s*{([^}]*)}/); if (darkMatch) { const darkContent = darkMatch[1]; config.darkColors = parseColorSection(darkContent); } return config; } function parseColorSection(content: string): ThemeColors { const colors: ThemeColors = {}; // Extract all CSS variables const varRegex = /(--[a-zA-Z-]+):\s*([^;]+);/g; let match; while ((match = varRegex.exec(content)) !== null) { const cssVar = match[1]; const value = match[2].trim(); // Check if this CSS variable maps to one of our theme colors const configKey = cssVarMap[cssVar]; if (configKey) { colors[configKey] = value; } } return colors; } export function formatCssValue(value: string): string { // If it's already a valid CSS color format, return as is if ( value.startsWith("hsl(") || value.startsWith("hsla(") || value.startsWith("oklch(") || value.startsWith("rgb(") || value.startsWith("rgba(") || value.startsWith("#") ) { return value; } // Otherwise, assume it's a hex color without the # if (/^[0-9A-Fa-f]{6}$/.test(value)) { return `#${value}`; } return value; }