Material-UI Override .MuiDataGrid-columnsContainer CSS - javascript

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,
}),
},
}))

Related

Is it possible to test for custom data-attributes in css-in-js?

I am trying to reference data attributes from JSS, test for them, and apply the styles if the test is true. However, when I run the code below, it does not apply "color:green" and I have no idea why!
import React from "react";
import { createUseStyles } from "react-jss";
const useStyles = createUseStyles({
statusDiv: {
backgroundColor: "lightGrey",
padding: "10px",
fontWeight: "bold",
'[data-status="OPEN"]': {
// no effect ..?
color: "green",
},
},
});
const App = () => {
const classes = useStyles();
return (
<div data-status="OPEN" className={classes.statusDiv}>
OPEN
</div>
);
};
export default App;
That's an interesting case.
What you can do is:
export default {
'#global' : {
'div.testClass[data-custom="value"]': {
color: 'red',
border: '1px, solid navy'
}
}
}
This assumes a JSS plug-in #global installed, but this is something I think is quite useful to have.
More about the plug-in #global - here
And if you want to address a data- attribute like in your edited example 0 you should do:
testClass: {
'[data-custom="value"]': {
//styles for the custom data
}
}
And in the markup you'll have (depends on the way you extracting the class):
testClass.classes['[data-custom="value"]']
... styles for the custom data will be applied by the above.
The way you wrote in your last edit will not work. You should add a small bit though. To work the code example you provided:
...
fontWeight: "bold",
'& [data-status="OPEN"]': {
// no effect ..?
color: "green",
},
The & require a nesting plug-in setup - here is more about it.
Thanks to the amazing support from #Vladyn, the following code demonstrates this working perfectly :D
import React from "react";
import { create } from "jss";
import { JssProvider, createUseStyles } from "react-jss";
import nested from "jss-plugin-nested";
const jss = create();
jss.use(nested());
const useStyles = createUseStyles({
statusDiv: {
backgroundColor: "lightGrey",
padding: "10px",
fontWeight: "bold",
'&[data-status="OPEN"]': {
color: "green",
},
'&[data-status="CLOSED"]': {
color: "red",
},
},
});
const App = () => {
const classes = useStyles();
const status = "OPEN";
return (
<JssProvider jss={jss}>
<div data-status={status} className={classes.statusDiv}>
{status}
</div>
</JssProvider>
);
};
export default App;
If your JS looks like this:
<div data-customAttribute={value} className={classes.testClass}></div>
Your CSS will look like:
.testClass[data-customAttribute="value"] {
// your styles
}

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

How can I remove the border of expansion panel in Material-UI?

