How to add multiple classes in Material UI using the classes props?
CssReactjsMaterial DesignMaterial UiJssCss Problem Overview
Using the css-in-js
method to add classes to a react component, how do I add multiple components?
Here is the classes variable:
const styles = theme => ({
container: {
display: 'flex',
flexWrap: 'wrap'
},
spacious: {
padding: 10
},
});
Here is how I used it:
return (<div className={ this.props.classes.container }>)
The above works, but is there a way to add both classes, without using the classNames
npm package? Something like:
<div className={ this.props.classes.container + this.props.classes.spacious}>
Css Solutions
Solution 1 - Css
you can use string interpolation:
<div className={`${this.props.classes.container} ${this.props.classes.spacious}`}>
Solution 2 - Css
You could use clsx. I noticed it used in the MUI buttons examples
First install it:
npm install --save clsx
Then import it in your component file:
import clsx from 'clsx';
Then use the imported function in your component:
<div className={ clsx(classes.container, classes.spacious)}>
Solution 3 - Css
you can install this package
https://github.com/JedWatson/classnames
and then use it like this
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
Solution 4 - Css
To have multiple classes applied to a component, wrap the classes you would like to apply within classNames.
For example, in your situation, your code should look like this,
import classNames from 'classnames';
const styles = theme => ({
container: {
display: "flex",
flexWrap: "wrap"
},
spacious: {
padding: 10
}
});
<div className={classNames(classes.container, classes.spacious)} />
Make sure that you import classNames!!!
Have a look at material ui documentation where they use multiple classes in one component to create a customized button
Solution 5 - Css
You can also use the extend property (the jss-extend plugin is enabled by default):
const styles = theme => ({
container: {
display: 'flex',
flexWrap: 'wrap'
},
spaciousContainer: {
extend: 'container',
padding: 10
},
});
// ...
<div className={ this.props.classes.spaciousContainer }>
Solution 6 - Css
I think this will solve your problem:
const styles = theme => ({
container: {
display: 'flex',
flexWrap: 'wrap'
},
spacious: {
padding: 10
},
});
and in react component:
<div className={`${classes.container} ${classes.spacious}`}>
Solution 7 - Css
You can add multiple string classes and variable classes or props classes at same time in this way
className={`${classes.myClass} ${this.props.classes.myClass2} MyStringClass`}
three classes at same time
Solution 8 - Css
Yes, jss-composes provides you this:
const styles = theme => ({
container: {
display: 'flex',
flexWrap: 'wrap'
},
spacious: {
composes: '$container',
padding: 10
},
});
And then you just use classes.spacious.
Solution 9 - Css
classNames
package can also be used as advanced as:
import classNames from 'classnames';
var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'
let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true }); // => 'btn-primary'
Solution 10 - Css
You can use this method below:
import clsx from 'clsx';
return <div className={clsx(classes.container, 'spacious')} />
This link helps.
Solution 11 - Css
It can be done painlessly with descructuring, after all, these are JavaScript objects:
const truncate = {
width: '100px',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
};
email: {
color: '#747474',
...truncate,
},
Solution 12 - Css
If you want to assign multiple class names to your element, you can use arrays.
So in your code above, if this.props.classes resolves to something like ['container', 'spacious'], i.e. if
this.props.classes = ['container', 'spacious'];
you can simply assign it to div as
<div className = { this.props.classes.join(' ') }></div>
and result will be
<div class='container spacious'></div>
Solution 13 - Css
As already mentioned, you can use string interpolation
className={`${this.props.classes.container} ${this.props.classes.spacious}`}
And you can try classnames
library,
https://www.npmjs.com/package/classnames