-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can we add new property for color in palette in MuiTheme #14185
Comments
@kushaljain03 Yes, you can: const theme = createMuiTheme({
palette: {
success: {
main : "#bac778",
},
},
}) |
Yes I can but I cannot use it like It gives warning about to use only primary default secondary |
No, you can't use the success color property directly. You need to create a wrapping component to use the theme values. |
Adding additional properties is not explicitly documented. At least I couldn't find it. I think we can add another section that also includes how one would make this work with TypeScript. Actually: https://material-ui.com/customization/themes/#custom-variables for JS and https://material-ui.com/guides/typescript/#customization-of-theme with additional info for TS. |
Color styling has been one of the major difficulties when using this library. For instance, a simple use case where you have three buttons side-by-side, all different colors. Trying to style this with themes is really limiting and unintuitive. From what I can tell this is only possible to implement with the first two buttons using one theme, then the third button using a different (nested) theme:
But this is a weird way to break things up logically, because in this app all of these colors should be under one theme. Another option is to avoid themes for this entirely, but then this seems to give up the nice benefits of having the contrastText helpers and such. |
@davidcalhoun Yes, you are right, this issue is about extending the Button implementation so people can just do: const theme = createMuiTheme({
palette: {
success: {
main : "#bac778",
},
},
}) then have a working: <Button color="success" /> implementation. The best solution right now is to add the color in the theme, then to create a wrapping component: import React from "react";
import { withStyles, ThemeProvider } from "@material-ui/styles";
import MuiButton from "@material-ui/core/Button";
import { createMuiTheme } from "@material-ui/core/styles";
const Button = withStyles(theme => ({
root: props =>
props.color === "success" && props.variant === "contained"
? {
color: theme.palette.success.contrastText,
backgroundColor: theme.palette.success.main,
"&:hover": {
backgroundColor: theme.palette.success.dark,
// Reset on touch devices, it doesn't add specificity
"@media (hover: none)": {
backgroundColor: theme.palette.success.main
}
}
}
: {}
}))(MuiButton);
const theme = createMuiTheme();
theme.palette.success = theme.palette.augmentColor({
main: "#689f38"
});
function Theming() {
return (
<ThemeProvider theme={theme}>
<Button variant="contained" color="primary">
primary
</Button>
<Button variant="contained" color="success">
success
</Button>
</ThemeProvider>
);
}
export default Theming; https://codesandbox.io/s/7zmw6ox8m1 By the way, we are planing on extending the color to |
If you don't care about the warnings, you can do 🤷♂️: import React from "react";
import { ThemeProvider } from "@material-ui/styles";
import Button from "@material-ui/core/Button";
import { createMuiTheme } from "@material-ui/core/styles";
const theme = createMuiTheme();
theme.palette.success = theme.palette.augmentColor({
main: "#689f38"
});
const isSuccess = style => props =>
props.color === "success" && props.variant === "contained" ? style : {};
theme.overrides = {
MuiButton: {
root: {
color: isSuccess(theme.palette.success.contrastText),
backgroundColor: isSuccess(theme.palette.success.main),
"&:hover": {
backgroundColor: isSuccess(theme.palette.success.dark)
}
}
}
};
function Theming() {
return (
<ThemeProvider theme={theme}>
<Button variant="contained" color="primary">
primary
</Button>
<Button variant="contained" color="success">
success
</Button>
</ThemeProvider>
);
}
export default Theming; |
Thanks for the great examples! That helps. For sure, having other color names outside of just "primary" and "secondary" helps a lot, but I'm not sure if it solves my use case. In my case I'm trying to use color themes for a dropdown button I'm creating with three states:
It would be great to be able to define these in a theme somehow, but these states don't necessarily map onto semantic names ( I'm guessing the philosophy is different (or maybe it's a performance concern?), but I would kind of prefer being able to define custom color names inside the theme that wouldn't necessarily be semantic or whatnot, just practical. For the cases above, I'd like to define some colors inside the theme called I especially like the second example, but I want to avoid anything that generates warnings! For this particular use case, I think I'll just avoid using themes for now and look for other styling options. |
@davidcalhoun This is something I'm experimenting locally. The material design guidelines already define a color and the "contrast" color (or "on" color in material speak). The idea is that you can add any color in the theme and either let us figure out what a good "on"-color would be or let you define that too. The component should then take care of the rest i.e. given a color name figure out what color to choose for background, text or iconography. States like hover, disabled, focused etc are currently handled via opacity in the material guidelines. Would be interesting to explore possible APIs to make this customizable too e.g. let the user define a theme wide function with the following signature: |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Closing this in favor of #13875. You can already add custom colors to the palette. Just not use them in |
For a typescript implementation you can do something like this. Using props in the styles are avoided to improve JSS performance. (This avoids generating unique classes for every button and works great in large lists, etc...) import React from "react";
import { createStyles, Theme, makeStyles } from "@material-ui/core/styles";
import Button, { ButtonProps } from "@material-ui/core/Button";
import capitalize from "lodash/capitalize";
export type ColorTypes =
| "primary"
| "secondary"
| "error"
| "success"
| "warning"
| "default"
| "inherit"
| "info";
export type ColoredButtonProps = { color: ColorTypes } & Omit<
ButtonProps,
"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 ColoredButton: React.FC<ColoredButtonProps> = ({
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 (
<Button {...props} color={colorProp} className={className}>
{children}
</Button>
);
};
ColoredButton.displayName = "ColoredButton";
export default ColoredButton; |
For a typescript implementation and mui 5, you can act like this. import { colors } from "@mui/material",
const common = {
infromation: {
warnning: '#CFDD4A',
}
} type.ts will be like this: import Palette from "@mui/material/styles/createPalette";
declare module '@mui/material/styles' {
interface Palette {
infromation?: {
warnning?: string
}
}
} |
Like MuiTheme already provided a way to override colors of 3 property
Primary
Secondary
error
This is the below way to change the colors of existing properties.
What If we need to define new property for color like
Is that possible ?
The text was updated successfully, but these errors were encountered: