Material-ui @next自定义按钮颜色?

Nem*_* Ga 8 javascript material-ui

我正在努力修改Material-UI @ next(v1)中的按钮颜色.

我如何将muitheme设置为与bootstrap相似,所以我可以使用"btn-danger"表示红色,"btn-success"表示绿色...?

我尝试使用自定义className但它无法正常工作(悬停颜色不会改变),它似乎重复.我有什么选择?

Nea*_*arl 59

Material UI v5中,这就是您在主题中为 Material UI 创建自定义颜色的方法Button。原色和次色的创建方式相同

const { palette } = createTheme();
const { augmentColor } = palette;
const createColor = (mainColor) => augmentColor({ color: { main: mainColor } });
const theme = createTheme({
  palette: {
    anger: createColor('#F40B27'),
    apple: createColor('#5DBA40'),
    steelBlue: createColor('#5C76B7'),
    violet: createColor('#BC00A3'),
  },
});
Run Code Online (Sandbox Code Playgroud)

用法

<Button color="anger" variant="contained">
  anger
</Button>
<Button color="apple" variant="contained">
  apple
</Button>
<Button color="steelBlue" variant="contained">
  steelBlue
</Button>
<Button color="violet" variant="contained">
  violet
</Button>
Run Code Online (Sandbox Code Playgroud)

如果您使用的是打字稿,您还需要为刚刚定义的颜色添加其他类型:

declare module '@mui/material/styles' {
  interface CustomPalette {
    anger: PaletteColorOptions;
    apple: PaletteColorOptions;
    steelBlue: PaletteColorOptions;
    violet: PaletteColorOptions;
  }
  interface Palette extends CustomPalette {}
  interface PaletteOptions extends CustomPalette {}
}

declare module '@mui/material/Button' {
  interface ButtonPropsColorOverrides {
    anger: true;
    apple: true;
    steelBlue: true;
    violet: true;
  }
}
Run Code Online (Sandbox Code Playgroud)

现场演示

Codesandbox 演示

相关答案

  • 这样一来,事情就变得复杂了…… (6认同)
  • 我不同意@shen,这使得我的组件更容易设计样式,因为它不再需要为不同状态(悬停、选定等)设置属性。AugmentColor 尤其使我的主题更加清晰,因为它现在允许我生成不同的颜色深浅,而无需对每种颜色进行硬编码。现在我可以为不同的按钮状态提供特定的变体。谢谢@NearHuscarl!! (5认同)
  • 这比“mui”文档更好地解释了“颜色的其他类型” (2认同)

小智 14

我在这个帖子中使用Brendans的答案提出了这个解决方案.希望它能帮助处于类似情况的人.

import React, { Component } from 'react'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles'
import Button from 'material-ui/Button'
import { red, blue } from 'material-ui/colors'

const redTheme = createMuiTheme({ palette: { primary: red } })
const blueTheme = createMuiTheme({ palette: { primary: blue } })

