22

Using this tool https://react-theming.github.io/create-mui-theme/ I get a js file and a json file as mentioned on above theme generator page in respective paths as mentioned:

// src/ui/theme/index.js
/* src/ui/theme/theme.json */

Now they work fine when I leave the file extension to js. As soon as I try to use js as a tsx file the editor starts complaining. I have all the necessary setup done via CRA Typescript in tsconfig file also. Also necessary config from this page https://material-ui.com/guides/typescript/

When I try this it does not work, any ideas if I am missing something?

// My amended index.tsx file

import { createMuiTheme } from '@material-ui/core/styles';

const palette = {
  primary: { main: '#3f51b5' },
  secondary: { main: '#f50057' }
};
const themeName = 'San Marino Razzmatazz Sugar Gliders';

export default createMuiTheme({ palette, themeName });

Also the theme.json is untouched by me. I am still learning sorry, any ideas if this is an interface problem and how to use it?

7 Answers 7

26

Material UI custom theme V5

Material UI custom theme in React with Typescript v4->v5 migration guide. create separate file for declaration.

👉 theme.d.ts

import { Theme, ThemeOptions } from '@mui/material/styles';

declare module '@mui/material/styles' {
  interface CustomTheme extends Theme {
    status: {
      danger: string;
    };
  }
  // allow configuration using `createTheme`
  interface CustomThemeOptions extends ThemeOptions {
    status?: {
      danger?: string;
    };
  }
  export function createTheme(options?: CustomThemeOptions): CustomTheme;
}

it will override default createTheme function with custome theme configuration. now you can use custom config in theme as mention below 👇.

👉 theme.ts

import { createTheme } from '@mui/material/styles';
import { orange, red } from '@mui/material/colors';

const theme = createTheme({
  status: {
    danger: red[500],
  },
  palette: {
    primary: {
      main: orange[500],
    },
  },
});

export default theme;
Sign up to request clarification or add additional context in comments.

3 Comments

Argument of type '{ status: { danger: "#f44336"; }; palette: { primary: { main: "#ff9800"; }; }; }' is not assignable to parameter of type 'ThemeOptions'. .... Object literal may only specify known properties, and 'status' does not exist in type 'ThemeOptions'
When tried to add a color in palette TS2769: No overload matches this call. ... ' is not assignable to type 'PaletteOptions'. Object literal may only specify known properties, and 'customStatus' does not exist in type 'PaletteOptions'.
@Amir Achhodi can you tell me how we can do it if I want to add a color in palette like: palette: { customStatus: { main: 'red', } }
26

Material-UI has got typing declarations already defined so you can't just add extra properties to it. You would have to extend the interface via module augmentation:

import { createMuiTheme } from '@material-ui/core/styles';

declare module '@material-ui/core/styles/createMuiTheme' {
    interface ThemeOptions {    
        themeName?: string  // optional
    }
}

const palette = {
  primary: { main: '#3f51b5' },
  secondary: { main: '#f50057' }
};

const themeName = 'San Marino Razzmatazz Sugar Gliders';

export default createMuiTheme({ palette, themeName });

3 Comments

