UNPKG

aura-glass

Version:

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

291 lines (288 loc) 11.9 kB
'use client'; import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import { cn } from '../../lib/utilsComprehensive.js'; import { Palette, Settings, Check, Eye, Save, Sun, Moon, Monitor } from 'lucide-react'; import { useState, useCallback } from 'react'; import '../../primitives/GlassCore.js'; import '../../primitives/glass/GlassAdvanced.js'; import '../../primitives/OptimizedGlassCore.js'; import '../../primitives/glass/OptimizedGlassAdvanced.js'; import '../../primitives/MotionNative.js'; import { MotionFramer } from '../../primitives/motion/MotionFramer.js'; import { GlassButton } from '../button/GlassButton.js'; import '../button/GlassFab.js'; import '../button/GlassMagneticButton.js'; import { CardHeader, CardTitle, CardContent } from '../card/index.js'; import { GlassCard } from '../card/GlassCard.js'; /** * GlassThemeSwitcher component * Theme switching interface with preview and customization */ const GlassThemeSwitcher = ({ currentTheme = "light", themes = [], enableSystemTheme = true, showPreview = true, showCustomOption = false, compact = false, onThemeChange, onCustomThemeSave, className, ...props }) => { const customThemes = Array.isArray(themes) ? themes : []; const [selectedTheme, setSelectedTheme] = useState(currentTheme); const [showCustomizer, setShowCustomizer] = useState(false); const [customColors, setCustomColors] = useState({ primary: "var(--glass-color-primary)", secondary: "#64748b", background: "var(--glass-white)", text: "var(--glass-black)" }); // System theme options const systemThemes = [{ id: "light", name: "Light", icon: Sun, preview: { primary: "var(--glass-color-primary)", secondary: "#64748b", background: "var(--glass-white)", text: "var(--glass-black)" } }, { id: "dark", name: "Dark", icon: Moon, preview: { primary: "var(--glass-color-primary-light)", secondary: "#94a3b8", background: "#0f172a", text: "var(--glass-white)" } }, ...(enableSystemTheme ? [{ id: "system", name: "System", icon: Monitor, preview: { primary: "#8b5cf6", secondary: "#64748b", background: "#f8fafc", text: "#1e293b" } }] : [])]; // Handle theme selection const handleThemeSelect = useCallback(themeId => { setSelectedTheme(themeId); onThemeChange?.(themeId); }, [onThemeChange]); // Handle custom color change const handleCustomColorChange = useCallback((colorKey, value) => { setCustomColors(prev => ({ ...prev, [colorKey]: value })); }, []); // Save custom theme const handleSaveCustomTheme = useCallback(() => { onCustomThemeSave?.(customColors); setShowCustomizer(false); }, [customColors, onCustomThemeSave]); // Get theme preview style const getPreviewStyle = useCallback(preview => ({ backgroundColor: preview.background, color: preview.text, "--preview-primary": preview.primary, "--preview-secondary": preview.secondary }), []); return jsx(MotionFramer, { "data-glass-component": true, preset: "fadeIn", className: "glass-w-full", children: jsxs(GlassCard, { className: cn("overflow-hidden", className), ...props, children: [jsx(CardHeader, { className: 'pb-3', children: jsxs("div", { className: "glass-flex glass-items-center glass-justify-between", children: [jsxs(CardTitle, { className: 'text-primary glass-text-lg font-semibold glass-flex glass-items-center glass-gap-2', children: [jsx(Palette, { className: 'w-5 h-5' }), "Theme"] }), !compact && showCustomOption && jsx(GlassButton, { variant: "ghost", size: "sm", onClick: e => setShowCustomizer(!showCustomizer), className: "glass-p-2 glass-focus glass-touch-target glass-contrast-guard", children: jsx(Settings, { className: 'w-4 h-4' }) })] }) }), jsxs(CardContent, { className: 'pt-0', children: [jsx("div", { className: cn("grid glass-gap-3 mb-6", compact ? "grid-cols-1" : "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"), children: systemThemes.map(theme => { const IconComponent = theme.icon; const isSelected = selectedTheme === theme.id; return jsxs(MotionFramer, { preset: "scaleIn", className: cn("relative glass-p-4 glass-radius-lg cursor-pointer transition-all duration-200", "hover:scale-[1.02] hover:shadow-lg", "glass-focus glass-touch-target glass-contrast-guard", isSelected ? "ring-2 ring-primary bg-primary/20" : "ring-1 ring-white/10 bg-white/5 hover:ring-white/30"), onClick: e => handleThemeSelect(theme.id), children: [showPreview && jsx("div", { className: 'glass-w-full h-16 glass-radius-md mb-3 ring-1 ring-white/10', style: getPreviewStyle(theme.preview), children: jsxs("div", { className: "glass-p-2 glass-gap-1", children: [jsx("div", { className: 'h-2 glass-radius-md', style: { backgroundColor: "var(--preview-primary)" } }), jsx("div", { className: 'h-1 glass-radius-md', style: { backgroundColor: "var(--preview-secondary)" } })] }) }), jsxs("div", { className: "glass-flex glass-items-center glass-justify-between", children: [jsxs("div", { className: "glass-flex glass-items-center glass-gap-2", children: [jsx(IconComponent, { className: 'w-4 h-4' }), jsx("span", { className: 'font-medium glass-text-sm', children: theme.name })] }), isSelected && jsx(Check, { className: 'w-4 h-4 text-primary' })] })] }, theme.id); }) }), customThemes.length > 0 && jsxs(Fragment, { children: [jsx("div", { className: 'mb-3', children: jsx("h4", { className: 'text-primary/80 glass-text-sm font-medium', children: "Custom Themes" }) }), jsx("div", { className: cn("grid glass-gap-3", compact ? "grid-cols-1" : "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"), children: customThemes.map(theme => { const isSelected = selectedTheme === theme.id; return jsxs(MotionFramer, { preset: "scaleIn", className: cn("relative glass-p-4 glass-radius-lg cursor-pointer transition-all duration-200", "hover:scale-[1.02] hover:shadow-lg", "glass-focus glass-touch-target glass-contrast-guard", isSelected ? "ring-2 ring-primary bg-primary/20" : "ring-1 ring-white/10 bg-white/5 hover:ring-white/30"), onClick: e => handleThemeSelect(theme.id), children: [showPreview && jsx("div", { className: 'glass-w-full h-16 glass-radius-md mb-3 glass-border glass-border-white/20', style: getPreviewStyle(theme.preview), children: jsxs("div", { className: "glass-p-2 glass-gap-1", children: [jsx("div", { className: 'h-2 glass-radius-md', style: { backgroundColor: theme.preview.primary } }), jsx("div", { className: 'h-1 glass-radius-md', style: { backgroundColor: theme.preview.secondary } })] }) }), jsxs("div", { className: "glass-flex glass-items-center glass-justify-between", children: [jsx("span", { className: 'font-medium glass-text-sm', children: theme.name }), isSelected && jsx(Check, { className: 'w-4 h-4 text-primary' })] })] }, theme.id); }) })] }), showCustomizer && jsx(MotionFramer, { preset: "slideDown", className: 'mt-6 glass-p-4 glass-surface-subtle/5 glass-radius-lg', children: jsxs("div", { className: "glass-gap-4", children: [jsxs("h4", { className: 'text-primary font-medium glass-flex glass-items-center glass-gap-2', children: [jsx(Eye, { className: 'w-4 h-4' }), "Customize Theme"] }), jsx("div", { className: "glass-grid glass-grid-cols-2 glass-gap-4", children: Object.entries(customColors).map(([key, value]) => jsxs("div", { className: "glass-gap-2", children: [jsx("label", { className: 'text-primary/80 glass-text-sm capitalize', children: key }), jsxs("div", { className: "glass-flex glass-gap-2", children: [jsx("input", { type: "color", value: value, onChange: e => handleCustomColorChange(key, e.target.value), className: 'w-10 h-8 glass-radius-md ring-1 ring-white/10 cursor-pointer glass-focus glass-touch-target glass-contrast-guard' }), jsx("input", { type: "text", value: value, onChange: e => handleCustomColorChange(key, e.target.value), className: 'glass-flex-1 glass-px-3 glass-py-1 glass-surface-subtle/10 ring-1 ring-white/10 glass-radius-md text-primary glass-text-sm focus:outline-none focus:ring-white/30 glass-focus glass-touch-target glass-contrast-guard' })] })] }, key)) }), jsx("div", { className: 'glass-w-full h-20 glass-radius-md ring-1 ring-white/10', style: { backgroundColor: customColors.background, color: customColors.text }, children: jsxs("div", { className: "glass-p-3 glass-gap-2", children: [jsx("div", { className: 'h-3 glass-radius-md', style: { backgroundColor: customColors.primary } }), jsx("div", { className: 'h-2 glass-radius-md', style: { backgroundColor: customColors.secondary } })] }) }), jsxs("div", { className: "glass-flex glass-gap-2", children: [jsxs(GlassButton, { variant: "primary", size: "sm", onClick: handleSaveCustomTheme, className: "glass-flex glass-items-center glass-gap-2", children: [jsx(Save, { className: 'w-4 h-4' }), "Save Theme"] }), jsx(GlassButton, { variant: "ghost", size: "sm", onClick: e => setShowCustomizer(false), children: "Cancel" })] })] }) })] })] }) }); }; export { GlassThemeSwitcher, GlassThemeSwitcher as default }; //# sourceMappingURL=GlassThemeSwitcher.js.map