Override Material UI shadow array values in theme overrides using createMuiTheme - javascript

I have a custom theme for my toolkit and am using createMuiTheme to override the palette, fonts, etc. I am attempting to slim down the shadow array in the theme object which is used for various components, which by default comes with 25 values. I only want to offer two options in my shadow array to keep things simple.
When I pass the two values I want to support for shadows into the array I get a warning from MUI:
index.js:1437 Warning: Material-UI: the shadows array provided to createMuiTheme should support 25 elevations.
So i've gotten around this by adding setting "none" for the other shadows that I don't want set values for like so:
let theme = createMuiTheme({
palette: {
common: {
black: "#000",
white: "#fff",
...
},
typography: {
fontFamily: opensans,
...
},
shadows: [
`0px 0px 6px 0px ${hexa(grey[500], 0.25)}`,
`0px 0px 6px 0px ${hexa(grey[500], 0.55)}`,
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
"none",
etc...
]
});
This is not ideal since it bloats the theme a ton which developers use as a ref to see whats available to use, is there a way around this?
My ideal state is representation in the theme object that looks like this but with no console warnings:
let theme = createMuiTheme({
palette: {
common: {
black: "#000",
white: "#fff",
...
},
typography: {
fontFamily: opensans,
...
},
shadows: [
`0px 0px 6px 0px ${hexa(grey[500], 0.25)}`,
`0px 0px 6px 0px ${hexa(grey[500], 0.55)}`,
]
});

You probably could do something like:
const makeTheme = () => {
const original = createMuiTheme();
return {
...original,
// override shadows based on the original array
shadows: original.shadows.map(() => 'none'),
};
};
const theme = makeTheme();

Actually you shouldn't be doing this as by this way what you are doing is that you are removing all the other default shadows given by material ui, this will make some components behave in some weird way, as it won't find the shadow, as you have overridden them.
Better approach is to add another customShadow key in the theme, and add your custom shadows to it. This way you are no longer overriding the default shadows that comes loaded with material ui and all the components that uses those shadows will work without any problem.
I hope you got your answer

Related

How can I style a toastify toast in the same js file, without using the styled toastcontainer?

in my app I use the ToastContainer component to display more than one type of toast. I do not want them both to have the same style, therefore I cannot use a styled ToastContainer to achieve what I want.
I know from the documentation for toastify that a toast can have it's own className for which you can specify the color etc. in a css file. But I want to have the css in the javascript file. But I have not yet found a way for it to work.
This is what I have come up with:
const notify = () => {
toast(customMsg, {
className: container,
autoClose: false,
closeOnClick: false,
position: toast.POSITION.BOTTOM_RIGHT,
});
};
const container = {
backgroundColor: 'yellow !important',
color: ' black !important',
borderRadius: '10px !important',
border: '2px solid orange',
width: '200px'
};
This does not work, but if I change className to "container" and put the styling in a css file it works. Is there a way for the className to be specified in the javascript file?

How to use theme colors for "color" prop used in MaterialUI components

Trying to use the colors from my Mui pallete as values for color prop like so:
Example:
<Tabs
indicatorColor="primary.mainGradient"
>
<Tab />
</Tabs>
But that doesnt work, Ive also tried using useTheme like so:
indicatorColor={theme.palette.primary.mainGradient}
That didn't work either. How can I use other colors other than primary for color props?
EDIT:
This is how I create my color in theme:
const theme = useMemo(
() =>
createMuiTheme({
palette: {
primary: {
main: '#4297FF',
mainGradient: "linear-gradient(-45deg,rgba(0, 101, 251, 1) 0%,rgba(0, 185, 255, 0.9251050762101716) 100%)",
},
Here is the error I'm getting from my console.
Failed prop type: Invalid prop `color` of value `linear-gradient(-45deg,rgba(0, 101, 251, 1) 0%,rgba(0, 185, 255, 0.9251050762101716) 100%)` supplied to `ForwardRef(TabIndicator)`, expected one of ["primary","secondary"]
indicatorColor only accepts 'primary' and 'secondary' values, which sets the background-color to theme.palette.primary.main and theme.palette.secondary.main respectively.
You can see the full TabIndicator API here.
To answer your question, you can add a custom style object directly to TabIndicatorProps.style like this:
<Tabs
TabIndicatorProps={{
style: {
height: 5,
background:
"linear-gradient(-45deg,rgba(0, 101, 251, 1) 0%,rgba(0, 185, 255, 0.9251050762101716) 100%)"
}
}}
>
Live Demo

material ui multiple classnames with same definition

In traditional CSS, the following is common for defining shared properties between classes:
.classA,.classB{
background-color: black;
}
In Material UI, using theming, the above can be translated as the following:
styles = (theme)=>({
classA:{
backgroundColor: 'black'
},
classB:{
backgroundColor: 'black'
},
})
I was wondering if there is a particular syntax to remove the duplication in the material UI styled approach above, ie, can the two classes be defined simultaneously?, Something along the following (in pseudocode):
styles = (theme)=>({
classA,classB:{
backgroundColor: 'black'
},
})
why don't you just set a base class for the color?
blackBg: {
backgroundColor: 'black'
}
and then use the classnames package to attach multiple classnames to your element
import classNames from 'classnames'
...
<div className={classNames(blackBg, myOtherClass)} />
...

How to custom color text and icon in TableSortText component of Material-ui?

What I'm trying to do:
I am trying to provide the user the option to provide custom styling to my EnhancedTable component by passing in a styles object containing properties such as headCellColor, headCellBackgroundColor, bodyCellColor, bodyCellBackgroundColor etc which can be used to color the cells in TableHead and TableBody.
In the TableHead component, I use a TableSortLabel in a way similar to what they've done in this material-ui docs example: https://material-ui.com/components/tables/#sorting-amp-selecting
I wish to custom color the text and the arrow icons on hover and when active based on the props provided by the user.
Let's see the colors of TableSortLabel in different situations:
The color of the text is grey initially and there is no arrow. When mouse is hovered over it, a grey arrow appears and the text turns black. On clicking it, active state is set, the grey arrow turns black and the text turns black permanently until active state is removed.
What I've tried so far:
const useStyles = makeStyles({
tableSortLabel: props => ({
backgroundColor: "blue",
color: props.headCellColor,
fill: props.headCellColor,
"&:hover": {
backgroundColor: "blue"
}
})
});
function EnhancedTableHeadCell(props) {
const { isActive, onHoverSortState, clickHandler, ...otherProps } = props;
const classes = useStyles(props.styles);
return (
<FancyTableCell styles={props.styles} {...otherProps}>
<TableSortLabel
active={isActive}
classes={{
icon: classes.tableSortLabel,
active: classes.tableSortLabel
}}
direction={onHoverSortState}
onClick={clickHandler}
>
{props.children}
</TableSortLabel>
</FancyTableCell>
);
}
This is what it looks like in the browser:
https://i.postimg.cc/fW7W2MRB/c1.jpg
The first one is a normal header, the second is on hover and the third is when clicked (active state).
From what we can observe, the text color is totally unaffected by the color css property in all the three cases (normal, hover, active). On hover, backgroundColor only affects the icon and not the text. However, we can see that backgroundColor affects the text when it is active. Everything is going as expected with the icon. The only issue is with the text.
What could I be possible doing wrong? How can I solve my problem?
What worked for me is:
const StyledTableSortLabel = withStyles((theme: Theme) =>
createStyles({
root: {
color: 'white',
"&:hover": {
color: 'white',
},
'&$active': {
color: 'white',
},
},
active: {},
icon: {
color: 'inherit !important'
},
})
)(TableSortLabel);
You can reference the following for increasing css specificity:
https://material-ui.com/customization/components/#pseudo-classes
Solution for your problem is following:
MuiTableSortLabel: {
root: {
color: textPrimary,
// if you want to have icons visible permanently
// '& $icon': {
// opacity: 1,
// color: primaryMain
// },
"&:hover": {
color: primaryMain,
'&& $icon': {
opacity: 1,
color: primaryMain
},
},
"&$active": {
color: primaryMain,
// && instead of & is a workaround for https://github.com/cssinjs/jss/issues/1045
'&& $icon': {
opacity: 1,
color: primaryMain
},
},
},
}
This restyling I use globally via my ThemeProvider, but you can of course use it individually in your single component by using "withStyles" HOC (see "BootstrapButton" in example)
I could'nt find a proper way to do it so I came up with a temporary solution overriding the material ui css.
I added this to my global css:
.MuiTableSortLabel-root.MuiTableSortLabel-active,
.MuiTableSortLabel-root:hover,
.MuiTableSortLabel-icon {
color: inherit !important;
}
Worked for me with Mui5:
sx = {
{
'&.MuiTableSortLabel-root': {
color: 'white',
},
'&.MuiTableSortLabel-root:hover': {
color: 'blue',
},
'&.Mui-active': {
color: 'blue',
},
'& .MuiTableSortLabel-icon': {
color: 'blue !important',
},
}
}
'&.MuiTableSortLabel-root' <-- no space &.
'&.Mui-active' <-- no space &.
'& .MuiTableSortLabel-icon' <-- space

What's the most performant but full-featured styling method in React.js

I have been reading a lot blog posts, best practices and slides (e.g. CSS in JS by Christopher Chedeau aka 'vjeux' which I think is great).
I totally understand why it is "better" to set your styling directly within your React Component, but I then found out that this might be limited as well. You may not use CSS pseudo-classes nor media queries to handle some responsive styling issues.
As someone who is used to do a lot of work with CSS and lately with SASS (which I still love) this drives me in some kind of cleavage, because I do not want to disclaim any styling property which standard CSS gives me.
My question now is:
Is it possible to have your styling within your React Components without those given disadvantages, and if: How would you actually do it to achieve the best performance and maximum of clarity.
Check out https://github.com/FormidableLabs/radium. It's pretty cool. Here's an example where they show how to add media queries among other things.
var styles = {
base: {
backgroundColor: '#0074d9',
border: 0,
borderRadius: '0.3em',
color: '#fff',
cursor: 'pointer',
fontSize: 16,
outline: 'none',
padding: '0.4em 1em',
':hover': {
backgroundColor: '#0088FF'
},
':focus': {
backgroundColor: '#0088FF'
},
':active': {
backgroundColor: '#005299',
transform: 'translateY(2px)',
},
// Media queries must start with #media, and follow the same syntax as CSS
'#media (min-width: 992px)': {
padding: '0.6em 1.2em'
},
'#media (min-width: 1200px)': {
padding: '0.8em 1.5em',
// Media queries can also have nested :hover, :focus, or :active states
':hover': {
backgroundColor: '#329FFF'
}
}
},
red: {
backgroundColor: '#d90000',
':hover': {
backgroundColor: '#FF0000'
},
':focus': {
backgroundColor: '#FF0000'
},
':active': {
backgroundColor: '#990000'
}
}
};

Categories

Resources