Enhancing MUI Theming with TypeScript: Custom Variants and Styles
TypeScript provides a powerful type system that can greatly enhance the MUI customization process, enabling developers to enforce type safety and utilize auto-completion features within their editors. This article will walk you through how to use TypeScript to customize MUI components and themes effectively.
Step 1: TypeScript with Component Customization
Customizing with Styled
When using styled
, TypeScript can infer types from the component. But to ensure that you are passing the correct props, you can define an interface for them:
import Button from '@mui/material/Button';
import { styled } from '@mui/material/styles';
interface CustomButtonProps {
colorVariant?: 'dashed' | 'default';
}
const CustomButton = styled(Button)<CustomButtonProps>(({ theme, colorVariant }) => ({
...(colorVariant === 'dashed' && {
border: `2px dashed ${theme.palette.primary.main}`,
}),
// more styles here
}));
// Usage
<CustomButton colorVariant="dashed">
Custom Styled Button
</CustomButton>;
Extending Theme with Custom Variants
When adding new variants, you'll need to extend MUI's theme module to include the custom variant:
import { createTheme, ThemeProvider, Button } from '@mui/material';
declare module '@mui/material/Button' {
interface ButtonPropsVariantOverrides {
dashed: true;
}
}
const theme = createTheme({
components: {
MuiButton: {
variants: [
{
props: { variant: 'dashed' },
style: {
textTransform: 'none',
border: `2px dashed #3f51b5`,
},
},
],
},
},
});
// Usage
<ThemeProvider theme={theme}>
<Button variant="dashed">
Dashed Variant Button
</Button>
</ThemeProvider>;
Step 2: Defining Themes with TypeScript
Creating a Typed Custom Theme
Defining a theme requires specifying the structure of the custom theme, adhering to MUI's ThemeOptions
interface:
import { createTheme, ThemeProvider } from '@mui/material';
declare module '@mui/material/styles' {
interface Theme {
customShadows: {
card: string;
};
}
// allow configuration using `createTheme`
interface ThemeOptions {
customShadows?: {
card?: string;
};
}
}
const customTheme = createTheme({
customShadows: {
card: '0 2px 10px 0 rgba(0,0,0,0.12)',
},
// other theme settings
});
// Usage
<ThemeProvider theme={customTheme}>
{/* Your component tree */}
</ThemeProvider>;
Implementing Predefined Component Styles
To ensure type safety when overriding component styles, you should extend the Theme
interface:
declare module '@mui/material/styles' {
interface Theme {
components?: {
MuiButton?: {
styleOverrides?: {
root?: React.CSSProperties;
};
};
};
}
}
const customTheme = createTheme({
components: {
MuiButton: {
styleOverrides: {
root: (theme) => ({
borderRadius: theme.shape.borderRadius,
}),
},
},
},
});
// Now, TypeScript is aware of the custom styleOverrides
TypeScript's integration with MUI's theming system ensures that your theme customizations are not only visually consistent but also type-safe, preventing a class of errors and improving developer experience.
Remember, by leveraging TypeScript with MUI, you gain access to a richer development environment, making the customization process more efficient and enjoyable. Now that you have the tools to type-check your themes, you can confidently apply these practices to craft stunning and consistent UIs.