Reputation: 2590
I am struggling to modify button colors in Material UI (v1).
How would I set the theme to behave similarly to Bootstrap, so I could just use "btn-danger" for red, "btn-success" for green...?
I tried with custom className
but it doesn't work properly (the hover color doesn't change) and it seems repetitive. What options do I have?
Upvotes: 67
Views: 227955
Reputation: 523
It's easy. With no theme struggling.
<Button
variant="contained"
sx={{
backgroundColor: colors.blue[600],
"&:hover": {
backgroundColor: colors.blue[300]
}
}}
>
{"Content"}
</Button>
Upvotes: 1
Reputation: 1
First, you have to define a (name type).d.ts , then you have to add a name color to list colors that has a hint of button, and then you can use it very easily.
defined type.d.ts
import React from 'react';
declare module '@mui/material/styles' {
interface Palette {
...
nameColorButton: {
main: React.CSSProperties['color'] // required
}
}
interface PaletteOptions {
...
nameColorButton?: {
main: React.CSSProperties['color'] // required
}
}
}
Then enter the file where you are defining the theme theme.ts
createTheme({
...
palette: {
nameColorButton:{
main:'#f00' // required
}
},
MuiButton: {
variants: [
{
props: {
color: 'nameColorButton',
},
style: { ... }
})
you can use to code
<Button color='nameColorButton'> ... </Button>
Upvotes: 0
Reputation: 81290
In Material UI v5, this is how you create customized colors in your theme for your Material UI Button
. The primary and secondary colors are created the same way 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>
If you're using typescript, you also need to add additional types for the colors you just defined:
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;
}
}
Upvotes: 67
Reputation: 34107
Export any color from '@mui/material/colors'; (Docs)
import { pink } from '@mui/material/colors';
and use like this
<Button variant="contained" sx={{ backgroundColor: pink[700] }}>Check</Button>
Upvotes: 3
Reputation: 155
Use This sx props it gives more understanding and also more relative to the MUI. in most of the MUI components, they use these props.
import {Button} from '@mui/material'
<Button variant="contained" sx={{
borderRadius: 35,
backgroundColor: "#21b6ae",
padding: "18px 36px",
fontSize: "18px",
**color:"white"**
}} >
elevation
</Button>
Upvotes: 0
Reputation: 1051
From 2022/05:
According to the official Doc: Customize MUI with your theme, you need to use ThemeProvider
and createTheme
.
First, customize the primary
color like this,
import {ThemeProvider, createTheme} from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#000000',
},
},
});
Then wrap your App or anywhere your want with the ThemeProvider
component, and set the color
props of your Button
component to primary
.
function YourApp() {
// logic omitted
return (
<ThemeProvider theme={theme}>
<YourApp>
<Button color="primary">Click me</Button>
</YourApp>
</ThemeProvider>
);
}
Upvotes: 1
Reputation: 1026
Here is an example typescript implementation:
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;
with this you can do <Button variant="contained" color="success">
with autocomplete and warning free :)
Update:
In Material UI V5 this is achievable in a much more elegant way. You can just add a color to the palette and the button will automatically support it! Their documentation has a great example of how to do this: https://mui.com/customization/palette/#adding-new-colors
Upvotes: 10
Reputation: 69
The easiest way to change the button color is to add the "style" attribute. Here's an example of a green button I created:
import Button from '@material-ui/core/Button';
<Button
variant="contained"
color="primary"
style={{ backgroundColor: '#357a38' }}
>
Run
</Button>
Upvotes: 3
Reputation: 6588
There is a mistake with Bagelfp's answer, and some other things to consider;
First, 'error' is not a supported color theme in material-ui@next v1's Button component. Only 'default', 'inherit', 'primary' and 'secondary' are accepted by the color prop.
Here is the approach I have found to be the easiest so far. First, choose your two most common theme colors and place them at the root of your app.
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>
);
}
}
Then in your component, choose the theme with your desired color;
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>
)
If you need a third and fourth color, you can export Component.js with a new palette just like you did in App.js.
This is the only solution I have found that allows me to retain the darkened hover effect (none of the official override examples retain functioning hover). I really wish I could find a way to simply drop in a new theme color when calling Button, but for now this is the most simple way to do it.
EDIT: My new preferred method is to create a CustomButton component using styled-components and material-ui buttonbase. I also place the styled-components theme provider at the root of my app alongside my MuiThemeProvider. This gives me easy access to additional theme colors in all my styled-components without importing and dropping in more ThemeProviders. In the case of my CustomButton, I just give it a theme
prop, which is passed right down to the css in styled(ButtonBase)
. See the styled-component docs for more info.
Upvotes: 18
Reputation: 81
You can use theme.palette.getContrastText()
to calculate the correct text color based on a background color value.
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>
);
}
Upvotes: 8
Reputation: 2552
Try this:
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" />
});
Now you have a ButtonContainedError to use anywhere.
And it is consistent with your theme.
Upvotes: 17
Reputation: 1176
first try to install npm install @material-ui/styles the apply styles according to material documentation, for react class component you can use below code:
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;
for more information with references please check my blog in medium. https://medium.com/@farbodaprin/how-to-make-a-customisable-material-ui-button-a85b6534afe5
Upvotes: 6
Reputation: 1707
You can try this
<Button
style={{
borderRadius: 35,
backgroundColor: "#21b6ae",
padding: "18px 36px",
fontSize: "18px"
}}
variant="contained"
>
Submit
</Button>
Upvotes: 43
Reputation: 361
I came up with this solution using Brendans answer in this thread. Hopefully it'll help someone in a similar situation.
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>
)
}
Upvotes: 35
Reputation: 61
You could create a theme
with palettes defined for each of their 3 supported intentions
(primary, secondary, error), and then use the color
prop on <Button>
to use those. In your example the btn-danger
could be <Button color='error'>
EDIT: Brendan's answer is correct here that error
is not supported for Button
. According to the documentation Button
only supports intentions that "make sense for this component.", so only primary
and secondary
would work here.
From their docs (trimmed down a little here):
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>
);
}
See Brendan's Answer for a more realistic example of creating themes for your components.
Upvotes: 4