muspe-cli
Version:
MusPE Advanced Framework v2.1.3 - Mobile User-friendly Simple Progressive Engine with Enhanced CLI Tools, Specialized E-Commerce Templates, Material Design 3, Progressive Enhancement, Mobile Optimizations, Performance Analysis, and Enterprise-Grade Develo
375 lines (337 loc) • 10.2 kB
JavaScript
// MusPE UI Enterprise - Advanced Theme Engine
class MusPEThemeEngine {
constructor() {
this.themes = new Map();
this.currentTheme = 'default';
this.customProperties = new Map();
this.breakpoints = {
xs: '475px',
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
'2xl': '1536px'
};
this.init();
}
init() {
this.registerDefaultThemes();
this.setupThemeWatcher();
this.injectThemeEngine();
}
registerDefaultThemes() {
// Default Light Theme
this.registerTheme('light', {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a'
},
gray: {
50: '#f9fafb',
100: '#f3f4f6',
200: '#e5e7eb',
300: '#d1d5db',
400: '#9ca3af',
500: '#6b7280',
600: '#4b5563',
700: '#374151',
800: '#1f2937',
900: '#111827'
},
success: {
50: '#ecfdf5',
500: '#10b981',
600: '#059669'
},
warning: {
50: '#fffbeb',
500: '#f59e0b',
600: '#d97706'
},
error: {
50: '#fef2f2',
500: '#ef4444',
600: '#dc2626'
}
},
typography: {
fontFamily: {
sans: ['-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'sans-serif'],
mono: ['SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'monospace']
},
fontSize: {
xs: ['0.75rem', { lineHeight: '1rem' }],
sm: ['0.875rem', { lineHeight: '1.25rem' }],
base: ['1rem', { lineHeight: '1.5rem' }],
lg: ['1.125rem', { lineHeight: '1.75rem' }],
xl: ['1.25rem', { lineHeight: '1.75rem' }],
'2xl': ['1.5rem', { lineHeight: '2rem' }],
'3xl': ['1.875rem', { lineHeight: '2.25rem' }],
'4xl': ['2.25rem', { lineHeight: '2.5rem' }]
},
fontWeight: {
normal: '400',
medium: '500',
semibold: '600',
bold: '700',
extrabold: '800'
}
},
spacing: {
0: '0px',
1: '0.25rem',
2: '0.5rem',
3: '0.75rem',
4: '1rem',
5: '1.25rem',
6: '1.5rem',
8: '2rem',
10: '2.5rem',
12: '3rem',
16: '4rem',
20: '5rem'
},
borderRadius: {
none: '0',
sm: '0.125rem',
default: '0.25rem',
md: '0.375rem',
lg: '0.5rem',
xl: '0.75rem',
'2xl': '1rem',
'3xl': '1.5rem',
full: '9999px'
},
shadows: {
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)'
},
animation: {
duration: {
fast: '150ms',
normal: '250ms',
slow: '350ms',
slower: '500ms'
},
easing: {
linear: 'linear',
ease: 'ease',
'ease-in': 'ease-in',
'ease-out': 'ease-out',
'ease-in-out': 'ease-in-out',
spring: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
}
}
});
// Dark Theme
this.registerTheme('dark', {
colors: {
primary: {
50: '#1e3a8a',
100: '#1e40af',
200: '#1d4ed8',
300: '#2563eb',
400: '#3b82f6',
500: '#60a5fa',
600: '#93c5fd',
700: '#bfdbfe',
800: '#dbeafe',
900: '#eff6ff'
},
gray: {
50: '#111827',
100: '#1f2937',
200: '#374151',
300: '#4b5563',
400: '#6b7280',
500: '#9ca3af',
600: '#d1d5db',
700: '#e5e7eb',
800: '#f3f4f6',
900: '#f9fafb'
}
// Inherit other properties from light theme
}
});
// High Contrast Theme
this.registerTheme('high-contrast', {
colors: {
primary: {
500: '#0000ff',
600: '#0000cc'
},
gray: {
50: '#ffffff',
900: '#000000'
}
}
});
}
registerTheme(name, config) {
this.themes.set(name, config);
this.generateThemeCSS(name, config);
}
generateThemeCSS(name, config) {
const css = this.buildThemeCSS(config);
// Create or update theme stylesheet
let styleSheet = document.querySelector(`#muspe-theme-${name}`);
if (!styleSheet) {
styleSheet = document.createElement('style');
styleSheet.id = `muspe-theme-${name}`;
document.head.appendChild(styleSheet);
}
const themeSelector = name === 'default' ? ':root' : `[data-theme="${name}"]`;
styleSheet.textContent = `${themeSelector} { ${css} }`;
}
buildThemeCSS(config) {
let css = '';
// Colors
if (config.colors) {
Object.entries(config.colors).forEach(([colorName, colorValues]) => {
if (typeof colorValues === 'object') {
Object.entries(colorValues).forEach(([shade, value]) => {
css += `--muspe-${colorName}-${shade}: ${value};\n`;
});
} else {
css += `--muspe-${colorName}: ${colorValues};\n`;
}
});
}
// Typography
if (config.typography) {
const { fontFamily, fontSize, fontWeight } = config.typography;
if (fontFamily) {
Object.entries(fontFamily).forEach(([name, fonts]) => {
css += `--muspe-font-${name}: ${Array.isArray(fonts) ? fonts.join(', ') : fonts};\n`;
});
}
if (fontSize) {
Object.entries(fontSize).forEach(([size, value]) => {
const [sizeValue, options] = Array.isArray(value) ? value : [value, {}];
css += `--muspe-text-${size}: ${sizeValue};\n`;
if (options.lineHeight) {
css += `--muspe-leading-${size}: ${options.lineHeight};\n`;
}
});
}
if (fontWeight) {
Object.entries(fontWeight).forEach(([weight, value]) => {
css += `--muspe-font-${weight}: ${value};\n`;
});
}
}
// Spacing
if (config.spacing) {
Object.entries(config.spacing).forEach(([key, value]) => {
css += `--muspe-space-${key}: ${value};\n`;
});
}
// Border Radius
if (config.borderRadius) {
Object.entries(config.borderRadius).forEach(([key, value]) => {
css += `--muspe-radius-${key}: ${value};\n`;
});
}
// Shadows
if (config.shadows) {
Object.entries(config.shadows).forEach(([key, value]) => {
css += `--muspe-shadow-${key}: ${value};\n`;
});
}
// Animation
if (config.animation) {
const { duration, easing } = config.animation;
if (duration) {
Object.entries(duration).forEach(([key, value]) => {
css += `--muspe-duration-${key}: ${value};\n`;
});
}
if (easing) {
Object.entries(easing).forEach(([key, value]) => {
css += `--muspe-ease-${key}: ${value};\n`;
});
}
}
return css;
}
setTheme(themeName) {
if (!this.themes.has(themeName)) {
console.warn(`Theme "${themeName}" not found`);
return;
}
this.currentTheme = themeName;
document.documentElement.setAttribute('data-theme', themeName);
// Store preference
localStorage.setItem('muspe-theme', themeName);
// Emit theme change event
window.dispatchEvent(new CustomEvent('muspe:theme-changed', {
detail: { theme: themeName }
}));
}
setupThemeWatcher() {
// Watch for system theme changes
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleSystemThemeChange = () => {
if (!localStorage.getItem('muspe-theme')) {
this.setTheme(mediaQuery.matches ? 'dark' : 'light');
}
};
mediaQuery.addEventListener('change', handleSystemThemeChange);
// Set initial theme
const savedTheme = localStorage.getItem('muspe-theme');
if (savedTheme && this.themes.has(savedTheme)) {
this.setTheme(savedTheme);
} else {
this.setTheme(mediaQuery.matches ? 'dark' : 'light');
}
}
injectThemeEngine() {
// Add theme toggle utilities to global scope
window.MusPETheme = {
setTheme: (theme) => this.setTheme(theme),
getTheme: () => this.currentTheme,
getAvailableThemes: () => Array.from(this.themes.keys()),
registerTheme: (name, config) => this.registerTheme(name, config),
toggleDarkMode: () => {
const isDark = this.currentTheme === 'dark';
this.setTheme(isDark ? 'light' : 'dark');
}
};
}
// Advanced theme utilities
createCustomTheme(name, baseTheme = 'light', overrides = {}) {
const base = this.themes.get(baseTheme) || this.themes.get('light');
const merged = this.deepMerge(base, overrides);
this.registerTheme(name, merged);
return merged;
}
deepMerge(target, source) {
const result = { ...target };
for (const key in source) {
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
result[key] = this.deepMerge(result[key] || {}, source[key]);
} else {
result[key] = source[key];
}
}
return result;
}
}
// Initialize theme engine
if (typeof window !== 'undefined') {
window.muspeThemeEngine = new MusPEThemeEngine();
}
export default MusPEThemeEngine;