Theme System
Veltix provides a comprehensive theme system that allows you to customize the appearance of your dashboards with consistent styling across all components.
Overview
The theme system includes:
- Light & Dark Themes: Built-in theme switching
- Custom Color Palettes: Define your own color schemes
- Typography: Customizable fonts and text styling
- Component Styling: Consistent component appearance
- Responsive Design: Theme-aware responsive layouts
Theme Structure
Theme Configuration
interface Theme {
name: string;
colors: ColorPalette;
typography: TypographyConfig;
spacing: SpacingConfig;
borderRadius: BorderRadiusConfig;
shadows: ShadowConfig;
components: ComponentTheme;
}Color Palette
interface ColorPalette {
primary: {
50: string;
100: string;
200: string;
300: string;
400: string;
500: string;
600: string;
700: string;
800: string;
900: string;
};
secondary: ColorScale;
accent: ColorScale;
neutral: ColorScale;
success: ColorScale;
warning: ColorScale;
error: ColorScale;
background: {
primary: string;
secondary: string;
tertiary: string;
};
text: {
primary: string;
secondary: string;
tertiary: string;
inverse: string;
};
}Built-in Themes
Light Theme
The default light theme with clean, professional styling.
const lightTheme: Theme = {
name: 'light',
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a'
},
background: {
primary: '#ffffff',
secondary: '#f8fafc',
tertiary: '#f1f5f9'
},
text: {
primary: '#0f172a',
secondary: '#475569',
tertiary: '#64748b',
inverse: '#ffffff'
}
}
};Dark Theme
A modern dark theme for low-light environments.
const darkTheme: Theme = {
name: 'dark',
colors: {
primary: {
50: '#0f172a',
100: '#1e293b',
200: '#334155',
300: '#475569',
400: '#64748b',
500: '#94a3b8',
600: '#cbd5e1',
700: '#e2e8f0',
800: '#f1f5f9',
900: '#f8fafc'
},
background: {
primary: '#0f172a',
secondary: '#1e293b',
tertiary: '#334155'
},
text: {
primary: '#f8fafc',
secondary: '#cbd5e1',
tertiary: '#94a3b8',
inverse: '#0f172a'
}
}
};Theme Switching
Automatic Theme Detection
import { useTheme } from '@veltix/ui';
function Dashboard() {
const { theme, setTheme } = useTheme();
return (
<div className={`theme-${theme}`}>
<button onClick={() => setTheme('light')}>Light</button>
<button onClick={() => setTheme('dark')}>Dark</button>
<button onClick={() => setTheme('auto')}>Auto</button>
</div>
);
}System Theme Detection
// Automatically detect system theme
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)');
systemTheme.addEventListener('change', (e) => {
setTheme(e.matches ? 'dark' : 'light');
});Custom Themes
Creating Custom Themes
const customTheme: Theme = {
name: 'corporate',
colors: {
primary: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e'
},
background: {
primary: '#ffffff',
secondary: '#f8fafc',
tertiary: '#f1f5f9'
},
text: {
primary: '#0f172a',
secondary: '#475569',
tertiary: '#64748b',
inverse: '#ffffff'
}
},
typography: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace']
},
fontSize: {
xs: '0.75rem',
sm: '0.875rem',
base: '1rem',
lg: '1.125rem',
xl: '1.25rem',
'2xl': '1.5rem',
'3xl': '1.875rem',
'4xl': '2.25rem'
}
}
};Theme Registration
import { registerTheme } from '@veltix/ui';
// Register custom theme
registerTheme('corporate', customTheme);
// Use the theme
const { setTheme } = useTheme();
setTheme('corporate');Color Palettes
Primary Colors
// Blue palette
const bluePalette = {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a'
};
// Green palette
const greenPalette = {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d'
};Semantic Colors
const semanticColors = {
success: {
50: '#f0fdf4',
100: '#dcfce7',
500: '#22c55e',
600: '#16a34a',
700: '#15803d'
},
warning: {
50: '#fffbeb',
100: '#fef3c7',
500: '#f59e0b',
600: '#d97706',
700: '#b45309'
},
error: {
50: '#fef2f2',
100: '#fee2e2',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c'
}
};Typography
Font Configuration
const typographyConfig = {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
serif: ['Georgia', 'serif'],
mono: ['JetBrains Mono', 'monospace']
},
fontSize: {
xs: '0.75rem',
sm: '0.875rem',
base: '1rem',
lg: '1.125rem',
xl: '1.25rem',
'2xl': '1.5rem',
'3xl': '1.875rem',
'4xl': '2.25rem',
'5xl': '3rem'
},
fontWeight: {
light: '300',
normal: '400',
medium: '500',
semibold: '600',
bold: '700',
extrabold: '800'
},
lineHeight: {
tight: '1.25',
normal: '1.5',
relaxed: '1.75'
}
};Text Styles
const textStyles = {
heading: {
fontFamily: 'sans',
fontWeight: 'bold',
lineHeight: 'tight'
},
body: {
fontFamily: 'sans',
fontWeight: 'normal',
lineHeight: 'normal'
},
caption: {
fontFamily: 'sans',
fontWeight: 'medium',
fontSize: 'sm',
lineHeight: 'normal'
}
};Component Theming
Chart Components
const chartTheme = {
colors: {
axis: '#64748b',
grid: '#e2e8f0',
text: '#475569'
},
font: {
family: 'Inter',
size: '12px'
},
animation: {
duration: 300,
easing: 'ease-in-out'
}
};UI Components
const uiTheme = {
button: {
primary: {
backgroundColor: 'var(--color-primary-500)',
color: 'var(--color-white)',
border: 'none',
borderRadius: '6px',
padding: '8px 16px'
},
secondary: {
backgroundColor: 'transparent',
color: 'var(--color-primary-500)',
border: '1px solid var(--color-primary-500)',
borderRadius: '6px',
padding: '8px 16px'
}
},
card: {
backgroundColor: 'var(--color-background-secondary)',
borderRadius: '8px',
padding: '16px',
boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)'
}
};CSS Variables
Theme Variables
:root {
/* Primary colors */
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-500: #3b82f6;
--color-primary-900: #1e3a8a;
/* Background colors */
--color-background-primary: #ffffff;
--color-background-secondary: #f8fafc;
--color-background-tertiary: #f1f5f9;
/* Text colors */
--color-text-primary: #0f172a;
--color-text-secondary: #475569;
--color-text-tertiary: #64748b;
/* Spacing */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
/* Border radius */
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 12px;
}Dark Theme Variables
[data-theme="dark"] {
--color-background-primary: #0f172a;
--color-background-secondary: #1e293b;
--color-background-tertiary: #334155;
--color-text-primary: #f8fafc;
--color-text-secondary: #cbd5e1;
--color-text-tertiary: #94a3b8;
}Theme Utilities
Theme Hook
import { useTheme } from '@veltix/ui';
function ThemeToggle() {
const { theme, setTheme, isDark } = useTheme();
return (
<button
onClick={() => setTheme(isDark ? 'light' : 'dark')}
className="theme-toggle"
>
{isDark ? '☀️' : '🌙'}
</button>
);
}Theme Provider
import { ThemeProvider } from '@veltix/ui';
function App() {
return (
<ThemeProvider
defaultTheme="light"
themes={['light', 'dark', 'corporate']}
storageKey="veltix-theme"
>
<Dashboard />
</ThemeProvider>
);
}Best Practices
1. Color Usage
- Use semantic colors for consistent meaning
- Ensure sufficient contrast ratios
- Test themes in different lighting conditions
- Consider color blindness accessibility
2. Typography
- Choose readable font families
- Maintain consistent font sizes
- Use appropriate line heights
- Consider mobile readability
3. Component Design
- Design components to work with any theme
- Use CSS variables for dynamic theming
- Test components in all themes
- Maintain visual hierarchy
4. Performance
- Minimize theme switching overhead
- Use CSS variables for efficient updates
- Cache theme configurations
- Optimize theme assets
Troubleshooting
Common Issues
Theme not switching
- Check theme registration
- Verify CSS variable definitions
- Ensure proper theme provider setup
- Check browser storage permissions
Colors not updating
- Verify CSS variable usage
- Check theme configuration
- Ensure proper CSS specificity
- Test in different browsers
Performance issues
- Optimize theme switching
- Use efficient CSS variables
- Minimize theme complexity
- Implement proper caching
Last updated on