UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

348 lines (345 loc) 12.5 kB
'use client'; import { jsxs, jsx } from 'react/jsx-runtime'; import React, { useState, useCallback, useMemo } from 'react'; import '../../primitives/GlassCore.js'; import '../../primitives/glass/GlassAdvanced.js'; import { OptimizedGlassCore } from '../../primitives/OptimizedGlassCore.js'; import '../../primitives/glass/OptimizedGlassAdvanced.js'; import '../../primitives/MotionNative.js'; import '../../primitives/motion/MotionFramer.js'; // Predefined color palettes const predefinedPalettes = { ocean: { primary: "#0066cc", secondary: "#00a3cc", accent: "#00ffcc" }, sunset: { primary: "#ff6b35", secondary: "#f7931e", accent: "#ffb627" }, forest: { primary: "#2d5a27", secondary: "#4a7c59", accent: "#7fb069" }, royal: { primary: "#4a0e4e", secondary: "#7b2cbf", accent: "#c77dff" }, minimal: { primary: "#2c3e50", secondary: "#34495e", accent: "#ecf0f1" } }; const GlassColorSchemeGenerator = ({ initialScheme, advanced = false, generateCSS = true, generateTailwind = false, className = "", onSchemeChange, onExport }) => { const [baseColor, setBaseColor] = useState(initialScheme?.primary || "#0066cc"); const [palette, setPalette] = useState("ocean"); const [harmony, setHarmony] = useState("analogous"); // Generate color scheme based on base color and harmony const generateScheme = useCallback((color, harmonyType) => { // Convert hex to HSL const hexToHsl = hex => { const r = parseInt(hex.slice(1, 3), 16) / 255; const g = parseInt(hex.slice(3, 5), 16) / 255; const b = parseInt(hex.slice(5, 7), 16) / 255; const max = Math.max(r, g, b); const min = Math.min(r, g, b); let h = 0, s = 0, l = (max + min) / 2; if (max !== min) { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h * 360, s * 100, l * 100]; }; // Convert HSL to hex const hslToHex = (h, s, l) => { h /= 360; s /= 100; l /= 100; const hue2rgb = (p, q, t) => { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; }; let r, g, b; if (s === 0) { r = g = b = l; } else { const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } const toHex = c => { const hex = Math.round(c * 255).toString(16); return hex.length === 1 ? "0" + hex : hex; }; return `#${toHex(r)}${toHex(g)}${toHex(b)}`; }; const [h, s, l] = hexToHsl(color); let colors; switch (harmonyType) { case "analogous": colors = { primary: hslToHex(h, s, l), secondary: hslToHex((h + 30) % 360, s, l), accent: hslToHex((h - 30 + 360) % 360, s, l) }; break; case "complementary": colors = { primary: hslToHex(h, s, l), secondary: hslToHex((h + 180) % 360, s, l), accent: hslToHex((h + 180) % 360, s * 0.8, l * 1.2) }; break; case "triadic": colors = { primary: hslToHex(h, s, l), secondary: hslToHex((h + 120) % 360, s, l), accent: hslToHex((h + 240) % 360, s, l) }; break; case "monochromatic": default: colors = { primary: hslToHex(h, s, l), secondary: hslToHex(h, s * 0.6, l * 1.1), accent: hslToHex(h, s * 0.4, l * 1.3) }; break; } return { ...colors, neutral: hslToHex(h, 10, 50), success: "var(--glass-color-success)", warning: "var(--glass-color-warning)", error: "var(--glass-color-danger)", info: "var(--glass-color-primary)", background: hslToHex(h, 20, 5), surface: hslToHex(h, 15, 10), text: hslToHex(h, 10, 95) }; }, []); const colorScheme = useMemo(() => generateScheme(baseColor, harmony), [baseColor, harmony, generateScheme]); // Update parent when scheme changes React.useEffect(() => { onSchemeChange?.(colorScheme); }, [colorScheme, onSchemeChange]); const handlePredefinedPalette = paletteName => { const paletteColors = predefinedPalettes[paletteName]; setPalette(paletteName); setBaseColor(paletteColors.primary); }; const generateCSSVariables = scheme => { return `:root {\n${Object.entries(scheme).map(([key, value]) => ` --color-${key}: ${value};`).join("\n")}\n}`; }; const generateTailwindConfig = scheme => { return `module.exports = {\n theme: {\n extend: {\n colors: {\n${Object.entries(scheme).map(([key, value]) => ` ${key}: '${value}',`).join("\n")}\n }\n }\n }\n}`; }; const exportScheme = format => { let content = ""; let filename = ""; switch (format) { case "css": content = generateCSSVariables(colorScheme); filename = "color-scheme.css"; break; case "json": content = JSON.stringify(colorScheme, null, 2); filename = "color-scheme.json"; break; case "tailwind": content = generateTailwindConfig(colorScheme); filename = "tailwind.config.js"; break; } // Create download const blob = new Blob([content], { type: "text/plain" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); onExport?.(colorScheme, format); }; return jsxs("div", { "data-glass-component": true, className: `space-y-6 ${className}`, children: [jsxs(OptimizedGlassCore, { className: "glass-p-6", intensity: "medium", elevation: "level1", children: [jsx("h3", { className: 'glass-text-lg font-semibold text-primary mb-4', children: "Base Color" }), jsxs("div", { className: 'glass-grid glass-grid-cols-1 md:grid-cols-2 glass-gap-6', children: [jsxs("div", { className: "glass-gap-4", children: [jsxs("div", { className: "glass-flex glass-items-center glass-gap-4", children: [jsx("input", { type: "color", value: baseColor, onChange: e => setBaseColor(e.target.value), className: 'w-16 h-16 glass-radius-lg glass-border-2 glass-border-white/20 cursor-pointer' }), jsxs("div", { children: [jsx("label", { className: 'block glass-text-sm text-primary/70 mb-1', children: "Hex Color" }), jsx("input", { type: "text", value: baseColor, onChange: e => setBaseColor(e.target.value), className: 'glass-px-3 glass-py-2 glass-surface-subtle/10 glass-border glass-border-white/20 glass-radius-md text-primary placeholder-white/50 focus:outline-none focus:border-white/40', placeholder: "#0066cc" })] })] }), jsxs("div", { children: [jsx("label", { className: 'block glass-text-sm text-primary/70 mb-2', children: "Quick Palettes" }), jsx("div", { className: "glass-flex glass-flex-wrap glass-gap-2", children: Object.entries(predefinedPalettes).map(([name, colors]) => jsx("button", { onClick: e => handlePredefinedPalette(name), className: `glass-px-3 glass-py-2 glass-radius-md glass-text-sm font-medium transition-colors ${palette === name ? "bg-white/20 glass-text-primary" : "bg-white/10 glass-text-primary/70 hover:bg-white/15"}`, children: name.charAt(0).toUpperCase() + name.slice(1) }, name)) })] })] }), jsx("div", { className: "glass-gap-4", children: jsxs("div", { children: [jsx("label", { className: 'block glass-text-sm text-primary/70 mb-2', children: "Color Harmony" }), jsx("div", { className: "glass-grid glass-grid-cols-2 glass-gap-2", children: [{ value: "analogous", label: "Analogous" }, { value: "complementary", label: "Complementary" }, { value: "triadic", label: "Triadic" }, { value: "monochromatic", label: "Monochromatic" }].map(({ value, label }) => jsx("button", { onClick: e => setHarmony(value), className: `glass-px-3 glass-py-2 glass-radius-md glass-text-sm font-medium transition-colors ${harmony === value ? "bg-white/20 glass-text-primary" : "bg-white/10 glass-text-primary/70 hover:bg-white/15"}`, children: label }, value)) })] }) })] })] }), jsxs(OptimizedGlassCore, { className: "glass-p-6", intensity: "medium", elevation: "level1", children: [jsx("h3", { className: 'glass-text-lg font-semibold text-primary mb-4', children: "Color Scheme Preview" }), jsx("div", { className: 'glass-grid glass-grid-cols-2 md:grid-cols-4 glass-gap-4', children: Object.entries(colorScheme).map(([key, color]) => jsxs("div", { className: "glass-gap-2", children: [jsx("div", { className: 'glass-w-full h-16 glass-radius-lg glass-border glass-border-white/20', style: { backgroundColor: color } }), jsxs("div", { className: 'text-center', children: [jsx("div", { className: 'glass-text-xs text-primary/70 capitalize', children: key }), jsx("div", { className: 'glass-text-xs text-primary/50 font-mono', children: color })] })] }, key)) })] }), jsxs(OptimizedGlassCore, { className: "glass-p-6", intensity: "medium", elevation: "level1", children: [jsx("h3", { className: 'glass-text-lg font-semibold text-primary mb-4', children: "Export Options" }), jsxs("div", { className: "glass-flex glass-flex-wrap glass-gap-3", children: [generateCSS && jsx("button", { onClick: e => exportScheme("css"), className: 'glass-px-4 glass-py-2 glass-surface-blue/20 glass-text-secondary glass-radius-md hover:glass-surface-blue/30 transition-colors', children: "Export CSS Variables" }), generateTailwind && jsx("button", { onClick: e => exportScheme("tailwind"), className: 'glass-px-4 glass-py-2 glass-surface-green/20 glass-text-secondary glass-radius-md hover:glass-surface-green/30 transition-colors', children: "Export Tailwind Config" }), jsx("button", { onClick: e => exportScheme("json"), className: 'glass-px-4 glass-py-2 glass-surface-primary/20 glass-text-secondary glass-radius-md hover:glass-surface-primary/30 transition-colors', children: "Export JSON" })] }), generateCSS && jsxs("div", { className: "glass-mt-4", children: [jsx("label", { className: 'block glass-text-sm text-primary/70 mb-2', children: "CSS Variables Preview" }), jsx("pre", { className: 'glass-p-3 glass-surface-dark/20 glass-radius-md glass-text-xs text-primary/80 overflow-x-auto', children: jsx("code", { children: generateCSSVariables(colorScheme) }) })] })] })] }); }; export { GlassColorSchemeGenerator }; //# sourceMappingURL=GlassColorSchemeGenerator.js.map