Remove CSS rule for Material UI component in theme overrides - css

I want to remove the CSS padding-bottom in the Material UI CardContent component. But I only find solutions on setting it to something else. My current workaround is to set it to something invalid (e.g. -1) so browsers will just ignore it.
I have this theme which contains the workaround:
export default createMuiTheme({
overrides: {
MuiCardContent: {
root: {
"&:last-child": {
paddingBottom: -1,
},
},
},
},
});
would would be the correct way of remove a css rule from a component in Material UI.
(I already tried inherit, initial, revert and unset). Setting it to 0 is not what I want because I want the padding of the MuiCardContent without last-child to get applied.

Related

Material-UI - why different css is shown on prod environment then development env

I use material UI (verison: ^4.12.3) Select, with custom input.
For some reason the prod env Select input has a black background and :before element with white background.
I don't know from where it comes from.
this is image of the prod:
this is image of the dev Select:
when comparing the 2 css & html of the envs Select element, it's is shown that there is a ::before element added in prod that is not presented in dev
also, the background color is different. in prod there is another class added to the InputBase element, which doesn't exist in dev. this class adds a background-color black:
Edit 1
it seems like MUI inject <style>. in the prod html i see the background-color: black and the ::before. ill try adding the index solution, but my problem is not precedence (the style that i do use override the injected style). also, it wont help the ::before element. how to disable the injected styles ? or work around it ?
the injected bad css:
Please refer to this question. As answered by user Mordechai.
It seems like webpack could mess with MUI's rules on JSS precedence... This could be solved by adding an index of one to MUI's methods.
//Hook
const useStyles = makeStyles({
// your styles here
}, {index: 1})
// HOC
MyComponent = withStyles({
// your styles here
}, {index: 1})(MyComponent)
adding <StylesProvider /> wrapper to the app fixed it. we use micro-frontend infrastructure. and one of the frontends app also had makeStyles. this is causing classNames conflicts in MUI.
in the root component <App/>:
import {
StylesProvider,
createGenerateClassName
} from '#material-ui/core/styles';
const generateClassName = createGenerateClassName({
seed: 'app1'
});
const App = () => {
return (
<StylesProvider generateClassName={generateClassName}>
<OtherAppComponents />
</StylesProvider>
)
}
if you have more then 2 add a provider and a generator to each, with different seed

React Material UI DataGrid style MuiDataGrid-window within createMuiTheme or makeStyles / styled

I'm trying really hard to change the css for the .MuiDataGrid-window in MatierialUi DataGrid.
Therefore I was following css rules from https://material-ui.com/api/data-grid/
I tried it within createMuiTheme for root it was working fine, but not for window. I also tried a lot of different cominations like MuiDataGrid-window or only 'MuiDataGrid-window' directly under overrides, but nothing worked..
export const theme = createMuiTheme({
overrides: {
MuiDataGrid: {
root: {
backgroundColor: 'red',
},
window: {
width: '120%',
},
},
}
});
Next try was a styled DataGrid component, which also didn't work out.
Both didn't work. A styled component would be my prefered way!
const StyledDataGrid = styled(DataGrid)({
MuiDataGrid: {
root: {
backgroundColor: 'green',
},
window: {
width: '120%',
}
}
});
Maybe I'm completely on the wrong way.. But how to style the CSS attributes in MUI's API like .MuiDataGrid-mainGridContainer, .MuiDataGrid-overlay, .MuiDataGrid-columnsContainer, .MuiDataGrid-colCellWrapper etc.
Thanks a lot and maybe it is helpful for somebody else :)
If you check the styles applied, window class element has two selectors associated (multiple classes):
.MuiDataGrid-root .MuiDataGrid-window
To apply the styles in children elements, such as, window in grid root, you need to select both of them:
MuiDataGrid: {
root: {
backgroundColor: 'red',
'& .MuiDataGrid-window': {
backgroundColor: 'green'
}
}
}
In documentation the grid component have just one rule name: root

Override React AgGrid styling settings using createStyles and withStyles

