UNPKG

aura-glass

Version:

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

314 lines (312 loc) 9.41 kB
// Theme helper functions const createGlassTheme = (baseTheme = {}) => { const defaultColors = { primary: 'var(--glass-color-primary)', secondary: 'var(--glass-gray-500)', accent: '#8b5cf6', background: '#0b1220', surface: 'rgba(255,255,255,0.06)', text: 'rgba(255,255,255,0.92)', textSecondary: 'var(--glass-text-secondary)', border: 'rgba(255,255,255,0.16)', error: 'var(--glass-color-danger)', warning: 'var(--glass-color-warning)', success: 'var(--glass-color-success)', info: '#0ea5e9' }; return { colors: { ...defaultColors, ...(baseTheme.colors || {}) }, spacing: { xs: '0.25rem', sm: '0.5rem', md: '1rem', lg: '1.5rem', xl: '2rem', xxl: '3rem', ...baseTheme.spacing }, typography: { fontFamily: 'system-ui, -apple-system, sans-serif', fontSize: { xs: '0.75rem', sm: '0.875rem', md: '1rem', lg: '1.125rem', xl: '1.25rem', xxl: '1.5rem' }, fontWeight: { light: 300, normal: 400, medium: 500, semibold: 600, bold: 700 }, lineHeight: { tight: 1.25, normal: 1.5, relaxed: 1.75 }, ...baseTheme.typography }, borderRadius: '12px', boxShadow: '0 8px 32px rgba(0, 0, 0, 0.18)', // Use tokenized backdrop via CSS variables on surfaces backdropFilter: 'var(--glass-backdrop-blur)', transition: 'all 0.2s ease', ...baseTheme }; }; const getThemeValue = (theme, path, fallback) => { const keys = path.split('.'); let value = theme; for (const key of keys) { if (value && typeof value === 'object' && key in value) { value = value[key]; } else { return fallback; } } return value; }; const createThemeVariant = (baseTheme, overrides) => { return { ...baseTheme, ...overrides, colors: { ...baseTheme.colors, ...overrides.colors }, spacing: { ...baseTheme.spacing, ...overrides.spacing }, typography: { ...baseTheme.typography, ...overrides.typography, fontSize: { ...baseTheme.typography.fontSize, ...overrides.typography?.fontSize }, fontWeight: { ...baseTheme.typography.fontWeight, ...overrides.typography?.fontWeight }, lineHeight: { ...baseTheme.typography.lineHeight, ...overrides.typography?.lineHeight } } }; }; // Color manipulation utilities const adjustColorOpacity = (color, opacity) => { // Handle hex colors if (color.startsWith('#')) { const hex = color.replace('#', ''); const r = parseInt(hex.substr(0, 2), 16); const g = parseInt(hex.substr(2, 2), 16); const b = parseInt(hex.substr(4, 2), 16); return `rgba(${r}, ${g}, ${b}, ${opacity})`; } // Handle rgba colors if (color.startsWith('rgba')) { const parts = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\)/); if (parts) { return `rgba(${parts[1]}, ${parts[2]}, ${parts[3]}, ${opacity})`; } } // Handle rgb colors if (color.startsWith('rgb')) { const parts = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/); if (parts) { return `rgba(${parts[1]}, ${parts[2]}, ${parts[3]}, ${opacity})`; } } return color; }; const lightenColor = (color, amount) => { // Simple color lightening - in a real implementation you'd use a proper color library if (color.startsWith('#')) { const hex = color.replace('#', ''); const r = Math.min(255, parseInt(hex.substr(0, 2), 16) + amount); const g = Math.min(255, parseInt(hex.substr(2, 2), 16) + amount); const b = Math.min(255, parseInt(hex.substr(4, 2), 16) + amount); return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`; } return color; }; const darkenColor = (color, amount) => { if (color.startsWith('#')) { const hex = color.replace('#', ''); const r = Math.max(0, parseInt(hex.substr(0, 2), 16) - amount); const g = Math.max(0, parseInt(hex.substr(2, 2), 16) - amount); const b = Math.max(0, parseInt(hex.substr(4, 2), 16) - amount); return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`; } return color; }; // Spacing utilities const createSpacingScale = (base = 4) => { return { xs: `${base}px`, sm: `${base * 2}px`, md: `${base * 4}px`, lg: `${base * 6}px`, xl: `${base * 8}px`, xxl: `${base * 12}px` }; }; const getSpacingValue = (spacing, size) => { return spacing[size]; }; // Typography utilities const createTypographyScale = (baseSize = 16, scale = 1.25) => { return { xs: `${baseSize / scale ** 2}px`, sm: `${baseSize / scale}px`, md: `${baseSize}px`, lg: `${baseSize * scale}px`, xl: `${baseSize * scale ** 2}px`, xxl: `${baseSize * scale ** 3}px` }; }; const createFontWeightScale = () => { return { light: 300, normal: 400, medium: 500, semibold: 600, bold: 700 }; }; // Theme validation const validateTheme = theme => { const errors = []; if (!theme.colors) { errors.push('Theme must include colors'); } else { const requiredColors = ['primary', 'background', 'text']; requiredColors.forEach(color => { if (!theme.colors[color]) { errors.push(`Theme colors must include ${color}`); } }); } if (!theme.spacing) { errors.push('Theme must include spacing'); } if (!theme.typography) { errors.push('Theme must include typography'); } return errors; }; // CSS custom properties generation const generateThemeCSSVariables = theme => { const variables = []; // Colors Object.entries(theme.colors).forEach(([key, value]) => { variables.push(` --color-${key}: ${value};`); }); // Spacing Object.entries(theme.spacing).forEach(([key, value]) => { variables.push(` --spacing-${key}: ${value};`); }); // Typography Object.entries(theme.typography.fontSize).forEach(([key, value]) => { variables.push(` --font-size-${key}: ${value};`); }); Object.entries(theme.typography.fontWeight).forEach(([key, value]) => { variables.push(` --font-weight-${key}: ${value};`); }); Object.entries(theme.typography.lineHeight).forEach(([key, value]) => { variables.push(` --line-height-${key}: ${value};`); }); variables.push(` --font-family: ${theme.typography.fontFamily};`); variables.push(` --border-radius: ${theme.borderRadius};`); variables.push(` --box-shadow: ${theme.boxShadow};`); variables.push(` --backdrop-filter: ${theme.backdropFilter};`); variables.push(` --transition: ${theme.transition};`); return `:root {\n${variables.join('\n')}\n}`; }; // Theme merging utilities const mergeThemes = (...themes) => { const merged = themes.reduce((acc, theme) => { return { ...acc, ...theme, colors: { ...acc.colors, ...theme.colors }, spacing: { ...acc.spacing, ...theme.spacing }, typography: { ...acc.typography, ...theme.typography, fontSize: { ...acc.typography?.fontSize, ...theme.typography?.fontSize }, fontWeight: { ...acc.typography?.fontWeight, ...theme.typography?.fontWeight }, lineHeight: { ...acc.typography?.lineHeight, ...theme.typography?.lineHeight } } }; }, {}); // Validate and provide defaults const errors = validateTheme(merged); if (errors.length > 0) { console.warn('Theme validation errors:', errors); } return createGlassTheme(merged); }; // Theme preset generators const createDarkTheme = () => { return createGlassTheme({ colors: { primary: 'var(--glass-color-primary-light)', secondary: 'var(--glass-gray-400)', accent: '#a78bfa', background: '/* Use createGlassStyle({ intent: "primary", elevation: "level2" }) */', surface: 'rgba(31, 41, 55, 0.8)', text: 'var(--glass-gray-50)', textSecondary: 'rgba(156, 163, 175, 0.8)', border: 'rgba(75, 85, 99, 0.3)', error: 'var(--glass-color-danger-light)', warning: 'var(--glass-color-warning-light)', success: 'var(--glass-color-success-light)', info: 'var(--glass-color-primary-light)' } }); }; const createLightTheme = () => { return createGlassTheme({ colors: { primary: 'var(--glass-color-primary)', secondary: 'var(--glass-gray-500)', accent: '#8b5cf6', background: '/* Use createGlassStyle({ intent: "neutral", elevation: "level2" }) */', surface: 'rgba(249, 250, 251, 0.8)', text: 'var(--glass-gray-900)', textSecondary: 'rgba(75, 85, 99, 0.7)', border: 'rgba(229, 231, 235, 0.5)', error: 'var(--glass-color-danger)', warning: 'var(--glass-color-warning)', success: 'var(--glass-color-success)', info: 'var(--glass-color-primary)' } }); }; export { adjustColorOpacity, createDarkTheme, createFontWeightScale, createGlassTheme, createLightTheme, createSpacingScale, createThemeVariant, createTypographyScale, darkenColor, generateThemeCSSVariables, getSpacingValue, getThemeValue, lightenColor, mergeThemes, validateTheme }; //# sourceMappingURL=themeHelpers.js.map