# Fakemui Theming Guide
Complete guide to theming in Fakemui, including built-in themes, customization, and dynamic theme switching.
## Overview
Fakemui's theming system is based on Material Design 3, providing a comprehensive design token system for consistent, accessible, and customizable user interfaces.
**Key features**:
- 9 built-in themes
- Custom theme creation
- Dynamic theme switching
- Material Design 3 compliance
- Accessibility standards (WCAG AA+)
## Built-in Themes
### Available Themes
| Theme | Description | Use Case |
|-------|-------------|----------|
| **default** | Primary blue (Material Design 3 default) | General applications |
| **light** | Light mode optimization | Daytime/bright environments |
| **dark** | Dark mode optimization | Nighttime/reduced eye strain |
| **ocean** | Ocean blue with teal accents | Calm, professional applications |
| **forest** | Green with natural tones | Environmental/wellness apps |
| **sunset** | Warm orange/red tones | Creative/vibrant applications |
| **lavender** | Purple with soft tones | Design-focused applications |
| **midnight** | Deep blue with dark background | Night mode preference |
| **rose** | Pink/rose tones | Fashion/lifestyle applications |
### Theme Structure
Each theme defines:
```typescript
interface Theme {
palette: {
// Primary colors
primary: { main, light, dark, contrastText }
secondary: { main, light, dark, contrastText }
error: { main, light, dark, contrastText }
warning: { main, light, dark, contrastText }
info: { main, light, dark, contrastText }
success: { main, light, dark, contrastText }
// Neutral colors
background: { default, paper }
text: { primary, secondary, disabled, hint }
divider: color
action: { active, hover, selected, disabled }
// Elevation colors (5 levels)
surface1, surface2, surface3, surface4, surface5
}
typography: {
fontFamily: string
fontSize: number
fontWeightLight: number
fontWeightRegular: number
fontWeightMedium: number
fontWeightBold: number
// Typography variants
h1, h2, h3, h4, h5, h6: TypographyOptions
body1, body2: TypographyOptions
button, caption: TypographyOptions
}
spacing: (multiplier: number) => number
shape: {
borderRadius: number
}
shadows: string[]
transitions: {
duration: { shortest, shorter, standard, complex }
easing: { easeInOut, easeOut, easeIn, linear }
}
}
```
## Using Built-in Themes
### Basic Theme Setup
```typescript
import { ThemeProvider } from '@/fakemui/theming'
import App from './App'
export function Root() {
return (
)
}
```
### Reading Current Theme
```typescript
import { useTheme } from '@/fakemui/theming'
export function ComponentWithTheme() {
const { theme, palette } = useTheme()
return (
Current theme: {theme}
)
}
```
### Accessing Theme in sx Prop
```typescript
import { Box, Button } from '@/fakemui'
export function StyledComponent() {
return (
Content with theme
)
}
```
## Creating Custom Themes
### Option 1: Extend Existing Theme
```typescript
import { createTheme } from '@/fakemui/theming'
const customTheme = createTheme({
palette: {
primary: {
main: '#6366f1', // Indigo
light: '#818cf8',
dark: '#4f46e5',
contrastText: '#ffffff'
},
secondary: {
main: '#ec4899', // Pink
light: '#f472b6',
dark: '#db2777',
contrastText: '#ffffff'
}
},
typography: {
fontFamily: "'Inter', sans-serif",
fontSize: 14
}
})
// Use custom theme
```
### Option 2: Full Theme Customization
```typescript
import { createTheme } from '@/fakemui/theming'
const brandTheme = createTheme({
palette: {
primary: {
main: '#2563eb', // Brand blue
light: '#3b82f6',
dark: '#1d4ed8',
contrastText: '#ffffff'
},
secondary: {
main: '#7c3aed', // Brand purple
light: '#a78bfa',
dark: '#6d28d9',
contrastText: '#ffffff'
},
success: {
main: '#10b981',
light: '#34d399',
dark: '#059669',
contrastText: '#ffffff'
},
warning: {
main: '#f59e0b',
light: '#fbbf24',
dark: '#d97706',
contrastText: '#ffffff'
},
error: {
main: '#ef4444',
light: '#f87171',
dark: '#dc2626',
contrastText: '#ffffff'
},
background: {
default: '#ffffff',
paper: '#f9fafb'
},
text: {
primary: 'rgba(0, 0, 0, 0.87)',
secondary: 'rgba(0, 0, 0, 0.60)',
disabled: 'rgba(0, 0, 0, 0.38)',
hint: 'rgba(0, 0, 0, 0.38)'
},
divider: 'rgba(0, 0, 0, 0.12)',
action: {
active: 'rgba(0, 0, 0, 0.54)',
hover: 'rgba(0, 0, 0, 0.04)',
selected: 'rgba(0, 0, 0, 0.08)',
disabled: 'rgba(0, 0, 0, 0.26)'
}
},
typography: {
fontFamily: "'Roboto', sans-serif",
fontSize: 14,
fontWeightLight: 300,
fontWeightRegular: 400,
fontWeightMedium: 500,
fontWeightBold: 700,
h1: {
fontSize: '6rem',
fontWeight: 300,
lineHeight: 1.167,
letterSpacing: '-0.015625em'
},
h2: {
fontSize: '3.75rem',
fontWeight: 300,
lineHeight: 1.2,
letterSpacing: 0
},
h3: {
fontSize: '3rem',
fontWeight: 400,
lineHeight: 1.167,
letterSpacing: '0.0125em'
},
h4: {
fontSize: '2.125rem',
fontWeight: 500,
lineHeight: 1.235,
letterSpacing: 0
},
h5: {
fontSize: '1.5rem',
fontWeight: 500,
lineHeight: 1.334,
letterSpacing: 0
},
h6: {
fontSize: '1.25rem',
fontWeight: 500,
lineHeight: 1.6,
letterSpacing: '0.0125em'
},
body1: {
fontSize: '1rem',
fontWeight: 400,
lineHeight: 1.5,
letterSpacing: '0.03125em'
},
body2: {
fontSize: '0.875rem',
fontWeight: 400,
lineHeight: 1.43,
letterSpacing: '0.0178571429em'
},
button: {
fontSize: '0.875rem',
fontWeight: 500,
lineHeight: 1.75,
letterSpacing: '0.0892857143em',
textTransform: 'uppercase'
},
caption: {
fontSize: '0.75rem',
fontWeight: 500,
lineHeight: 1.67,
letterSpacing: '0.0333333333em'
}
},
shape: {
borderRadius: 4
},
shadows: [
'none',
'0px 2px 1px -1px rgba(0,0,0,0.2)',
'0px 3px 1px -2px rgba(0,0,0,0.2)',
'0px 3px 3px -2px rgba(0,0,0,0.2)',
'0px 2px 4px -1px rgba(0,0,0,0.2)',
'0px 3px 5px -1px rgba(0,0,0,0.2)'
],
transitions: {
duration: {
shortest: 150,
shorter: 200,
standard: 300,
complex: 375
},
easing: {
easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)',
easeOut: 'cubic-bezier(0.0, 0, 0.2, 1)',
easeIn: 'cubic-bezier(0.4, 0, 1, 1)',
linear: 'linear'
}
}
})
```
## Dynamic Theme Switching
### Basic Theme Switcher
```typescript
import { Box, Button, Stack } from '@/fakemui'
import { useTheme } from '@/fakemui/theming'
export function ThemeSwitcher() {
const { theme, setTheme } = useTheme()
const themes = ['default', 'dark', 'ocean', 'forest', 'sunset']
return (
Current theme: {theme}
{themes.map((t) => (
))}
)
}
```
### Theme Switcher in AppBar
```typescript
import { AppBar, Toolbar, Box, Select } from '@/fakemui'
import { useTheme } from '@/fakemui/theming'
export function Header() {
const { theme, setTheme } = useTheme()
return (
MyApp
)
}
```
### Persist Theme Preference
```typescript
import { useTheme } from '@/fakemui/theming'
import { useEffect } from 'react'
export function App() {
const { theme, setTheme } = useTheme()
// Load theme from localStorage
useEffect(() => {
const savedTheme = localStorage.getItem('app-theme')
if (savedTheme) {
setTheme(savedTheme)
}
}, [])
// Save theme to localStorage
useEffect(() => {
localStorage.setItem('app-theme', theme)
}, [theme])
return
}
```
### System Preference Detection
```typescript
import { useTheme } from '@/fakemui/theming'
import { useEffect } from 'react'
export function App() {
const { setTheme } = useTheme()
useEffect(() => {
// Check system preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)')
const handleChange = (e) => {
setTheme(e.matches ? 'dark' : 'default')
}
// Set initial theme based on system preference
setTheme(prefersDark.matches ? 'dark' : 'default')
// Listen for changes
prefersDark.addEventListener('change', handleChange)
return () => prefersDark.removeEventListener('change', handleChange)
}, [setTheme])
return
}
```
## Color System
### Material Design 3 Color Roles
```typescript
// Core colors
primary // Primary interactive color
secondary // Secondary interactive color
tertiary // Tertiary interactive color (accent)
// Semantic colors
error // Error/destructive actions
warning // Warning messages
info // Informational messages
success // Success confirmations
// Neutral colors
background // Background surface
surface // Surface elements (cards, containers)
text // Text content
outline // Borders, dividers
```
### Using Colors in Components
```typescript
import { Button, Card, Typography, Box } from '@/fakemui'
export function ColorDemo() {
return (
{/* Primary variants */}
{/* Secondary variants */}
{/* Semantic colors */}
{/* In cards */}
Success message
)
}
```
## Material Design 3 Token Reference
### Spacing
```typescript
// 8px base unit
sx={{
p: 1 // 8px
p: 2 // 16px
p: 3 // 24px
p: 4 // 32px
gap: 0.5 // 4px
}}
```
### Elevation/Shadows
```typescript
// 5 elevation levels
boxShadow: 0 // none
boxShadow: 1 // low
boxShadow: 2 // low-medium
boxShadow: 3 // medium
boxShadow: 4 // medium-high
boxShadow: 5 // high
```
### Typography
```typescript
// 6 heading levels
variant="h1" // Display large
variant="h2" // Display medium
variant="h3" // Display small
variant="h4" // Headline large
variant="h5" // Headline medium
variant="h6" // Headline small
// Body text
variant="body1" // Body large
variant="body2" // Body medium
// Special
variant="button" // Button text
variant="caption" // Caption
```
### Border Radius
```typescript
// All components support borderRadius
sx={{ borderRadius: 1 }} // 4px
sx={{ borderRadius: 1.5 }} // 6px
sx={{ borderRadius: 2 }} // 8px
sx={{ borderRadius: '50%' }} // Circular
```
## Responsive Design
### Breakpoints
Material Design 3 defines responsive breakpoints:
```typescript
// Mobile-first breakpoints
xs: 0 // Extra small (phones)
sm: 600 // Small (tablets)
md: 960 // Medium (small laptops)
lg: 1264 // Large (laptops)
xl: 1904 // Extra large (desktops)
```
### Using Breakpoints in sx
```typescript
Responsive text
```
### Responsive Grid
```typescript
Full width on mobile
Half width on tablet
Third width on medium
Quarter width on large
```
## Accessibility in Theming
### Contrast Ratios
All theme colors maintain WCAG AA+ contrast:
```typescript
// Light text on dark background
color: 'text.primary' // 87% opacity = 4.5:1 ratio
// Dark text on light background
color: 'text.primary' // 87% opacity = 14:1 ratio
```
### Color Blindness Support
Fakemui themes avoid red-green only differentiation:
```typescript
// ✅ Good - uses multiple visual cues
}>
Error message
// ❌ Avoid - relies only on red color
Error
```
### High Contrast Mode
```typescript
const highContrastTheme = createTheme({
palette: {
text: {
primary: '#000000', // Full black
secondary: '#333333' // Darker gray
},
background: {
default: '#ffffff', // Full white
paper: '#f5f5f5'
}
}
})
```
## Common Theming Patterns
### Dark Mode Toggle
```typescript
import { IconButton, useTheme } from '@/fakemui'
import { DarkModeIcon, LightModeIcon } from '@/fakemui/icons'
export function DarkModeToggle() {
const { theme, setTheme } = useTheme()
const isDark = theme === 'dark'
return (
setTheme(isDark ? 'default' : 'dark')}
color="inherit"
>
{isDark ? : }
)
}
```
### Brand Customization
```typescript
const createBrandTheme = (brandColor) => {
return createTheme({
palette: {
primary: {
main: brandColor,
light: lighten(brandColor, 0.3),
dark: darken(brandColor, 0.3),
contrastText: '#ffffff'
}
}
})
}
```
### Accessibility Overrides
```typescript
const accessibilityTheme = createTheme({
palette: {
text: {
primary: '#000000',
secondary: '#404040',
disabled: '#808080'
},
action: {
hover: 'rgba(0, 0, 0, 0.08)',
selected: 'rgba(0, 0, 0, 0.16)'
}
},
typography: {
fontSize: 16, // Larger base font
h6: {
fontSize: '1.5rem' // Larger headings
}
}
})
```
## Best Practices
1. **Maintain sufficient contrast** - Aim for WCAG AA+ (4.5:1)
2. **Use semantic colors** - Use `error`, `success`, `warning` for meaning
3. **Don't rely on color alone** - Combine with icons/text
4. **Test with color blindness simulators** - Chrome DevTools has built-in tool
5. **Support system preferences** - Detect `prefers-color-scheme`
6. **Persist user choice** - Save theme in localStorage
7. **Use theme tokens** - Avoid hardcoded colors
8. **Document custom themes** - Include usage examples
9. **Test on real devices** - Colors vary across screens
10. **Follow Material Design 3** - Use official specifications
## Troubleshooting
### Theme not applying
```typescript
// ✅ Correct - Wrap app in ThemeProvider
// ❌ Wrong - Missing wrapper
```
### Colors not updating
```typescript
// ✅ Use useTheme hook
const { setTheme } = useTheme()
setTheme('dark')
// ❌ Don't set directly
window.fakemui.theme = 'dark' // Won't work
```
### Custom theme not working
```typescript
// ✅ Pass theme object to ThemeProvider
const customTheme = createTheme({ /* ... */ })
// ❌ Pass theme string (only works for built-in themes)
// Won't work
```
## Resources
- [Material Design 3 Official Guide](https://m3.material.io/)
- Material Design 3 Color System: https://m3.material.io/styles/color/overview
- Material Design 3 Typography: https://m3.material.io/styles/typography/overview
- WCAG Contrast Guidelines: https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html