Let's say I have the following in a component:
const styles = theme => ({
alignRight: {
"margin-left": "auto"
}
});
Now, I might want to align something to the right side in some other place too. Using the default css in js system, I then have to define 'alignRight' class in every single component that I want to use it in.
My question is, how can I make the same class available to multiple components without having to declare it everywhere?
The customization page doesn't seem to address this.
I think that you are looking for the @global
plugin of JSS. Here is the documentation.
Yeah but that doesn't play well with withStyles
, right? There's no way to refer to those "global" classes through the classes
object in each component.
@AdityaAnand1 JSS will generate a deterministic class name. You are free to use wherever you like. it's global CSS, like you would do it with the bootstrap class names.
I was looking for a solution to this as well. It's not really a MUI problem, but withStyles
seems like the correct approach so maybe it could be tweaked to make this work.
This is the API I'm looking for (it doesn't quite work as is):
import { Theme, WithStyles, createStyles, withStyles } from '@material-ui/core/styles'
import classNames from 'classnames'
import React from 'react'
interface IProps extends WithStyles<typeof globalStyles>, WithStyles<typeof myComponentStyles> {}
// styles defined once per app and used on many components
const globalStyles = ({ spacing }: Theme) =>
createStyles({
pushLeft: { marginLeft: spacing.unit },
pushRight: { marginRight: spacing.unit },
})
// styles specific to `MyComponent`
const myComponentStyles = () =>
createStyles({
root: { color: 'red' },
})
function MyComponent({ classes }: IProps) {
// `classes` contains typed global and component CSS classes
return <div className={classNames(classes.root, classes.pushLeft, classes.pushRight)} />
}
// HOC gets `globalStyles` and `myComponentStyles`.
export default withStyles(globalStyles)(withStyles(myComponentStyles)(MyComponent))
// Figure out a way to wrap this to only make one HOC per Component. Maybe HOF like:
const myWithStyles = createWithStyles(globalStyles)
myWithStyles(myComponentStyles)(MyComponent)
There's no way to refer to those "global" classes through the classes object in each component.
No, you can't. But what's the point, it's global? Here is an example:
https://github.com/mui-org/material-ui/blob/7d2fadfc7b90c958d10ef89a0a3ce58cc7ff939e/packages/material-ui/src/CssBaseline/CssBaseline.js#L8-L17
@oliviertassinari in the linked example you lose type safety of your global CSS classes, no?
@christophercliff Yes, you lose type safety.
What if I have .anyGlobalClass
. What do I do in that case?
For that this doesn't work on my component.
className={classNames(classes.ButtonLeft, 'anyGlobalClass')}
@kushalmahajan You have two options. 1. you change the class name generator to have global classnames https://material-ui.com/css-in-js/advanced/#global-css 2. you use the @global
syntax of JSS to target global class names. Your example should be working.
yes, I was in fact looking at your example given above for 2nd option i.e.
const styles = theme => ({
'@global': {
'.anyGlobalCss': { ...rules}
}
This doesn't works. Then option 1 is in alpha...probably not looking into it.
@kushalmahajan Ok, here are two examples to have global CSS, the first one is fully global, the second one is an hybrid:
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
const styles = {
"@global": {
".root": {
height: 100,
width: 100,
backgroundColor: "red"
}
},
foo: {
"&.bar": {
height: 100,
width: 100,
backgroundColor: "blue"
}
}
};
function GlobalClass(props) {
const { classes } = props;
return (
<React.Fragment>
<div className="root" />
<div className={`${classes.foo} bar`} />
</React.Fragment>
);
}
GlobalClass.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(GlobalClass);
https://codesandbox.io/s/5xxmxkx1wk
@@kushalmahajan It would be great to document it in our documentation: https://material-ui.com/css-in-js/advanced/#global-css. If you want to submit a documentation pull request, we would be happy to review it!
Sure. Will implement and document this weekend
@kushalmahajan It was taken care by @n-batalha, no need :).
Great!
Most helpful comment
@kushalmahajan Ok, here are two examples to have global CSS, the first one is fully global, the second one is an hybrid:
https://codesandbox.io/s/5xxmxkx1wk
@@kushalmahajan It would be great to document it in our documentation: https://material-ui.com/css-in-js/advanced/#global-css. If you want to submit a documentation pull request, we would be happy to review it!