How can I remove the border of expansion panel area in Material-UI?
You should be able to set the elevation to 0 which will remove the box-shadow:
<Accordion elevation={0}>
(note: ExpansionPanel has been renamed to Accordion)
This works for version "#material-ui/core": "4.9.9"
You can use the following to be applied for the entire theme:
const theme = createMuiTheme({
overrides: {
MuiExpansionPanel: {
root: {
'&:before': {
display: 'none'
},
},
},
}
}
Or if you need it only for one component then can be hidden through a class style:
import { makeStyles } from '#material-ui/core/styles'
....
const useStyles = makeStyles({
hideBorder: {
'&.MuiExpansionPanel-root:before': {
display: 'none',
},
},
})
....
const classes = useStyles()
.....
<ExpansionPanel className={classes.hideBorder}>
Try to edit the css of the expansion-panel class (I guess you mean the box shadow, there is no border)
.expansion-panel {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
This works for #mui/material 5.1.0:
MuiAccordion: {
styleOverrides: {
root: {
"&:before": {
backgroundColor: "transparent",
},
},
},
},
This is worked for me #mui/material: ^5.8.7
I create style like this
const AccordionStyle = {
'&:before': {
backgroundColor: 'transparent !important',
},
};
and I used the style in sx
<Accordion sx={AccordionStyle}>
</Accordion>
border: 'none'
This helped me.

How to create button with text under icon by reactjs?

Now, I have component like this:
code of it:
import React from "react";
import {withStyles} from "material-ui/styles";
import Settings from "material-ui-icons/Settings";
import Button from "material-ui/Button";
const styles = {
button: {
color: "primary",
height: 95,
width: 95,
disableRipple: "true",
focusRipple: "true",
},
icon: {
height: 35,
width: 35,
display: "block",
float: "none",
},
text: {
height: 35,
width: 35,
display: "block",
float: "none",
marginTop: 10,
},
};
/* eslint-disable react/prop-types */
const IconedLabel = ({classes}) => (
<section>
<Button className={classes.iconButton} variant="raised" color="primary">
<Settings className={classes.icon}/>
<div className={classes.text}>Message</div>
</Button>
</section>
);
export default withStyles(styles)(IconedLabel);
But need to button, that in top part contains icon and text message in bottom.
I use reactjs and material-ui lib from here https://material-ui-next.com/demos/buttons/
The Button component uses flexbox to control the layout/alignment of content. To align the content vertically (so the icon is above the text), you can simply change the flex-direction to column.
This style needs to be applied to an element inside the button component, not to the root element. You can use the classes property to override all of the styles in a component.
In this case, you want to add flexDirection: column to the label class.
Documentation on class overrides in material ui v1
Here's a working example. Hope it helps.
const [React, ReactDOM, Button, Settings, withStyles] = [window.React, window.ReactDOM, window['material-ui'].Button, ({className}) => <i className={`material-icons ${className}`}>settings</i>, window['material-ui'].withStyles]
// Ignore code above this line
const styles = theme => ({
button: {
height: 95, // setting height/width is optional
},
label: {
// Aligns the content of the button vertically.
flexDirection: 'column'
},
icon: {
fontSize: '32px !important',
marginBottom: theme.spacing.unit
}
})
const CustomButton = ({ classes }) => (
<Button
/* Use classes property to inject custom styles */
classes={{ root: classes.button, label: classes.label }}
variant="raised"
color="primary"
disableRipple={true}
>
<Settings className={classes.icon} />
Message
</Button>
)
const WrappedCustomButton = withStyles(styles)(CustomButton)
ReactDOM.render(<WrappedCustomButton />, document.querySelector('#root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><script src="https://unpkg.com/material-ui#1.0.0-beta.40/umd/material-ui.production.min.js"></script><link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"><div id="root" />
A (potentially bad) solution would simply be:
.MuiIconButton-label {
flex-direction: column
}
I say bad, because you might want to use it in it's standard format elsewhere.
What I opted to do was add a class name nav-bar-icon-wrapper to the IconButton & set the flex direction in it's parent:
.nav-bar-icon-wrapper {
flex-direction: column
}
.MuiIconButton-label {
flex-direction: inherit
}
If I run into instance later where I want the icon/label button to be standard, I'll just add a new class default-icon-wrapper and css that handles that:
.default-icon-wrapper {
flex-direction: row
}
FWIW:
I preach the BEM http://getbem.com/introduction/ convention AND that whenever you make a component, you add an optional modifier prop.
I have functions in a shared dir that looks these:
export function BEMifyThis(modifier) {
return (klass) => BEMify(klass, modifier)
}
export function BEMify(klass, modifier=false) {
if (modifier) {
klass += ` ${klass}-${modifier}`
}
return klass
}
Then I use that everywhere in my component so the user can access the component elements as a group or individually using their modifiers.
import {BEMifyThis} from '../shared/bem'
const BEMify = BEMifyThis(this.props.modifier)
className={"navbar__menu_item")}
becomes
className={BEMify("navbar__menu_item")}
so something like navbar__menu_item becomes navbar__menu_item navbar__menu_item-logout

How to align text in Draft.js

I'm wondering how to align text in Draft.js just like on the picture below.
I have searched this several days, but I haven't found the solution.
After reading the source code, I found a way for it. Using blockRenderMap, you can add some custom block types like this:
const blockRenderMap: Record<string, DraftBlockRenderConfig> = {
'header-one-right': {
element: 'h1',
wrapper: <StyleHOC style={{ ...blockStylesMap['header-one'], display: 'flex', justifyContent: 'flex-end' }} />,
},
'header-two-right': {
element: 'h2',
wrapper: <StyleHOC style={{ ...blockStylesMap['header-two'], display: 'flex', justifyContent: 'flex-end' }} />,
},
'header-three-right': {
element: 'h3',
wrapper: <StyleHOC style={{ ...blockStylesMap['header-three'], display: 'flex', justifyContent: 'flex-end' }} />,
},
'unstyled-right': {
element: 'div',
wrapper: <StyleHOC style={{ ...blockStylesMap['unstyled'], display: 'flex', justifyContent: 'flex-end' }} />,
},
};
I use flex to avoid wasting time to find a away to override the internal style .public-DraftStyleDefault-ltr.
StyleHOC is quite simple:
const StyleHOC: React.FC<Props> = ({ style, children }) => {
const childrenWithStyle = React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, { style });
}
return child;
});
return <>{childrenWithStyle}</>;
};
And then you can toggle the blockType using RichUtils.toggleBlockType(editorState, blockType).
The Editor component has a div with the class .public-DraftStyleDefault-ltr. This controls the text alignment of each paragraph that you write. As you create more paragraphs, more of these divs are created to contain the text. The text is wrapped in a span element and .public-DraftStyleDefault-ltr has a default alignment of text-align: left.
I created some css classes for text-align: left, text-align: center, text-align: right and text-align: justify and added this basic for loop to my component for creating text alignment buttons.
const textBlock = document.querySelectorAll(".public-DraftStyleDefault-ltr");
for (let i = 0; i < textBlock.length; i++) {
textBlock[i].classList.toggle(this.props.style);
}
this.props.style is the name of the css class that determines the text-alignment I wanted.
It is a pretty basic fix since this way when you click align right say, the whole document is aligned right. I am planning to work on this so only the selected text is aligned so should be able to update this answer soon. Hope it helps in some way
I tried to make almost the same thing. But my trouble was in text-align property, which was correctly set to block span, but .public-DraftStyleDefault-ltr doesn't react to it.
So, I have made next decision, which get the first div child, and copy it's params:
const paragraphs: any = document.querySelectorAll(".public-DraftStyleDefault-ltr");
for (let i = 0; i < paragraphs.length; i++) {
const paragraph = paragraphs.item(i);
if (paragraph) {
const firstItem = paragraph.querySelectorAll('*').item(0);
// Apply to the parent the first child style
paragraph.style.textAlign = firstItem.style.textAlign;
}
}
To change block alignment you can:
1- set alignment data
const modifiedBlockState = Modifier.setBlockData(editorState.getCurrentContent(),
editorState.getSelection(),Map({align:'align-center'}));
setEditorState(EditorState.push(modifiedBlockState,'change-block-data'));
2- use it in styling function
/*
JSX
blockStyleFn={ block => block.getData().get('align')
this will return 'align-center|left|right' which will be assigned as a classname
*/
<Editor blockStyleFn={ block => block.getData().get('align')} .../>
//CSS
.align-center div{
text-align: center;
}
.align-right div{
text-align: right;
}
.....

Categories

Resources