material ui multiple classnames with same definition - javascript

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)} />
...

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?

Material-UI Override .MuiDataGrid-columnsContainer CSS

I am trying to override the CSS property position on the .MuiDataGrid-columnsContainer. When looking at the https://material-ui.com/api/data-grid/#css you can see there is a rule for root but there isn't a rule for .MuiDataGrid-columnsContainer. I have read the documentation on overriding the CSS properties but I can't seem to get it to work for that class.
Normally I would leverage the rule and do the following
const useStyles = makeStyles({
paper: {
background: '#010310',
}
});
Then return something like this
const classes = useStyles();
return (
<DataGrid classes={{ paper: classes.paper }} />
);
However, when I replace the word paper in the makeStyles and in the return to be columnsContainer it doesn't work.
Possible Reasons It's Not Working
Based on the documentation on the CSS for datagrid (link above), the only Rule is root and since the .MuiDataGrid-columnsContainer doesn't have a Rule then I need to do it differently. Unfortunately, I haven't found another way that has worked.
I appreciate any help I get, Thank you!
You can give inline style to the class that you want to override and give it an !important flag.
For example if the class you want to override is .MuiDataGrid-columnsContainer then you can simply do this .
.MuiDataGrid-columnsContainer{
position: relative !important; // to override the default css property
}
For a local overriding of MuiDataGrid-columnsContainer, as you can see on api doc, you have to pass your css to root class. So:
<DataGrid classes={{ root: classes.root }} />
Now if you want to override MuiDataGrid-columnsContainer in particular, in your makeStyles write something like:
const useStyles = makeStyles({
root: {
"&.MuiDataGrid-columnsContainer":{
background: '#010310',
}
}
});
Thats it.
root: {
"& .MuiDataGrid-root": {
color: `#fff`
},
"& .MuiIconButton-label": {
color: `#fff`
}
},
I put this "& .MuiDataGrid-root" in my main layout and it works very well.
const useStyles = makeStyles(() => ({
root: {
display: 'flex',
"& .MuiDataGrid-root": {
color: `#fff`
},
"& .MuiIconButton-label": {
color: `#fff`
}
},
appBar: {
backgroundColor:'#181745',
color:theme.palette.primary.main,
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
}))

Color each selected Dropdown item in react semantic-ui

I have the following jsx code (react-semantic-ui) in render method:
{!this.props.loading &&
<ControlRow>
<Grid.Column width={5}>
<Dropdown
multiple
fluid
selection
options={myOptions}
onChange={this.navigateToMyFunc}
/>
...
...
And I am using styled-components to style my elements:
https://github.com/styled-components/styled-components
Unfortunately the only working styling for the Dropdown due to some weird specifics of the environment is indirect from ControlRow:
const ControlsRow = styled(Grid.Row)`
.ui.multiple.dropdown > .label {
color: white !important;
background-color: #2185d0;
}
`
See also the following thread: Dropdown in semantic ui can't be made of multiple selection type when wrapped with styled-components
Now the Dropdown as you can see is of type multiple. Each selected item should be colored according to the specified in the myOptions options. I can pass myOptions to the ControlRow which will make the array to be accessible in it, but I am not sure how to write the styled-components part of it:
.ui.multiple.dropdown > .label {
color: white !important;
background-color: ${props => props.myOptions..??};
}
I need to also know which item it is to select correct myOptions color. Here is how it looks:
Right now it is just always blue, but I need it to be colored according to each option.
Update
Seems like it is an absent feature in semantic-ui-react - coloring by hex - codes (only a few regular color names allowed) - so I posted this feature to their github:
https://github.com/Semantic-Org/Semantic-UI-React/issues/3889
by default semantic-ui supports selected list of colors. If you need custom label color, you can add your custom css classes and apply the class name to the label.
const getOptions = (myOptions : string[]) => {
return myOptions.map((myValue : string) =>({
key: myValue,
text: myValue,
value: myValue,
label: { className: setColorClass(myValue), empty: true, circular: true }
}))
}
function setColorClass(optValue) {
if (optValue === '1') return 'light-green';
else if (optValue === '2') return 'sandy-brown';
else return 'light-coral';
}
in your css class you can have the following classes
.ui.label.light-green {
background-color: lightgreen !important;
}
.ui.label.sandy-brown {
background-color: lightgreen !important;
}
.ui.label.light-coral {
background-color: lightgreen !important;
}
Also if you want to apply label circular color when the value is selected, you can do the following, write a renderLabel function in your react class and apply it in the compnent
function renderLabel(label:any){
return {
content: `${label.text}`,
className: setColorClass(label.text)
}
}
Sample component
<Dropdown
search
selection
closeOnChange
value={myValue}
options={getOptions(myOptions)}
placeholder='Choose from here'
onChange={handleDropdownChange}
renderLabel={renderLabel}
/>
You don't need to use CSS styling for this. And nothing related to Styled Components needs to be done.
SemanticUI lets you use a custom render function for labels.
You would use it like this:
const renderLabel = (option) => ({
color: option.color,
content: option.text,
})
const myOptions = [
{ text: "option one", color: "blue" },
{ text: "option two", color: "red" },
// more options...
]
// ...
<Dropdown
multiple
fluid
selection
options={myOptions}
onChange={this.navigateToMyFunc}
renderLabel={renderLabel} // here
/>
This assumes that your option objects have a color property and a text property. You'll need to adjust to the shape of your option objects.
Also, the color property will need to be one of the available label colors in SemanticUI:
const colors = [
'red',
'orange',
'yellow',
'olive',
'green',
'teal',
'blue',
'violet',
'purple',
'pink',
'brown',
'grey',
'black',
]

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