将 MUI 主题拆分为单独的文件

问题描述 投票:0回答:1

在我的 Next.js 项目中,我在

index.ts
文件夹中有这个
src/theme

'use client'; // necessary for MUI to work with nextjs (SSR)
import { createTheme } from '@mui/material/styles';
import { typography } from './typography';
import { palette } from './palette';

const theme = createTheme({
  palette,
  typography,
  components: {
    MuiButton: {
      styleOverrides: {
        root: {
          borderRadius: 8,
        }
      },
      variants: [
        {
          props: { variant: 'primary' },
          style: {
            backgroundColor: '#FFCB3C',
            color: '#1A334D',
            '&:hover': {
              backgroundColor: '#FFAA01',
            },
          },
        },
        {
          props: { variant: 'complementaryPrimary' },
          style: {
            backgroundColor: '#a09a88',
            color: '#ffffff',
            '&:hover': {
              backgroundColor: '#FFAA01',
            },
          },
        }
      ],
    }
  },
});

export default theme;

这工作没有问题,我创建了新的变体。我还从他们自己的

palette
文件导入
typography
.ts

问题是,如果我想重构它并创建一个

buttonStyles.ts
文件

const buttonStyles = {
  MuiButton: {
    styleOverrides: {
      root: {
        borderRadius: 8,
      }
    },
    variants: [
      {
        props: { variant: 'primary' },  // Ensure this is correctly recognized by TS as augmented
        style: {
          backgroundColor: '#FFCB3C',
          color: '#1A334D',
          '&:hover': {
            backgroundColor: '#FFAA01',
          },
        },
      },
      {
        props: { variant: 'complementaryPrimary' },  // Ensure this is correctly recognized by TS as augmented
        style: {
          backgroundColor: '#a09a88',
          color: '#ffffff',
          '&:hover': {
            backgroundColor: '#FFAA01',
          },
        },
      }
    ],
  },
}

export default buttonStyles;

并将其导入到

index.ts
文件中:

'use client'; // necessary for MUI to work with nextjs (SSR)
import { createTheme } from '@mui/material/styles';
import buttonStyles from './buttonStyles';
import { typography } from './typography';
import { palette } from './palette';

const theme = createTheme({
  palette,
  typography,
  components: {
    ...buttonStyles,
  },
});

export default theme;

它一直因这个错误而失败

Type '{ MuiButton: { styleOverrides: { root: { borderRadius: number; }; }; variants: { props: { variant: string; }; style: { backgroundColor: string; color: string; '&:hover': { backgroundColor: string; }; }; }[]; }; }' is not assignable to type 'Components<Omit<Theme, "components">>'.
  The types of 'MuiButton.variants' are incompatible between these types.
    Type '{ props: { variant: string; }; style: { backgroundColor: string; color: string; '&:hover': { backgroundColor: string; }; }; }[]' is not assignable to type '{ props: Partial<ButtonProps> | ((props: Partial<ButtonProps> & { ownerState: Partial<ButtonProps>; }) => boolean); style: Interpolation<...>; }[]'.
      Type '{ props: { variant: string; }; style: { backgroundColor: string; color: string; '&:hover': { backgroundColor: string; }; }; }' is not assignable to type '{ props: Partial<ButtonProps> | ((props: Partial<ButtonProps> & { ownerState: Partial<ButtonProps>; }) => boolean); style: Interpolation<...>; }'.
        Types of property 'props' are incompatible.
          Type '{ variant: string; }' is not assignable to type 'Partial<ButtonProps> | ((props: Partial<ButtonProps> & { ownerState: Partial<ButtonProps>; }) => boolean)'.
            Type '{ variant: string; }' is not assignable to type 'Partial<ButtonProps>'.
              Types of property 'variant' are incompatible.
                Type 'string' is not assignable to type 'OverridableStringUnion<"text" | "outlined" | "contained", ButtonPropsVariantOverrides> | undefined'.ts(2322)
(property) ThemeOptions.components?: Components<Omit<Theme, "components">> | undefined

