Reputation: 53
I'm using React and Material-ui, and currently I'm doing something like the code below.
Is there a better way?
For instance, is there a function that allows you to access 'props' within the "styles" jss object below the component that is eventually injected into the component with withStyles() without having to do all this ugly inline styling?
import React from 'react';
import {
MaterialComponentOne,
MaterialComponentTwo,
MaterialComponentThree,
} from '@material-ui/core';
function MyPureComponent(props) {
return (
<MaterialComponentOne
style={
props.type === 'secondary'
? {
css_property: 'css_value1',
}
: {
css_property: 'css_value2',
}
}
className={props.classes.MaterialComponentOne}
position="static"
>
<MaterialComponentTwo>
<MaterialComponentThree
style={
props.type === 'secondary'
? {
css_property: 'css_value1',
}
: {
css_property: 'css_value2',
}
}
variant="title"
className={props.classes.MaterialComponentThree}
>
{props.title}
</MaterialComponentThree>
</MaterialComponentTwo>
</MaterialComponentOne>
);
}
const styles = {
MaterialComponentOne: {
css_property: 'css_value',
css_property: 'css_value',
},
MaterialComponentTwo: {
css_propery: 'css_value',
},
};
export default withTheme()(withStyles(styles)(MyPureComponent));
thanks.
Upvotes: 5
Views: 5241
Reputation: 182
A natural way is using createStyles hook alongside with makeStyles and useStyles. You can use the prop name inside the element you are styling by making it an arrow function that returns the styling. In addition, you can also style other elements inside the createStyles hook. This took me some time, I hope anyone finds it useful. ✨🔥
Here is the code also provided as an answer to another question: (https://stackoverflow.com/a/69137307/10968401)
import { makeStyles, createStyles, Theme } from "@material-ui/core/styles";
...
...
const classes = useStyles();
...
...
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: propName => ({
border: "none",
boxShadow: "none",
cursor: propName ? "pointer" : "auto",
width: "100%",
backgroundColor: "#fff",
padding: "15px 15px"
}),
updated: {
marginTop: 12,
fontWeight: 400,
color: "#939393"
}
})
);
Upvotes: 2
Reputation: 3804
You may use clsx library which comes with Material UI or classnames library for conditionally joining classNames together. The example below is shown using classnames library, you may also use clsx library to achieve the same result.
import React from 'react';
import {
MaterialComponentOne,
MaterialComponentTwo,
MaterialComponentThree,
} from '@material-ui/core';
import classNames from "classnames"
function MyPureComponent(props) {
return (
<MaterialComponentOne
position="static"
className={classNames(
props.classes.MaterialComponentOne,
{[props.classes.classOne]: props.type === 'secondary'},
{[props.classes.classTwo]: props.type !== 'secondary'}
)}
>
<MaterialComponentTwo>
<MaterialComponentThree
variant="title"
className={classNames(
props.classes.MaterialComponentThree,
{"props.classes.classOne": props.type === 'secondary'},
{"props.classes.classTwo": props.type !== 'secondary'}
)}
>
{props.title}
</MaterialComponentThree>
</MaterialComponentTwo>
</MaterialComponentOne>
);
}
const styles = {
MaterialComponentOne: {
css_property: 'css_value',
css_property: 'css_value',
},
MaterialComponentTwo: {
css_propery: 'css_value',
},
classOne: {
css_property: 'css_value',
},
classTwo: {
css_property: 'css_value'
}
};
export default withTheme()(withStyles(styles)(MyPureComponent));
The classNames
function takes any number of arguments which can be a string or object. The argument 'foo'
is short for { foo: true}
. If the value associated with a given key is falsy, that key won't be included in the output.
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'
Upvotes: 4
Reputation: 11575
You can use styled-components.
Example based on the docs Adapting based on props:
import styled from 'styled-components';
const Button = styled.button`
background: ${props => props.primary ? 'palevioletred' : 'white'};
color: ${props => props.primary ? 'white' : 'palevioletred'};
`;
function MyPureComponent(props) {
return (
<div>
<Button>Normal</Button>
<Button primary>Primary</Button>
</div>
);
}
Upvotes: 2