Felix Astner
JavaScript, Magento and other Software
Felix Astner

Enhancing MUI Theming with TypeScript: Custom Variants and Styles

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.


profile

Felix Astner

As a software developer, I bring a specialized focus in web technologies, enriched by my interests in C++, AI, and computer theory. If you're in need of any freelance services, expert training, or insightful consulting, I encourage you to connect with me.

HomePrivacyImpressum