【发布时间】:2017-09-29 10:07:48
【问题描述】:
我正在努力修改 MUI next (v1) 中的按钮颜色。
我如何设置 muitheme 以表现与引导程序的相似性,所以我可以只使用红色的“btn-danger”,绿色的“btn-success”...?
我尝试使用自定义className,但它不能正常工作(悬停颜色不会改变)并且看起来重复。我有什么选择?
【问题讨论】:
标签: javascript reactjs material-ui
我正在努力修改 MUI next (v1) 中的按钮颜色。
我如何设置 muitheme 以表现与引导程序的相似性,所以我可以只使用红色的“btn-danger”,绿色的“btn-success”...?
我尝试使用自定义className,但它不能正常工作(悬停颜色不会改变)并且看起来重复。我有什么选择?
【问题讨论】:
标签: javascript reactjs material-ui
你可以试试这个
<Button
style={{
borderRadius: 35,
backgroundColor: "#21b6ae",
padding: "18px 36px",
fontSize: "18px"
}}
variant="contained"
>
Submit
</Button>
【讨论】:
我在这个线程中使用 Brendan 的答案提出了这个解决方案。希望它能帮助处于类似情况的人。
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>
)
}
【讨论】:
import { ThemeProvider } from '@material-ui/styles'; import { createMuiTheme } from "@material-ui/core/styles";
<Button color="error"> 等。
Bagelfp 的回答有误,还有一些需要考虑的事情;
首先,material-ui@next v1 的 Button component 中不支持“错误”颜色主题。 color 属性只接受 'default'、'inherit'、'primary' 和 'secondary'。
这是迄今为止我发现的最简单的方法。首先,选择您最常用的两种主题颜色并将它们放在应用的根目录中。
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>
);
}
}
然后在你的组件中,选择你想要的颜色的主题;
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>
)
如果您需要第三种和第四种颜色,您可以像在 App.js 中一样使用新的调色板导出 Component.js。
这是我发现的唯一解决方案,可以让我保留变暗的悬停效果(official override examples 都没有保留功能悬停)。我真的希望我能找到一种在调用 Button 时简单地放入新主题颜色的方法,但目前这是最简单的方法。
编辑:我的新首选方法是使用 styled-components 和 material-ui buttonbase 创建一个 CustomButton 组件。我还将 styled-components 主题提供程序与我的 MuiThemeProvider 放在我的应用程序的根目录中。这使我可以轻松访问所有样式组件中的其他主题颜色,而无需导入和放入更多 ThemeProviders。对于我的 CustomButton,我只是给它一个 theme 属性,它会直接传递给 styled(ButtonBase) 中的 css。有关详细信息,请参阅 styled-component 文档。
【讨论】:
main、dark和light等变体——如默认主题material-ui.com/customization/default-theme所示有没有办法将颜色设置为@987654331 @变种?
试试这个:
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" />
});
现在您可以在任何地方使用 ButtonContainedError。
而且和你的主题一致。
【讨论】:
main 颜色,那么似乎可以正确计算暗属性和亮属性。前任。粉红色的main 值将导致深色和浅色分别为深粉色和浅粉色。
这是一个示例打字稿实现:
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;
有了这个,你可以做到<Button variant="contained" color="success"> 自动完成和无警告:)
更新:
在 Material UI V5 中,这可以通过更优雅的方式实现。您只需向调色板添加颜色,按钮就会自动支持它!他们的文档有一个很好的例子来说明如何做到这一点:https://mui.com/customization/palette/#adding-new-colors
【讨论】:
const className = classes?.[`${props.variant}${capitalize(color)}`];Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Record<"root" | "textError" | "outlinedError" | "containedError", string>'.
classes[`${variant}${capitalize(color)}` as keyof typeof classes] 注意as keyof typeof classes。虽然我不确定我的队友是否会接受它,tbh。我很快就会对我的 PR 进行审核。
@ts-ignore 的注释并暂时使用您的解决方案
您可以使用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>
);
}
【讨论】:
在 MUI v5 中,这是您在主题中为您的 MUI Button 创建自定义颜色的方式。 primary and secondary colors 的创建方式与 under the hood 相同:
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'),
},
});
<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>
如果您使用的是 typescript,您还需要为刚刚定义的颜色添加其他类型:
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;
}
}
【讨论】:
首先尝试安装 npm install @material-ui/styles 根据材料文档应用样式,对于反应类组件,您可以使用以下代码:
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;
有关参考的更多信息,请查看我的中等博客。 https://medium.com/@farbodaprin/how-to-make-a-customisable-material-ui-button-a85b6534afe5
【讨论】:
您可以创建一个 theme,并为其 3 个受支持的 intentions(主要、次要、错误)中的每一个定义调色板,然后使用 <Button> 上的 color 属性来使用它们。 在您的示例中,btn-danger 可能是 <Button color='error'>
编辑: Brendan 的回答是正确的,Button 不支持 error。根据文档,Button 只支持“对这个组件有意义”的意图。所以只有 primary 和 secondary 可以在这里工作。
来自their docs(此处略减):
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>
);
}
请参阅Brendan's Answer,了解为您的组件创建主题的更真实示例。
【讨论】:
我发现 !important 在课程中有效。 (反应钩子)
const styles "...etc..." = (theme: Theme) => ({
buttonWarning: {
backgroundColor: theme.palette.warning.dark + '!important'
}
}))
然后在按钮中
const classes = styles();
<Button className={classes.buttonWarning}>Hello</Button>
【讨论】:
更改按钮颜色的最简单方法是添加“样式”属性。这是我创建的绿色按钮的示例:
import Button from '@material-ui/core/Button';
<Button
variant="contained"
color="primary"
style={{ backgroundColor: '#357a38' }}
>
Run
</Button>
【讨论】: