mui / mui/material-ui

[theme] Custom "Built-in/Default" Theme

Open
#30,037 1 comment 1 reaction 1 assignee View on GitHub

@siriwatknp is already working on this.

Since Dec 6, 2021.

design scope: system
Dominant language
JavaScript
Stars
99.1k
Forks
32.5k
Avg merge
2d 17h
Merged PRs (30d)
106

Description

Summary 💡

When developing a design system/component library on top of MUI components, there should be an easy path to "build in" the Theme that goes with these components and use that theme as the "default theme" for all MUI components as well, or at least pass that theme to the MUI components being wrapped rather than relying on the presence of a wrapping ThemeProvider.

Examples 🌈

We found a way that seems to work but doesn't seem to be documented as a supported method anywhere. We spiked this out and found that using @mui/system's useThemeWithoutDefault and passing in our custom theme as the default and then passing that return value to the theme prop of the MUI component (no official MUI support for this prop, i think this is part of emotion's styled api). This covers a lot of the cases except for nested components within that Root Component.

For example, https://github.com/mui-org/material-ui/blob/master/packages/mui-material/src/LinearProgress/LinearProgress.js#L193 LinearProgressBar1 uses the call theme.palette[ownerState.color].main in its styled implementation, and ownerState in this case is correct but the theme is just the default MUI theme because the ownerState.theme (our theme) is not passed as the theme prop to the inner slot components. This means that the theme will apply to LinearProgress then be completely ignored on the inner slot components. We are able to work around these inconsistencies by writing styles in our wrapper that fix them but that seems a little gross for this particular case.

I took some time and made a simple example codesandbox that demonstrates the above: https://codesandbox.io/s/built-in-default-theme-for-mui-components-sksmu?file=/wrapped-mui/linearprogress.tsx

I am not saying that the above approach is the best for this, maybe there's something that MUI could do to build in support for this so we don't have to do all this finagling, this was just an approach that we discovered could work.

Motivation 🔦

We create a Button component that wraps MUI's Button using the styled API. We build it expecting our custom augmented theme, but when used without a ThemeProvider, it ends up throwing errors, we can code more defensively to prevent the errors, but even then our components end up looking nothing like the design system we are implementing as the expected "out of the box" for this component library.

We could just use a ThemeProvider but some additional reasons this is difficult are:

  • All unit tests that implement our components now require a ThemeProvider with our theme.
  • Our app is very large and contributed to by many different teams, meaning we have many render roots in our app, and it's possible for some places to accidentally not use a ThemeProvider, especially if the root isn't rendering MUI components at the time it's migrated company wide.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.