[ PROMPT_NODE_24985 ]
Theme Customization
[ SKILL_DOCUMENTATION ]
# MUI Theme Customization
## Creating a Custom Theme
```typescript
import { createTheme, ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
const theme = createTheme({
palette: {
mode: 'light',
primary: {
main: '#1976d2',
light: '#42a5f5',
dark: '#1565c0',
contrastText: '#fff'
},
secondary: {
main: '#9c27b0',
light: '#ba68c8',
dark: '#7b1fa2',
contrastText: '#fff'
},
error: {
main: '#d32f2f'
},
warning: {
main: '#ed6c02'
},
info: {
main: '#0288d1'
},
success: {
main: '#2e7d32'
}
},
typography: {
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
h1: {
fontSize: '2.5rem',
fontWeight: 600
},
h2: {
fontSize: '2rem',
fontWeight: 600
},
button: {
textTransform: 'none',
fontWeight: 600
}
},
shape: {
borderRadius: 8
},
spacing: 8
});
function App() {
return (
{/* Your app */}
);
}
```
## Dark Mode Support
```typescript
const getTheme = (mode: 'light' | 'dark') => createTheme({
palette: {
mode,
...(mode === 'light'
? {
// Light mode colors
primary: { main: '#1976d2' },
background: {
default: '#f5f5f5',
paper: '#ffffff'
}
}
: {
// Dark mode colors
primary: { main: '#90caf9' },
background: {
default: '#121212',
paper: '#1e1e1e'
}
})
}
});
function App() {
const [mode, setMode] = useState('light');
const theme = useMemo(() => getTheme(mode), [mode]);
return (
setMode(m => m === 'light' ? 'dark' : 'light')}>
{mode === 'light' ? : }
{/* Your app */}
);
}
```
## Typography Customization
```typescript
const theme = createTheme({
typography: {
fontFamily: '"Inter", sans-serif',
fontSize: 14,
fontWeightLight: 300,
fontWeightRegular: 400,
fontWeightMedium: 500,
fontWeightBold: 700,
h1: {
fontSize: '3rem',
fontWeight: 700,
lineHeight: 1.2,
letterSpacing: '-0.01562em'
},
h2: {
fontSize: '2.5rem',
fontWeight: 700,
lineHeight: 1.3
},
body1: {
fontSize: '1rem',
lineHeight: 1.5,
letterSpacing: '0.00938em'
},
button: {
fontSize: '0.875rem',
fontWeight: 600,
textTransform: 'none',
letterSpacing: '0.02857em'
}
}
});
```
## Component Style Overrides
```typescript
const theme = createTheme({
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
padding: '8px 16px',
boxShadow: 'none',
'&:hover': {
boxShadow: 'none'
}
},
contained: {
'&:hover': {
transform: 'translateY(-2px)',
transition: 'transform 0.2s'
}
}
},
defaultProps: {
disableElevation: true
}
},
MuiCard: {
styleOverrides: {
root: {
borderRadius: 12,
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
}
}
},
MuiTextField: {
defaultProps: {
variant: 'outlined',
size: 'medium'
},
styleOverrides: {
root: {
'& .MuiOutlinedInput-root': {
borderRadius: 8
}
}
}
},
MuiChip: {
styleOverrides: {
root: {
borderRadius: 6,
fontWeight: 500
}
}
}
}
});
```
## Breakpoints
```typescript
const theme = createTheme({
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 960,
lg: 1280,
xl: 1920
}
}
});
// Usage
```
## Spacing
```typescript
const theme = createTheme({
spacing: 8 // Base unit: 8px
});
// Usage: theme.spacing(2) = 16px
// padding: 16px, margin: 24px
```
## Custom Palette Colors
```typescript
declare module '@mui/material/styles' {
interface Palette {
tertiary: Palette['primary'];
}
interface PaletteOptions {
tertiary?: PaletteOptions['primary'];
}
}
const theme = createTheme({
palette: {
primary: {
main: '#1976d2'
},
secondary: {
main: '#9c27b0'
},
tertiary: {
main: '#ff9800',
light: '#ffb74d',
dark: '#f57c00',
contrastText: '#000'
}
}
});
// Usage
```
## Shadows
```typescript
const theme = createTheme({
shadows: [
'none',
'0 2px 4px rgba(0,0,0,0.1)',
'0 4px 8px rgba(0,0,0,0.12)',
'0 8px 16px rgba(0,0,0,0.14)',
// ... up to shadows[24]
]
});
// Usage
// Uses shadows[2]
```
## Z-Index Layers
```typescript
const theme = createTheme({
zIndex: {
mobileStepper: 1000,
speedDial: 1050,
appBar: 1100,
drawer: 1200,
modal: 1300,
snackbar: 1400,
tooltip: 1500
}
});
```
## Transitions
```typescript
const theme = createTheme({
transitions: {
duration: {
shortest: 150,
shorter: 200,
short: 250,
standard: 300,
complex: 375,
enteringScreen: 225,
leavingScreen: 195
},
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)',
sharp: 'cubic-bezier(0.4, 0, 0.6, 1)'
}
}
});
// Usage
theme.transitions.create(['transform', 'background-color'], {
duration: theme.transitions.duration.standard
})
}}
/>
```
## Complete Theme Example
```typescript
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
palette: {
mode: 'light',
primary: {
main: '#2563eb',
light: '#60a5fa',
dark: '#1e40af',
contrastText: '#ffffff'
},
secondary: {
main: '#7c3aed',
light: '#a78bfa',
dark: '#5b21b6',
contrastText: '#ffffff'
},
error: {
main: '#dc2626'
},
warning: {
main: '#f59e0b'
},
info: {
main: '#0ea5e9'
},
success: {
main: '#10b981'
},
background: {
default: '#f8fafc',
paper: '#ffffff'
},
text: {
primary: '#0f172a',
secondary: '#64748b'
}
},
typography: {
fontFamily: '"Inter", "Segoe UI", "Roboto", sans-serif',
fontSize: 14,
h1: {
fontSize: '3rem',
fontWeight: 700,
lineHeight: 1.2
},
h2: {
fontSize: '2.25rem',
fontWeight: 700,
lineHeight: 1.3
},
h3: {
fontSize: '1.875rem',
fontWeight: 600,
lineHeight: 1.4
},
h4: {
fontSize: '1.5rem',
fontWeight: 600,
lineHeight: 1.5
},
h5: {
fontSize: '1.25rem',
fontWeight: 600,
lineHeight: 1.6
},
h6: {
fontSize: '1rem',
fontWeight: 600,
lineHeight: 1.6
},
button: {
textTransform: 'none',
fontWeight: 600,
fontSize: '0.875rem'
}
},
shape: {
borderRadius: 10
},
spacing: 8,
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
padding: '10px 20px',
fontWeight: 600,
boxShadow: 'none',
'&:hover': {
boxShadow: 'none'
}
},
contained: {
'&:hover': {
transform: 'translateY(-1px)',
boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
}
}
},
defaultProps: {
disableElevation: true
}
},
MuiCard: {
styleOverrides: {
root: {
borderRadius: 12,
boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)',
'&:hover': {
boxShadow: '0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)'
}
}
}
},
MuiTextField: {
defaultProps: {
variant: 'outlined'
},
styleOverrides: {
root: {
'& .MuiOutlinedInput-root': {
borderRadius: 8,
'&:hover .MuiOutlinedInput-notchedOutline': {
borderColor: '#2563eb'
}
}
}
}
},
MuiChip: {
styleOverrides: {
root: {
borderRadius: 6,
fontWeight: 500,
height: 28
}
}
},
MuiAppBar: {
styleOverrides: {
root: {
boxShadow: '0 1px 3px rgba(0,0,0,0.12)'
}
}
}
}
});
export default theme;
```
## Theme Provider Setup
```typescript
// src/theme.ts - Export your theme
export { default as theme } from './theme';
// src/main.tsx or src/index.tsx
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import theme from './theme';
root.render(
);
```
## Accessing Theme in Components
```typescript
import { useTheme } from '@mui/material/styles';
function MyComponent() {
const theme = useTheme();
return (
);
}
```
## Theme Nesting
```typescript
import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles';
function NestedTheme() {
const outerTheme = useTheme();
const innerTheme = createTheme({
...outerTheme,
palette: {
...outerTheme.palette,
mode: 'dark'
}
});
return (
Dark section within light app
);
}
```
Source: claude-code-templates (MIT). See About Us for full credits.