UNPKG

@mui/material

Version:

Material UI is an open-source React component library that implements Google's Material Design. It's comprehensive and can be used in production out of the box.

444 lines (381 loc) • 11.3 kB
# Themed components You can customize a component's styles, default props, and more by using its component key inside the theme. The `components` key in the theme helps to achieve styling consistency across your application. However, the theme isn't tree-shakable, prefer creating new components for heavy customizations. ## Theme default props Every Material UI component has default values for each of its props. To change these default values, use the `defaultProps` key exposed in the theme's `components` key: ```js const theme = createTheme({ components: { // Name of the component MuiButtonBase: { defaultProps: { // The props to change the default for. disableRipple: true, // No more ripple, on the whole application 💣! }, }, }, }); ``` ```tsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import Button from '@mui/material/Button'; const theme = createTheme({ components: { // Name of the component ⚛️ MuiButtonBase: { defaultProps: { // The default props to change disableRipple: true, // No more ripple, on the whole application 💣! }, }, }, }); export default function DefaultProps() { return ( <ThemeProvider theme={theme}> <Button>This button has disabled ripples.</Button> </ThemeProvider> ); } ``` If you're using TypeScript and [lab components](/material-ui/about-the-lab/), check [this article to learn how to override their styles](/material-ui/about-the-lab/#typescript). ## Theme style overrides The theme's `styleOverrides` key makes it possible to change the default styles of any Material UI component. `styleOverrides` requires a slot name as a key (use `root` to target the outer-most element) and an object with CSS properties as a value. Nested CSS selectors are also supported as values. ```js const theme = createTheme({ components: { // Name of the component MuiButton: { styleOverrides: { // Name of the slot root: { // Some CSS fontSize: '1rem', }, }, }, }, }); ``` ```tsx import { ThemeProvider, createTheme } from '@mui/material/styles'; import Button from '@mui/material/Button'; const theme = createTheme({ components: { MuiButton: { styleOverrides: { root: { fontSize: '1rem', }, }, }, }, }); export default function GlobalThemeOverride() { return ( <ThemeProvider theme={theme}> <Button>font-size: 1rem</Button> </ThemeProvider> ); } ``` ### Variants Most components include design-related props that affect their appearance. For example, the Card component supports a `variant` prop where you can pick `outlined` as a value that adds a border. If you want to override styles based on a specific prop, you can use the `variants` key in the particular slot that contains `props` and `style` keys. When the component's `props` matches, the `style` will be applied. Override definitions are specified as an array. Also, ensure that any styles that should take precedence are listed last. #### Overriding styles based on existing props The example below demonstrates the increase of the border thickness of the `outlined` Card: ```js const theme = createTheme({ components: { MuiCard: { styleOverrides: { root: { variants: [ { props: { variant: 'outlined' }, style: { borderWidth: '3px', }, }, ], }, }, }, }, }); ``` #### Adding styles based on new values The example below demonstrates the addition of a new variant `dashed` to the Button component: ```js const theme = createTheme({ components: { MuiButton: { styleOverrides: { root: { variants: [ { // `dashed` is an example value, it can be any name. props: { variant: 'dashed' }, style: { textTransform: 'none', border: `2px dashed ${blue[500]}`, }, }, ], }, }, }, }, }); ``` #### Overriding styles based on existing and new props The example below demonstrates the override of styles when the Button's variant is `dashed` (a new variant) and color is `secondary` (an existing color): ```js const theme = createTheme({ components: { MuiButton: { styleOverrides: { root: { variants: [ { props: { variant: 'dashed', color: 'secondary' }, style: { border: `4px dashed ${red[500]}`, }, }, ], }, }, }, }, }); ``` If you're using TypeScript, you'll need to specify your new variants/colors, using [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation). <!-- Tested with packages/mui-material/test/typescript/augmentation/themeComponents.spec.ts --> ```tsx declare module '@mui/material/Button' { interface ButtonPropsVariantOverrides { dashed: true; } } ``` ```tsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import Button from '@mui/material/Button'; declare module '@mui/material/Button' { interface ButtonPropsVariantOverrides { dashed: true; } } const customTheme = createTheme({ components: { MuiButton: { styleOverrides: { root: { variants: [ { props: { variant: 'dashed' }, style: ({ theme }) => ({ textTransform: 'none', border: `2px dashed ${theme.palette.primary.main}`, color: theme.palette.primary.main, }), }, { props: { variant: 'dashed', color: 'secondary' }, style: ({ theme }) => ({ border: `2px dashed ${theme.palette.secondary.main}`, color: theme.palette.secondary.main, }), }, { props: { variant: 'dashed', size: 'large' }, style: { borderWidth: 4, }, }, { props: { variant: 'dashed', color: 'secondary', size: 'large' }, style: { fontSize: 18, }, }, ], }, }, }, }, }); export default function GlobalThemeVariants() { return ( <ThemeProvider theme={customTheme}> <Button variant="dashed" sx={{ m: 1 }}> Dashed </Button> <Button variant="dashed" color="secondary" sx={{ m: 1 }}> Secondary </Button> <Button variant="dashed" size="large" sx={{ m: 1 }}> Large </Button> <Button variant="dashed" color="secondary" size="large" sx={{ m: 1 }}> Secondary large </Button> </ThemeProvider> ); } ``` The variant `props` can also be defined as a callback, allowing you to apply styles based on conditions. This is useful for styling when a property does not have a specific value. ```js const theme = createTheme({ components: { MuiButton: { styleOverrides: { root: { variants: [ { props: (props) => props.variant === 'dashed' && props.color !== 'secondary', style: { textTransform: 'none', border: `2px dashed ${blue[500]}`, }, }, ], }, }, }, }, }); ``` ### Slot ownerState callback (deprecated) Using callback to access slot's `ownerState` has been deprecated, use [variants](#variants) instead. ```diff const theme = createTheme({ components: { MuiButton: { styleOverrides: { - root: ({ ownerState, theme }) => ({ ... }), + root: { + variants: [...], }, }, }, }, }); ``` ### The `sx` syntax (experimental) The `sx` prop acts as a shortcut for defining custom styles that access the theme object. This prop lets you write inline styles using a superset of CSS. Learn more about [the concept behind the `sx` prop](/system/getting-started/the-sx-prop/) and [how `sx` differs from the `styled` utility](/system/styled/#difference-with-the-sx-prop). You can use the `sx` prop inside the `styleOverrides` key to modify styles within the theme using shorthand CSS notation. This is especially handy if you're already using the `sx` prop with your components because you can use the same syntax in your theme and quickly transfer styles between the two. :::info The `sx` prop is a stable feature for customizing components since Material UI v5, but it is still considered _experimental_ when used directly inside the theme object. ::: ```tsx import { ThemeProvider, createTheme } from '@mui/material/styles'; import Chip from '@mui/material/Chip'; import Check from '@mui/icons-material/Check'; const finalTheme = createTheme({ components: { MuiChip: { styleOverrides: { root: ({ theme }) => theme.unstable_sx({ // https://mui.com/system/getting-started/the-sx-prop/#spacing px: 1, py: 0.25, // https://mui.com/system/borders/#border-radius borderRadius: 1, // 4px as default. }), label: { padding: 'initial', }, icon: ({ theme }) => theme.unstable_sx({ mr: 0.5, ml: '-2px', }), }, }, }, }); export default function GlobalThemeOverrideSx() { return ( <ThemeProvider theme={finalTheme}> <Chip color="success" label={ <span> <b>Status:</b> Completed </span> } icon={<Check fontSize="small" />} /> </ThemeProvider> ); } ``` ```tsx const finalTheme = createTheme({ components: { MuiChip: { styleOverrides: { root: ({ theme }) => theme.unstable_sx({ px: 1, py: 0.25, borderRadius: 1, }), label: { padding: 'initial', }, icon: ({ theme }) => theme.unstable_sx({ mr: 0.5, ml: '-2px', }), }, }, }, }); ``` ### Specificity If you use the theming approach to customize the components, you'll still be able to override them using the `sx` prop as it has a higher CSS specificity, even if you're using the experimental `sx` syntax within the theme. ## Theme variables Another way to override the look of all component instances is to adjust the [theme configuration variables](/material-ui/customization/theming/#theme-configuration-variables). ```js const theme = createTheme({ typography: { button: { fontSize: '1rem', }, }, }); ``` ```tsx import { ThemeProvider, createTheme } from '@mui/material/styles'; import Button from '@mui/material/Button'; const theme = createTheme({ typography: { button: { fontSize: '1rem', }, }, }); export default function ThemeVariables() { return ( <ThemeProvider theme={theme}> <Button>font-size: 1rem</Button> </ThemeProvider> ); } ```