I'm trying to pass a custom palette color into the color
prop of a Typography tag.
I've got my theme set up in theme.ts
like this:
declare module "@mui/material/styles" {
interface Palette {
tertiary: Palette['primary'];
}
interface PaletteOptions {
tertiary: PaletteOptions['primary'];
}
}
export const theme = createTheme({
palette: {
primary: // not important
secondary: //not important
tertiary: {
main: '#FFE461',
dark: '#FED047',
light: "#FFEC92"
}
}
});
Then I've got some code in my index.tsx
file that looks like this:
import { CssBaseline, ThemeProvider, Typography } from "@mui/material";
import { theme } from "../theme/theme";
export function Index() {
return (
<ThemeProvider theme={theme}>
<CssBaseline/>
<Typography variant="h1" component="h1" color="primary">Heading 1</Typography>
<Typography variant="h2" component="h2" color="secondary">Heading 2</Typography>
<Typography variant="h3" component="h3" color="tertiary">Heading 3</Typography>
</ThemeProvider>
);
}
I am sure that the theme is applying because the colors for primary
and secondary
are both working as expected. The third <Typography>
tag's content is showing up as black, though, which is not what I'd expect.
I found a YouTube tutorial that says that I can't pass my custom palette color into the color
prop in the <Typography>
tag and that I'd have to use the sx
prop to pull in my custom color, but I'd rather avoid that if possible because it creates multiple different ways of setting the color on the <Typography>
tag. This is the initial setup for a new project, so I want to avoid that so other engineers working on it are encouraged to use a single code style.
Is there a way to have the Typography tag's color
prop pick up custom palette colors?
In the Typography source code you can find the following:
// TODO v6: deprecate these color values in v5.x and remove the transformation in v6
const colorTransformations = {
primary: 'primary.main',
textPrimary: 'text.primary',
secondary: 'secondary.main',
textSecondary: 'text.secondary',
error: 'error.main',
};
You can see here that MUI is currently allowing primary
as a shortcut for primary.main
and similar for secondary
, but it isn't doing that transformation for any additional colors you add. For anything else it will be looking in theme.palette
for the exact path you specify for the color
prop. Since theme.palette.tertiary
points at an object rather than a valid color, it has no effect. As you already discovered, specifying tertiary.main
does work.
Here's a full working example based on your code:
import * as React from "react";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import Typography from "@mui/material/Typography";
declare module "@mui/material/styles" {
interface Palette {
tertiary: Palette["primary"];
}
interface PaletteOptions {
tertiary: PaletteOptions["primary"];
}
}
export const theme = createTheme({
palette: {
tertiary: {
main: "#FFE461",
dark: "#FED047",
light: "#FFEC92"
}
}
});
export default function TypographyTheme() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Typography variant="h1" component="h1" color="primary">
Heading 1
</Typography>
<Typography variant="h2" component="h2" color="secondary">
Heading 2
</Typography>
<Typography variant="h3" component="h3" color="tertiary.main">
Heading 3
</Typography>
</ThemeProvider>
);
}