Thank you for the quick reply. It worked perfectly. I would not have known this as there is no example I can find for custom themes on MUI documentation with TS. There are lots of examples which uses this syntax but I would not have related those ever to implement in my solution. So thank you!
you’re welcome! Can you mark this as accepted if you think it solves it please :) Also you can learn a great deal of TS at typescriptlang.org/docs/handbook/typescript-in-5-minutes.html
yes I have but it says this :( Thanks for the feedback! Votes cast by those with less than 15 reputation are recorded, but do not change the publicly displayed post score.
9

What @kasperoo writes but instead make it more generic since typing styles is way to much work:

// imported theme from separate file
import { themeDetails } from './utils/theme';

declare module '@mui/material/styles' {
        interface ThemeOptions {
          [key: string]: any; // 
        }
    }
const theme = createTheme({ themeDetails, 'theme name' });

2 Comments

I describe a similar solution, but I am also making use of const assertions to provide literal types for the custom properties: dragoshmocrii.com/material-ui-custom-theme-and-typescript
This is not a good idea because it basically allows you to use any random string that doesn't actually exist in your theme. You could put somewhere in your app theme.monkey.dance and it would accept it as a valid value
6

Amir's answer wasn't working for me, i didn't have the types while using styled components, so what ended up working for me is to use the same names for the new interfaces and renaming the ones that came from mui

import { Theme as MUITheme, ThemeOptions as MUIThemeOptions } from '@mui/material/styles';

declare module '@mui/material/styles' {
  interface Theme extends MUITheme {
    accent: {
      main: string;
    };
  }
  // allow configuration using `createTheme`
  interface ThemeOptions extends MUIThemeOptions {
    accent?: {
      main?: string;
    };
  }
  export function createTheme(options?: ThemeOptions): Theme;
}

2 Comments

is this theme.d.ts ?
That's right! @NatheeshkumarRangasamy
3

According to this documentation at the bottom of the page they have mentioned following this link for further details.

If you navigate to the styles directory then you'll see something like createTheme.d.ts, createPalette.d.ts so according to their example we can write as follows:

theme.d.ts

declare module '@mui/material/styles' {
  interface Theme {
    status: {
      danger: string;
    };
  }
  // allow configuration using `createTheme`
  interface ThemeOptions {
    status?: {
      danger?: string;
    };
  }
}

export default function createTheme(options?: ThemeOptions, ...args: object[]): Theme;

palette.d.ts

declare module '@mui/material/styles/createPalette' {
  interface Palette {
    otherColor: {
      main?: string;
    };
  }
  interface PaletteOptions {
    otherColor: {
      main?: string;
    };
  }
}

export default function createPalette(palette: PaletteOptions): Palette;

theme.ts

import { createTheme } from '@mui/material';

const theme = createTheme({
  status: { danger: '#e53e3e' },
  palette: {
    primary: {
      main: '#1760a5',
      light: 'skyblue',
    },
    secondary: { main: '#15c630' },
    otherColor: { main: '#999' },
  },
});

export default theme;

Uses

const StyledBox = styled(Box)(({ theme }) => ({
  height: '20px',
  width: '20x',
  backgroundColor: theme.status.danger,
  color: theme.palette.otherColor.main,
}));

Comments

1

Material UI theme V5

this is the one that worked for me

You can declare your custom variables in .d.ts file. So I created a theme.d.ts file in src folder and override default MUI types with this config:

import type { Theme } from '@mui/material/styles';

declare module "@mui/material/styles" {
type Overrides = typeof globalThemeOverrides;
interface Theme extends Overrides {
    palette: Theme["palette"] & {
        custom: {};
    };
    anotherCustom: {};
   }
 }

Comments

0

I extended the ThemeOptions & PaletteOptions and passed in createTheme()

export interface CustomType {
  iconBorderRadius: number;
  iconBorderRadius2: number;
}

export interface CustomShadowsType{
  z1:string;
  z8:string;
  z12:string;
  z16:string;
  z20:string;
  z24:string;
  primary:string;
  secondary:string;
  info:string;
  success:string;
  warning:string;
  error:string;
}

export interface PaletteOptionsExtended extends PaletteOptions {
  custom: CustomType;
}

export interface ThemeOptionsExtended extends ThemeOptions {
  palette: PaletteOptionsExtended;
  customShadows:CustomShadowsType;
}

export default function ThemeProvider({ children }) {
  const themeOptions = useMemo(
    () => ({
      palette,
      shape: { borderRadius: 8 },
      typography,
      shadows,
      customShadows,
    }),
    []
  );

  const a: ThemeOptionsExtended = themeOptions;

  const theme = createTheme(a);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.