使用 Material UI 创建自定义变体

Mos*_*she 18 javascript reactjs material-ui

我正在尝试为 Material UI 中的组件创建自定义变体Button

我的第一步是Button使用我想要的样式创建一个基于组件的组件:

// CTA.js

import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";

const useStyles = makeStyles({
  root: { // CUSTOM__STYLES },
  label: { // CUSTOM__STYLES },
});

const CTA = ({ children }) => {
  const classes = useStyles();

  return (
    <Button
      classes={{
        root: classes.root, 
        label: classes.label,
      }}
    >
      {children}
    </Button>
  );
};
Run Code Online (Sandbox Code Playgroud)

然后,我将该组件导入到Button我正在创建的新组件中,如下所示:

// Button.js
import MuiButton from "@material-ui/core/Button";
import CTA from "./CTA";

const Button = ({ variant, ...muiButtonProps }) => {
  if (variant === "cta") {
    return <CTA {...muiButtonProps} />;
  }
  return <MuiButton {...muiButtonProps} />;
};
Run Code Online (Sandbox Code Playgroud)

现在,我想要的是能够导入我的新Button组件并使其像常规 Material-UI 按钮组件一样工作,但添加了variant="cta". 然而,它并不完全有效。

例如,看一下以下内容:

// Header.js
import { Button as MuiButton } from "@material-ui/core";
import { Button } from "@/theme/button.js";

...

<MuiButton variant="outlined">Mui Button</MuiButton>  // works
<Button variant="outlined">Button</Button> // does not work
<Button variant="cta">CTA Button</Button>  // works
Run Code Online (Sandbox Code Playgroud)

我发现我的新自定义 Button 组件在使用 时可以工作variant="cta",但在使用任何内置 Material-UI 变体选项时则不起作用。我不知道那是什么。我本以为这<Button variant="outlined">会像 一样工作<MuiButton variant="outlined">。但事实并非如此。

知道为什么不以及如何解决它吗?

Nea*_*arl 49

在 Material-UI v5 中,您可以轻松地为组件创建新变体(请参阅此RFC中支持的组件列表)createTheme(),从而无需创建包装器组件。下面是最小的例子:

const theme = createTheme({
  components: {
    MuiButton: {
      variants: [
        {
          props: { variant: 'dashed' },
          style: {
            textTransform: 'none',
            border: `2px dashed grey${blue[500]}`,
          },
        },
      ],
    },
  },
});
Run Code Online (Sandbox Code Playgroud)
export default function Demo() {
  return (
    <ThemeProvider theme={theme}>
      <Button variant="outlined">
        Outline
      </Button>
      <Button variant="dashed">
        Dashed
      </Button>
    </ThemeProvider>
  );
}
Run Code Online (Sandbox Code Playgroud)

对于打字稿用户,您还需要使用模块增强来更新变体定义。

declare module '@mui/material/Button' {
  interface ButtonPropsVariantOverrides {
    dashed: true;
  }
}
Run Code Online (Sandbox Code Playgroud)

现场演示

编辑 GlobalThemeVariants 材质演示

  • `createMuiTheme` 已被弃用,我们应该使用 `createTheme` (2认同)

Jak*_*mle 6

有两种选择,它不起作用,因为您破坏了“变体”并且不将其转发到您的 MuiButton。

你可以在 Button.js 中这样做

const Button = ({ variant, ...muiButtonProps }) => {
  if (variant === "cta") {
    return <CTA {...muiButtonProps} />;
  }
  return <MuiButton variant={variant} {...muiButtonProps} />;
};
Run Code Online (Sandbox Code Playgroud)

或者

const Button = (muiButtonProps) => {
  if (muiButtonProps.variant === "cta") {
    return <CTA {...muiButtonProps} />;
  }
  return <MuiButton {...muiButtonProps} />;
};
Run Code Online (Sandbox Code Playgroud)

查看文档: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

// Stage 4(finished) proposal
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
Run Code Online (Sandbox Code Playgroud)