我不知道为什么如果我把它写在

index.ts
它可以工作,如果没有,它就不行。我尝试了不同的方式来导入它:

components: {
    ...buttonStyles,
  },

components: {
    ...buttonStyles.MuiButton,
  },

我明白了

Type '{ styleOverrides: { root: { borderRadius: number; }; }; variants: { props: { variant: string; }; style: { backgroundColor: string; color: string; '&:hover': { backgroundColor: string; }; }; }[]; }' has no properties in common with type 'Components<Omit<Theme, "components">>'.ts(2559)
(property) ThemeOptions.components?: Components<Omit<Theme, "components">> | undefined

  components: {
    MuiButton: {...buttonStyles},
  },

更新后

buttonStyles.ts
这样

const buttonStyles = {
  styleOverrides: {
    root: {
      borderRadius: 8,
    }
  },
  variants: [
    {
      props: { variant: 'primary' },  // Ensure this is correctly recognized by TS as augmented
      style: {
        backgroundColor: '#FFCB3C',
        color: '#1A334D',
        '&:hover': {
          backgroundColor: '#FFAA01',
        },
      },
    },
    {
      props: { variant: 'complementaryPrimary' },  // Ensure this is correctly recognized by TS as augmented
      style: {
        backgroundColor: '#a09a88',
        color: '#ffffff',
        '&:hover': {
          backgroundColor: '#FFAA01',
        },
      },
    }
  ],

}

export default buttonStyles;

我收到这个错误

Type '{ styleOverrides: { root: { borderRadius: number; }; }; variants: { props: { variant: string; }; style: { backgroundColor: string; color: string; '&:hover': { backgroundColor: string; }; }; }[]; }' is not assignable to type '{ defaultProps?: Partial<ButtonProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof ButtonClasses, "MuiButton", Omit<Theme, "components">>> | undefined; variants?: { ...; }[] | undefined; }'.
  Types of property 'variants' are incompatible.
    Type '{ props: { variant: string; }; style: { backgroundColor: string; color: string; '&:hover': { backgroundColor: string; }; }; }[]' is not assignable to type '{ props: Partial<ButtonProps> | ((props: Partial<ButtonProps> & { ownerState: Partial<ButtonProps>; }) => boolean); style: Interpolation<...>; }[]'.
      Type '{ props: { variant: string; }; style: { backgroundColor: string; color: string; '&:hover': { backgroundColor: string; }; }; }' is not assignable to type '{ props: Partial<ButtonProps> | ((props: Partial<ButtonProps> & { ownerState: Partial<ButtonProps>; }) => boolean); style: Interpolation<...>; }'.
        Types of property 'props' are incompatible.
          Type '{ variant: string; }' is not assignable to type 'Partial<ButtonProps> | ((props: Partial<ButtonProps> & { ownerState: Partial<ButtonProps>; }) => boolean)'.
            Type '{ variant: string; }' is not assignable to type 'Partial<ButtonProps>'.
              Types of property 'variant' are incompatible.
                Type 'string' is not assignable to type 'OverridableStringUnion<"text" | "outlined" | "contained", ButtonPropsVariantOverrides> | undefined'.ts(2322)
(property) Components<Omit<Theme, "components">>.MuiButton?: {
    defaultProps?: Partial<ButtonProps> | undefined;
    styleOverrides?: Partial<OverridesStyleRules<keyof ButtonClasses, "MuiButton", Omit<Theme, "components">>> | undefined;
    variants?: {
        ...;
    }[] | undefined;
} | undefined

StackOverflow 周围还有一个关于主题组织的问题

如何通过主题选项将MUI v5主题拆分为单独的文件?

但它没有回答我的问题。我应该如何更新我的代码?谢谢!

reactjs typescript next.js material-ui
1个回答
0
投票

必须明确设置类型:

import { Components } from '@mui/material/styles';

export const buttonStyles: Components = {

现在可以了

const theme = createTheme({
  palette,
  typography,
  components: {
    ...buttonStyles,
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.