I'm aware that it's possible to override Ag Grid properties by editing the CSS itself, however I'm wondering if it's possible to use the functionalities built into react to do this instead. I'm relatively new to the two frameworks, so apologies if there's something I'm not understanding.
Ultimately, what I want to do is something like this:
styles.js
---------
const styles = (theme: Theme) =>
createStyles({
root: {
position: 'relative',
height: 'calc(100vh - 128px)',
},
agHeaderCellLabel: {
agHeaderCellText: {
writingMode: 'vertical-lr',
marginTop: '100px',
},
},
})
export default styles
GridComponent.tsx
-----------------
import styles from './styles'
...
return (
<Paper className={classes.root}>
<div
id="myGrid"
style={{
height: '100%',
width: '100%',
}}
className={`ag-theme-material ${classes.agHeaderCellLabel}`}
>
<AgGridReact
// listening for events
onGridReady={onGridReady}
onRowSelected={onRowSelected}
onCellClicked={onCellClicked}
onModelUpdated={calculateRowCount}
// Data
columnDefs={cDef}
defaultColDef={defaultColumnFormat}
suppressRowClickSelection={true}
groupSelectsChildren={true}
debug={true}
rowSelection="multiple"
// rowGroupPanelShow={this.state.rowGroupPanelShow}
enableRangeSelection={true}
pagination={true}
rowData={rows}
/>
</div>
</Paper>
)
...
export withStyles(styles)(GridComponent)
In this example I'm just trying to get the header text to be displayed vertically.
I've inherited this project, and I've noticed that all of the styling has been done in this method, as there are no custom css files lying around, so I'm trying to stick with that convention of a styles file alongside the component.
Is this possible, and if so,
I ran into this same situation, and came up with the following solution. Although not necessarily ideal, it allows you to continue with the desired convention.
styles.js
---------
const styles = (theme: Theme) =>
createStyles({
root: {
position: 'relative',
height: 'calc(100vh - 128px)',
},
//Apply changes to agGrid material HeaderRoot
myClassAppliedToGrid: {
'& .ag-header[ref="headerRoot"]':{
writingMode: 'vertical-lr',
marginTop: '100px',
}
}
//OR
//Apply Changes to agGrid material header row
myClassAppliedToGrid: {
'& .ag-header-row':{
writingMode: 'vertical-lr',
marginTop: '100px',
}
}
})
export default styles
The key idea is using the & SASS syntax to "reach into" agGrid and make more specific CSS classes so you can override them. (see https://css-tricks.com/the-sass-ampersand/ for more info)
The key pieces of info are:
.parent {
& .child {}
}
turns into
.parent .child {}
and
.some-class {
&.another-class {}
}
turns into
.some-class.another-class { }
Using this sytanx, you should be able to create CSS classes that you can apply to your grid, columns, rows, etc that will properly override the material ag-grid theme.
Here is another example, but this class gets applied to a cell using agGrid cellStyleRules when a row is dragged over it, rather than applying the class to the grid as a whole. This way it only effects cells that have a row drag occuring over them:
rowDraggedOverCellsTopEdge: {
'&.ag-cell': {
borderTopColor: theme.palette.gray[50],
borderTopWidth: 8,
backgroundColor: fade(theme.palette.gray[50], 0.3)
}
},
Finally, one thing I did not do but would reccommend investigating is looking into agGrid's theme overriding, especially if you are on version 23+
https://www.ag-grid.com/javascript-grid-themes-provided/#customising-themes
It might be a good idea to get your base overrides to the theme done this way if you expect a consistent look and feel of your grids throughout the application.
Cheers!

Using CSS attribute selector with styled components for icons

I'm using NextJS for React, SSR and styled-components (with hashing). So far I managed to build main CSS structure with Sass.
nextjs.config.js
const withSass = require('#zeit/next-sass')
module.exports = withSass({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: "[hash:base64:5]",
}
})
The problem is I cannot use an attribute CSS selector; for icons, usually I define font-family like below
[class^='icon-'] {
font-family: 'fonticon'
}
.icon-foo {
&:before {
content: '\someunicode';
}
}
when I run build and .icon-foo class successfully converts to some hash and match with the CSS. But I cannot use an attribute selector here.
I know it's impossible to convert this kind of selector, but is there any solution, like giving a exception rule for cssLoaderOptions for example,
excludeClasses: /^.icon-/
so I can keep my classes as they are just for the icons?
I know I can give font-family to <i> tag, but I want to avoid that if possible.

Add multiple style properties to a single theme property with Styled Components

I'm using styled components for a new project, and want to use the theming features of the library. I'm struggling to figure out if there is a good or best practice way of adding multiple style properties to one object (i.e., create a kind of inheritance). What is want is:
// in the theme, define a group of styles for a given component
// e.g. all fonts have a font-family, weight, size, etc
const theme = {
fonts: {
font-family: ...,
font-weight: ...,
font-size: ...,
}
}
// then in my styled component,
// define the multi-line theme, along with component specific styles
// or even override the theme styles
const Header = styled.span`
${props => props.theme.fonts};
text-decoration: underline;
...
`;
Right now, it's only apparent to me that you would need to pass the theme property to each style on the component. Is there a pattern that can help reduce some of the repeated code seen in my above example?
What I usually do is to define the theme styles in a separate files, for example
MyComponent
index.js
styles.js //<-- Custom styles for component
theme
spacing.js // <-- Common styles for all components
colors.js
fonts.js
Inside spacing.js I would have something like this:
const verticalPaddingSmall = {
paddingTop: 5,
paddingBottom: 5,
};
const verticalPaddingMedium = {
paddingTop: 10,
paddingBottom: 10,
};
export default function spacing(size, direction, isPadding) {
// some logic to return the correct object based on the params,
// screen size (tablets vs phones), etc...
return verticalPaddingSmall;
}
Obviously, that code is automatically generated based on some configurations I define for different screen sizes and so on, but the end result is something similar to that.
Then in my custom component I import the common styles, apply them to the styles and overwrite if needed it, something like this on styles.js:
import spacing from 'themes/spacing';
import fonts from 'themes/fonts';
const verticalPaddingSmall = StyleSheet.create({
main: {
...spacing('small', 'vertical', true),
},
title: {
...spacing('xsmall', 'horizontal', false),
...fonts.title,
fontSize: 25, //<--- overwrite default values from title
},
});
I rarely overwrite styles on components, because my common styles handle different styles for tables and phones, kinda like media queries on the web.

Resources