开发者问题收集

如何将 MUI 主题与汇总捆绑在一起

2021-08-21
2592

我一直在努力将我们现有的 React FE 组件从主存储库中拉出,并将其放入一个单独的存储库中,并与汇总捆绑在一起。我们的旧代码使用的是 makeStyles ,我已经将其切换到 styled-components ,但仍保留以前的 MUI 主题。我已经设置了 Storybook,并将其包装在样式化组件主题提供程序中,以便访问样式化组件内的主题。

结构看起来像

components
  \src
    index.ts(imports and exports components)
    \theme(MUI theme)
    \components
      \buttons
        button.tsx(react button code)
        index.ts(imports and exports button)
  \lib(rollup spits this out)

最后,回答这个问题。在我将所有内容与汇总捆绑在一起后,我执行了 NPM 安装,并将其导入到另一个项目中。问题是,我没有在导入的组件中获得正确的主题。这是我的按钮的一个稍微简化的版本。

import React from "react";
import { Button as MaterialButton, ButtonProps } from "@material-ui/core";
import styled from "styled-components";

export interface MyButtonProps extends ButtonProps {
  error?: boolean;
  target?: string;
}

const StyledButton = styled(MaterialButton)`
  &.error {
    background: ${(props) => props.theme.palette.error.main};
    color: #fff;
    &:hover {
      background: ${(props) => props.theme.palette.error.main};
    }
  }
`;

const Button = ({
  error,
  className,
  ...rest}: MyButtonProps) => {
  className += error ? " error" : "";
  return (
    <StyledButton
      {...rest}
      className={className}
    >
      {children}
    </StyledButton>
  );
};

export default Button;

因此,如果我在按钮上放置 error 属性,我确实会从我的主题中获得正确的颜色。但是,如果我输入 color="primary" ,则无法获得正确的颜色。我也没有主题中的任何基本样式。

我还没能弄清楚如何将此主题放入我与汇总捆绑的组件中。最后,这是我的汇总配置。

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import postcss from "rollup-plugin-postcss";
import svg from "rollup-plugin-svg-import";

const packageJson = require("./package.json");

export default {
  input: "src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true,
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true,
    },
  ],
  plugins: [
    peerDepsExternal(),
    resolve(),
    commonjs(),
    svg(),
    typescript({ useTsconfigDeclarationDir: true }),
    postcss({
      extensions: [".css"],
    }),
  ],
};

1个回答

对于任何偶然发现这个问题并对答案感到好奇的人。以下是我最终做的事情。希望这是正确的解决方案。有一件事很令人沮丧,我最终得到了 MUI ThemeProvider 给我它生成的类名。这意味着在我的样式组件中,我偶尔需要这样做来定位 [class^="MuiSvgIcon-root"] 的东西,但也许我可以通过 props 访问该类,仍然会弄乱它。无论如何,这是按钮。

import React from "react";
import { Button as MaterialButton, ButtonProps } from "@material-ui/core";
import styled from "styled-components";
import { ThemeProvider } from "@material-ui/core/styles";
import theme from "../../../theme";

export interface MyButtonProps extends ButtonProps {
  error?: boolean;
  target?: string;
}

const StyledButton = styled(MaterialButton)`
  &.error {
    background: ${theme.palette.error.main};
    color: #fff;
    &:hover {
      background: ${theme.palette.error.main};
    }
  }
`;

const Button = ({
  error,
  size,
  variant,
  endIcon,
  children,
  className,
  ...rest
}: MyButtonProps) => {
  if (className && error) {
    className += " error";
  } else if (!className && error) {
    className = "error";
  }

  return (
    <ThemeProvider theme={theme}>
      <StyledButton
        {...rest}
        variant={variant}
        size={size}
        endIcon={endIcon}
        className={className}
      >
        {children}
      </StyledButton>
    </ThemeProvider>
  );
};

export default Button;

我猜每个组件都需要包装。

Joe Madden
2021-09-01