How to use Material UI custom theme in React with Typescript

Asked
Active3 hr before
Viewed126 times

9 Answers

custommaterialreact
90%

Have a look at the Create React App with TypeScript example.,When adding custom properties to the Theme, you may continue to use it in a strongly typed way by exploiting TypeScript's module augmentation.,However type widening rears its ugly head once more if you try to make the styles depend on the theme:

In order for types to work, you have to at least have the following options enabled in your tsconfig.json:

{
   "compilerOptions": {
      "lib": ["es6", "dom"],
      "noImplicitAny": true,
      "noImplicitThis": true,
      "strictNullChecks": true
   }
}
load more v
88%

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:,Connect and share knowledge within a single location that is structured and easy to search., Can I avoid informal personal interactions at companies that offer free lunch?

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
});
load more v
72%

Pretag
 Pretag team - issue, fix, solve, resolve
65%

Because we're using TypeScript on the application, we must add the typescript template to the creation command. It creates an additional file called tsconfig.json on the root of the application, which has the responsibility of specifying the root files and the compiler options required by the project.,What about we have a quick pause now, and have a read at interfaces on the TypeScript documentation? The concept can get quite complex but don't worry, only the basic level is explored in our app.,Shall we check our TypeScript component in action? On the App.tsx file, add the reference to the recently created component:

.css - l84w3r {
   background - color: rgba(107, 70, 193, 0.2);
   border: none;
   color: var (--theme - ui - colors - gray - 2, #edf2f7);
   cursor: pointer;
   font - size: 14 px;
   font - family: "IBM Plex Sans", -apple - system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans - serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - webkit - letter - spacing: 0.025 rem; - moz - letter - spacing: 0.025 rem; - ms - letter - spacing: 0.025 rem;
   letter - spacing: 0.025 rem; - webkit - transition: default;
   transition: default;
   position: absolute;
   top: 0;
   right: 0;
   z - index: 1;
   border - radius: 0 0 0 0.25 rem;
   padding: 0.25 rem 0.6 rem;
}
@media screen and(min - width: 640 px) {
   .css - l84w3r {
      font - size: 14 px;
   }
}
@media screen and(min - width: 768 px) {
   .css - l84w3r {
      font - size: 16 px;
   }
}.css - l84w3r[disabled] {
   cursor: not - allowed;
}.css - l84w3r: not([disabled]): hover {
   background - color: var (--theme - ui - colors - primary, #6b46c1);color:var(--theme-ui-colors-white,# fff);
}
Copy.css - 1 gy8470 {
   border: 0; - webkit - clip: rect(0, 0, 0, 0);clip: rect(0, 0, 0, 0);height: 1 px;margin: -1 px;overflow: hidden;padding: 0;position: absolute;white - space: nowrap;width: 1 px;
}
copy code to clipboard1npx create - react - app welcomedev - react - starter--template typescript
load more v
75%

Material-UI is one of the most popular React component library in the world because it’s easy to use and fast. The best thing of all is looking good ! On the other hand, a lot of React users use TypeScript with React these days because it helps many potential run time errors especially for large applications. Combination of React and TypeScript is super powerful and beautiful. So it was meant to be that two of them met.,Unfortunately, type extension is still not enough. When you try to use extended theme in each component, you would get an error.,Because theme is typed with Theme , the cause of this error might around Theme and Palette. Go to createPalette.d.ts again.

As I explained above, default Material-UI theme is bit limited like below.

theme.tstheme.palette├──── primary│├──── main: string;│├────
dark: string;│├────
light: string;│├────
contrastText: string;│├────
50: string;│├────
100: string;│├────
200: string;│├────
300: string;│├────
400: string;│├────
600: string;│├────
700: string;│├────
800: string;│├────
900: string;│├────
A100: string;│├────
A200: string;│├────
A400: string;│└────
A700: string;│├────
secondary│...same as primary│├──── error│...same as primary│ | ____ text│├──── primary: string;│├────
secondary: string;│├────
disabled: string;│└────
hint: string;│ | ____ divider: string;│ | ____ action│├──── active: string;│├────
hover: string;│├────
hoverOpacity: string;│├────
selected: string;│├────
disabled: string;│└────
disabledBackground: string; || ____ background├────
default: string;└────
card: string;
load more v
40%

More documentation on Material-UI useTheme hook,More documentation on the default Material-UI theme,import { useTheme } from ‘@material-ui/core/styles’;

Pretag
 Pretag team - issue, fix, solve, resolve
22%

And then creating a custom theme factory function to create the theme.,So we need an interface for our customised theme that we can share with our packages.,Which will merge two interfaces, removing any members on T that exists in R and then adding R to the resulting type.

So if I want to extend the typography object to accept a secondaryFontFamily I would have to do something like this:

declare module "@material-ui/core/styles/createTypography" {
   interface TypographyOptions {
      secondaryFontFamily: string;
   }
   interface Typography {
      secondaryFontFamily: string;
   }
}
load more v
60%

In this article, I will demonstrate how to create a React application that supports multiple themes using Material UI and TypeScript. Let’s get started!,The usual drill, create a TypeScript based React application using create-react-app and add Material UI as a dependency.,You can see the full implementation on material-ui-multiple-themes repository on GitHub.

The usual drill, create a TypeScript based React application using create-react-app and add Material UI as a dependency.

npx create - react - app material - ui - multiple - themes--template typescript
cd material - ui - multiple - themes
npm install--save @material - ui / core
load more v
48%

, then when you want to use a value from the Theme, TypeScript will complain that this property is not defined on the type Theme:,If you’re creating a custom theme object and provide it to the ThemeProvider, you’ll notice that TypeScript complains when you’re reading a value from a custom property on the type Theme (ie in a makeStyles function). For example, if your custom theme object looks something like:,Material UI docs suggest to exploit TypeScript’s module augmentation feature to extend the Theme type with your custom properties. However, you still need to manually define those properties and their types. Wouldn’t it be nice for TypeScript to infer those properties and their values from our theme object? By using module augmentation, mapped types, and const assertions, you can achieve that like this:

If you’re creating a custom theme object and provide it to the ThemeProvider, you’ll notice that TypeScript complains when you’re reading a value from a custom property on the type Theme (ie in a makeStyles function). For example, if your custom theme object looks something like:

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

// A custom theme for this app
const theme = {
   palette: {
      primary: {
         main: '#556cd6',
      },
      secondary: {
         main: '#19857b',
      },
      error: {
         main: red.A400,
      },
      background: {
         default: '#fff',
      },
   },
   sidebarWidth: 240
};

export default createTheme(theme);
load more v

Other "custom-material" queries related to "How to use Material UI custom theme in React with Typescript"