Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
122 lines
4.3 KiB
Markdown
122 lines
4.3 KiB
Markdown
# Using Joy UI and Material UI together
|
||
|
||
<p class="description">Learn how to use Joy UI and Material UI together in the same project.</p>
|
||
|
||
## Introduction
|
||
|
||
There are two main use cases for using them together:
|
||
|
||
1. Your existing project already uses Material UI but you're willing to explore the new components and style Joy UI offers.
|
||
2. You've started your project with Joy UI but you find a key component you need is missing.
|
||
|
||
:::info
|
||
Once Joy UI reaches component parity with Material UI, we recommend that you **_choose one or the other_**. Not only do they have a different design language (and therefore a different theme structure) but they would increase your bundle size as well as potentially create unnecessary complexities.
|
||
:::
|
||
|
||
Additionally, keep these in mind when using them together:
|
||
|
||
- Both of them use [MUI System](/system/getting-started/) as their style engine, which uses React context for theming.
|
||
- Theme scoping must be done on one of the libraries.
|
||
|
||
### Prerequisites
|
||
|
||
- Have `@mui/material` and `@mui/joy` installed in your project.
|
||
- The version of both libraries must be [v5.12.0](https://github.com/mui/material-ui/releases/tag/v5.12.0) or higher.
|
||
|
||
## Set up the providers
|
||
|
||
Render Joy UI's `CssVarsProvider` inside Material UI's `ThemeProvider` and use `THEME_ID` to separate the themes from each other.
|
||
|
||
```js
|
||
import {
|
||
createTheme,
|
||
ThemeProvider,
|
||
THEME_ID as MATERIAL_THEME_ID,
|
||
} from '@mui/material/styles';
|
||
import { CssVarsProvider as JoyCssVarsProvider } from '@mui/joy/styles';
|
||
import CssBaseline from '@mui/material/CssBaseline';
|
||
|
||
const materialTheme = createTheme();
|
||
|
||
export default function App() {
|
||
return (
|
||
<ThemeProvider theme={{ [MATERIAL_THEME_ID]: materialTheme }}>
|
||
<JoyCssVarsProvider>
|
||
<CssBaseline enableColorScheme />
|
||
...Material UI and Joy UI components
|
||
</JoyCssVarsProvider>
|
||
</ThemeProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
<iframe src="https://codesandbox.io/embed/using-joy-ui-and-material-ui-together-qrsz2h?module=%2Fdemo.tsx&fontsize=14&hidenavigation=1&theme=dark&view=preview"
|
||
style="width:100%; height:400px; border:0; border-radius: 4px; overflow:hidden;"
|
||
title="Joy UI - Human Interface Guidelines Typography System"
|
||
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
|
||
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||
></iframe>
|
||
|
||
### Sync the color mode
|
||
|
||
To sync the color mode between the providers, call `setMode` from both of the libraries:
|
||
|
||
```js
|
||
import { useColorScheme as useJoyColorScheme } from '@mui/joy/styles';
|
||
import { useColorScheme as useMaterialColorScheme } from '@mui/material/styles';
|
||
|
||
const ModeToggle = () => {
|
||
const { mode, setMode: setMaterialMode } = useMaterialColorScheme();
|
||
const { setMode: setJoyMode } = useJoyColorScheme();
|
||
const [mounted, setMounted] = React.useState(false);
|
||
React.useEffect(() => {
|
||
setMounted(true);
|
||
}, []);
|
||
if (!mounted) {
|
||
// prevent server-side rendering mismatch
|
||
// because `mode` is undefined on the server.
|
||
return null;
|
||
}
|
||
return (
|
||
<IconButton
|
||
onClick={() => {
|
||
setMaterialMode(mode === 'dark' ? 'light' : 'dark');
|
||
setJoyMode(mode === 'dark' ? 'light' : 'dark');
|
||
}}
|
||
>
|
||
{/** You can use `mode` from Joy UI or Material UI since they are synced **/}
|
||
{mode === 'dark' ? <DarkMode /> : <LightMode />}
|
||
</IconButton>
|
||
);
|
||
};
|
||
```
|
||
|
||
## Caveat
|
||
|
||
Both libraries have the same class name prefix:
|
||
|
||
```js
|
||
import MaterialTypography, {
|
||
typographyClasses as materialTypographyClasses,
|
||
} from '@mui/material/Typography';
|
||
import JoyTypography, {
|
||
typographyClasses as joyTyographyClasses,
|
||
} from '@mui/joy/Typography';
|
||
import Stack from '@mui/material/Stack';
|
||
|
||
<Stack
|
||
sx={{
|
||
// similar to `& .${joyTyographyClasses.root}`
|
||
[`& .${materialTypographyClasses.root}`]: {
|
||
color: 'red',
|
||
},
|
||
}}
|
||
>
|
||
{/* Both components are red. */}
|
||
<MaterialTypography>Red</MaterialTypography>
|
||
<JoyTypography>Red</JoyTypography>
|
||
</Stack>;
|
||
```
|
||
|
||
Joy UI and Material UI components have a different name for [theming the components](/joy-ui/customization/themed-components/#component-identifier). For example, Joy UI's Button uses `JoyButton` whereas Material UI's Button uses `MuiButton`.
|