mui / mui/material-ui

I hope to use storybook MUI to create the new UI library, but the themes from material ui and joy ui can not work together, help me please.

Open
#43,238 3 comments 0 reactions 1 assignee View on GitHub

@siriwatknp is already working on this.

Since Aug 12, 2024.

customization: theme on hold package: joy-ui scope: all components
Dominant language
JavaScript
Stars
99.1k
Forks
32.5k
Avg merge
2d 17h
Merged PRs (30d)
106

Description

Steps to reproduce

Link to live example: (required)

Steps:

  1. I create the .storybook/preview.tsx, to confirm the mui material and mui joy working together
// .storybook/preview.ts
import React, { FC, ReactNode, Suspense, useMemo } from 'react';
import type { Preview } from '@storybook/react';
// import { I18nextProvider  } from '@storybook/react';
import { I18nextProvider } from 'react-i18next';
import i18n from '../src/i18n'; // Adjust the path if necessary
import { withThemeFromJSXProvider } from '@storybook/addon-themes';
import { ThemeProvider, StyledEngineProvider } from '@mui/material';

import {
    experimental_extendTheme as materialExtendTheme,
    Experimental_CssVarsProvider as MaterialCssVarsProvider,
    THEME_ID as MATERIAL_THEME_ID,
} from '@mui/material/styles';
import {
    CssVarsProvider as JoyCssVarsProvider,
    ThemeProvider as JoyThemeProvider,
    THEME_ID as JOY_THEME_ID,
} from '@mui/joy/styles';
import CssBaseline from '@mui/material/CssBaseline';

import { darkTheme } from '../src/themes/dark.theme';
import { lightTheme } from '../src/themes/light.theme';
import { joyThemes } from '../src/themes/joy.themes';

// import '../src/index.css';

import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';
import '@fontsource/material-icons';

const THEMES = {
    light: lightTheme,
    dark: darkTheme,
};

// Decorator to wrap stories with I18nextProvider
const withI18next = (Story: FC) => {
    return (
        // This catches the suspense from components not yet ready (still loading translations)
        // Alternative: set useSuspense to false on i18next.options.react when initializing i18next
        <Suspense fallback={<div>loading translations...</div>}>
            <I18nextProvider i18n={i18n}>
                <Story />
            </I18nextProvider>
        </Suspense>
    );
};

const withTheme = (Story: FC, context) => {
    const { theme: themeKey } = context.globals;
    const theme = useMemo(
        () => THEMES[themeKey] || THEMES['light'],
        [themeKey]
    );

    // const materialTheme = materialExtendTheme();

    return (
        <StyledEngineProvider injectFirst>
            {/* <ThemeProvider theme={theme}> */}
            <ThemeProvider theme={{ [MATERIAL_THEME_ID]: theme }}>
                <MaterialCssVarsProvider theme={joyThemes}>
                    <CssBaseline enableColorScheme />
                    <Story />
                </MaterialCssVarsProvider>
                </ThemeProvider>
            {/* </ThemeProvider> */}
        </StyledEngineProvider>
    );
};

const withNewTheme = withThemeFromJSXProvider({
    themes: {
        light: lightTheme,
        dark: darkTheme,
    },
    defaultTheme: 'light',
    Provider: ThemeProvider,
    GlobalStyles: CssBaseline,
});

const preview: Preview = {
    decorators: [withI18next, withTheme], // Add the i18n decorator here
    parameters: {
        actions: { fn: '^on[A-Z].*' },
        controls: {
            expanded: true, // will show all controls by default
            matchers: {
                color: /(background|color)$/i,
                date: /Date$/i,
            },
        },
    },
};

export default preview;

  1. I hope to apply theme on the new Ui library;
  2. I create the 'joy.themes.ts' to confirm the 'JoyInput' component;
import { extendTheme } from '@mui/joy/styles';

export const joyThemes = extendTheme({
    colorSchemes: {
        dark: {
            palette: {
                primary: {
                    50: '#C0CCD9',
                    100: '#A5B8CF',
                    200: '#6A96CA',
                    300: '#f00',
                    400: '#0f0',
                    500: '#00f',
                    600: '#1B62B5',
                    700: '#265995',
                    800: '#2F4968',
                    900: '#ddd',
                },
            },
        },
        light: {
            palette: {
                primary: {
                    50: '#232323',
                    100: '#C2D0E3',
                    200: '#8AA4C8',
                    300: '#f0f',
                    400: '#ff0',
                    500: '#0ff',
                    600: '#005FA5',
                    700: '#00508D',
                    800: '#00426F',
                    900: '#333',
                },
            },
        },
    },
    components: {
        JoyInput: {
            styleOverrides: {
                root: ({ theme, ownerState }) => {
                    console.log('JoyInput theme applied', { theme, ownerState });
                    return {
                        ...(ownerState.variant === 'solid' && {
                            backgroundColor: theme.vars.palette.primary[300],
                        })
                    }
                }
            }
        },
    },
});

// Then, pass it to `<CssVarsProvider theme={theme}>`.

  1. I also create the Input component.
import React from 'react';
import { cva, VariantProps } from 'class-variance-authority';
import { cn } from '../../utils/index';
import { Input as JoyInput, InputProps as JoyInputProps } from '@mui/joy';
import styles from './customize.module.css';

const InputStyles = cva([''], {
    variants: {
        size: {
            lg: styles.large,
            md: styles.medium,
            sm: styles.small,
        },
    },
    compoundVariants: [
        {
            size: 'lg',
        },
    ],
    defaultVariants: {
        size: 'lg',
    },
});

type InputBaseProps = Pick<
    JoyInputProps,
    | 'variant'
    | 'startDecorator'
    | 'endDecorator'
    | 'disabled'
    | 'onChange'
    | 'type'
    | 'placeholder'
> &
    VariantProps<typeof InputStyles>;

export interface InputProps extends InputBaseProps {
    className?: string;
    style?: React.CSSProperties;
}

export const Input = ({ className, style, size, ...rest }: InputProps) => {
    return (
        <JoyInput
            {...rest}
            className={cn(InputStyles({ size }), className)}
            style={style}
        />
    );
};

  1. I also created Button component by using Button from '@mui/material', the button can applied the proper theme color, but the 'Input' component not working well, he only can show light theme color, but not work on dark theme color.
Current behavior

the JoyInput component theme is working fine on 'light' only

Expected behavior

i hope that the JoyInput component can work on both themes. I hope that the 'backgroundColor' become 'red' when in dark theme.

Context

I hope to create the new UI library.

Your environment
npx @mui/envinfo
  Don't forget to mention which browser you used.
  Output from `npx @mui/envinfo` goes here.

Search keywords: storybook, MUI, @mui/material, @mui/joy

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.