class Buttons extends Component {
  render = () => (
    <div className="ledger-actions-module">
      <MuiThemeProvider theme={redTheme}>
        <Button color="primary" variant="raised">
          Delete
        </Button>
      </MuiThemeProvider>
      <MuiThemeProvider theme={blueTheme}>
        <Button color="primary" variant="raised">
          Update
        </Button>
      </MuiThemeProvider>
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一种解决方法,而不是真正的解决方案。我们应该能够使用简单的主题配置创建自定义按钮。 (4认同)
  • 对于 v4 `import { ThemeProvider } from '@material-ui/styles';` `import { createMuiTheme } from "@material-ui/core/styles";` (2认同)
  • 关于性能的警告 -&gt; 如果您有一个包含 n 个项目的列表,每个项目都需要红色和蓝色按钮怎么办?这将需要 n * 2 个主题提供者,并且最终可能会导致浏览器崩溃。开发人员也不太友好,因为这需要大量样板代码来设置颜色。我发布了一个可能的解决方案,允许下面的“&lt;Button color="error"&gt;”等。 (2认同)

Jul*_*ano 10

尝试这个:

import * as React from 'react';
import Button, { ButtonProps } from "@material-ui/core/Button";
import { Theme } from '@material-ui/core';
import { withStyles } from '@material-ui/styles';

const styles: (theme: Theme) => any = (theme) => {
    return {
        root:{
            backgroundColor: theme.palette.error.main,
            color: theme.palette.error.contrastText,
            "&:hover":{
                backgroundColor: theme.palette.error.dark
            },
            "&:disabled":{
                backgroundColor: theme.palette.error.light
            }
        }
    };
};

export const ButtonContainedError = withStyles(styles)((props: ButtonProps) => {
    const { className, ...rest } = props;
    const classes = props.classes||{};
    return <Button {...props} className={`${className} ${classes.root}`} variant="contained" />
});
Run Code Online (Sandbox Code Playgroud)

现在你有一个 ButtonContainedError 可以在任何地方使用。

并且与你的主题一致。


Bre*_*ill 9

Bagelfp的回答有一个错误,还有其他一些需要考虑的事情;

首先,'error'不是material-ui @ next v1的Button组件中支持的颜色主题.颜色道具只接受"默认","继承","主要"和"次要".

到目前为止,我发现这是最简单的方法.首先,选择两种最常见的主题颜色,并将它们放在应用程序的根目录下.

import React from 'react';
import { Component } from './Component.js'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';

const theme = createMuiTheme({
  palette: {
    primary: purple,
    secondary: green,
    error: red,
  },
});

export class App extends Component {
  render() {
    return (
      <MuiThemeProvider theme={theme}>
        <Component />
        ...
      </MuiThemeProvider>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的Component中,只需选择具有所需颜色的主题;

import React from 'react';
import Button from 'material-ui/Button';

export const Component = (props) => (
  <div>
    <Button variant="fab" color="primary">
      I am purple, click me!
    </Button>
  </div>
)
Run Code Online (Sandbox Code Playgroud)

如果你需要第三种和第四种颜色,你可以像在App.js中一样使用新的托盘导出Component.js.

这是我发现的唯一一个允许我保留黑暗悬停效果的解决方案(官方覆盖示例都没有保留功能悬停).我真的希望我能找到一种方法,在调用Button时简单地放入一个新的主题颜色,但是现在这是最简单的方法.

编辑:我新的首选方法是使用styled-components和material-ui buttonbase创建一个CustomButton组件.我还将样式组件主题提供程序放在我的应用程序的根目录旁边,与我的MuiThemeProvider一起.这使我可以轻松访问所有样式组件中的其他主题颜色,而无需导入和删除更多的ThemeProviders.在我的CustomButton的情况下,我只是给它一个theme道具,它直接传递给css in styled(ButtonBase).有关详细信息,请参阅样式组件文档.


Ada*_*per 7

这是一个示例打字稿实现:

import React from "react";
import { createStyles, Theme, makeStyles } from "@material-ui/core/styles";
import capitalize from "lodash/capitalize";

import MuiButton, {
  ButtonProps as MuiButtonProps
} from "@material-ui/core/Button";

export type ColorTypes =
  | "primary"
  | "secondary"
  | "error"
  | "success"
  | "warning"
  | "default"
  | "inherit"
  | "info";

type ButtonProps = { color: ColorTypes } & Omit<MuiButtonProps, "color">;

const useStyles = makeStyles<Theme>(theme =>
  createStyles({
    outlinedSuccess: {
      borderColor: theme.palette.success.main,
      color: theme.palette.success.main
    },
    outlinedError: {
      borderColor: theme.palette.error.main,
      color: theme.palette.error.main
    },
    outlinedWarning: {
      borderColor: theme.palette.warning.main,
      color: theme.palette.warning.main
    },
    outlinedInfo: {
      borderColor: theme.palette.info.main,
      color: theme.palette.info.main
    },
    containedSuccess: {
      backgroundColor: theme.palette.success.main,
      color: theme.palette.success.contrastText,
      "&:hover": {
        backgroundColor: theme.palette.success.dark
      }
    },
    containedError: {
      backgroundColor: theme.palette.error.main,
      color: theme.palette.error.contrastText,
      "&:hover": {
        backgroundColor: theme.palette.error.dark
      }
    },
    containedWarning: {
      backgroundColor: theme.palette.warning.main,
      color: theme.palette.warning.contrastText,
      "&:hover": {
        backgroundColor: theme.palette.warning.dark
      }
    },
    containedInfo: {
      backgroundColor: theme.palette.info.main,
      color: theme.palette.info.contrastText,
      "&:hover": {
        backgroundColor: theme.palette.info.dark
      }
    }
  })
);

const Button: React.FC<ButtonProps> = ({ children, color, ...props }) => {
  const classes = useStyles();
  const className = classes?.[`${props.variant}${capitalize(color)}`];
  const colorProp =
    ["default", "inherit", "primary", "secondary"].indexOf(color) > -1
      ? (color as "default" | "inherit" | "primary" | "secondary")
      : undefined;

  return (
    <MuiButton {...props} color={colorProp} className={className}>
      {children}
    </MuiButton>
  );
};

Button.displayName = "Button";

export default Button;

Run Code Online (Sandbox Code Playgroud)

有了这个,你可以<Button variant="contained" color="success">使用自动完成和警告免费:)


Adn*_*hah 6

你可以试试这个

<Button
    style={{
        borderRadius: 35,
        backgroundColor: "#21b6ae",
        padding: "18px 36px",
        fontSize: "18px"
    }}
    variant="contained"
    >
    Submit
</Button>
Run Code Online (Sandbox Code Playgroud)

  • 内联样式是一个 hacky 解决方案 (10认同)

Far*_*rin 6

首先尝试安装 npm install @material-ui/styles 根据材料文档应用样式,对于 React 类组件,您可以使用以下代码:

import React, {Component} from "react";
import { styled } from '@material-ui/styles';
import Button from '@material-ui/core/Button';

const MyButton = styled(Button)({
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
});
class AprinClass extends Component {
    render() {
        return (
            <MyButton>Styled Components</MyButton>
        )
    }
}
export default AprinClass;
Run Code Online (Sandbox Code Playgroud)

有关更多信息和参考资料,请查看我的 Medium 博客。 https://medium.com/@farbodaprin/how-to-make-a-customisable-material-ui-button-a85b6534afe5


小智 6

您可以使用theme.palette.getContrastText()根据背景颜色值计算正确的文本颜色。

import { Button, makeStyles } from '@material-ui/core';

const useStyles = makeStyles((theme) => ({
  deleteButton: {
    // to make a red delete button
    color: theme.palette.getContrastText(theme.palette.error.main),
    background: theme.palette.error.main,
  }
}));

export const DeleteButton = () => {
  const classes = useStyles();
  return (
    <Button className={classes.deleteButton}>Delete</Button>
  );
}
Run Code Online (Sandbox Code Playgroud)


Bag*_*lfp 4

您可以创建一个theme为 3 个受支持的调色板intentions(主要、次要、错误)定义的调色板,然后使用colorprop on<Button>来使用这些调色板。在你的例子中btn-danger可能是<Button color='error'>

编辑:布伦丹的答案在这里是正确的,但error不支持Button. 根据文档,Button仅支持“对此组件有意义”的意图,因此只有primarysecondary可以在这里工作。

来自他们的文档(此处稍作删减):

const theme = createMuiTheme({
  palette: {
    primary: purple,
    secondary: red
  }
});

function Palette() {
  return (
    <MuiThemeProvider theme={theme}>
      <div>
        <Button color="primary">{'Primary'}</Button>
        <Button color="secondary">{'Secondary'}</Button>
      </div>
    </MuiThemeProvider>
  );
}
Run Code Online (Sandbox Code Playgroud)

有关为组件创建主题的更实际示例,请参阅Brendan 的答案。