Reputation: 37344
Here is a createStyles
statement in my Typescript code:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
menuOpen: {
zIndex: 1,
width: 200,
height: '100%',
position: 'fixed',
top: 48,
transition: 'left .1s',
marginRight: theme.spacing(2),
left: 0,
background: '#3f51b5',
'& div:first-element': {
marginTop: 100
}
},
menuClose: {
zIndex: 1,
width: 200,
height: '100%',
position: 'fixed',
top: 48,
transition: 'left .1s',
marginRight: theme.spacing(2),
left: -200,
background: '#3f51b5',
'& div:first-element': {
marginTop: 100
}
},
}),
);
I'm flipping between these to open or close a menu (using a useState
variable). As you can see, these styles share common attributes. How would I be able to make a menu
style that these two styles could inherit from?
Edit:
So it looks like the transitioning stuff isn't working and I'm wondering if thats because React reload those DOM elements? I tried adding the transitions in the menuClose
and menuOpen
styles just in case it needed them but the menu acts like it doesnt have a transition attribute.
After @doglozano's answer I have the following in my createStyles
function:
// I've even tried putting the transition in a div wrapper
// but I think that element is getting overwritten also.
toolBar: {
'& div': {
transition: 'left .1s'
}
},
menu: {
zIndex: 1,
width: 200,
height: '100%',
position: 'fixed',
top: 48,
transition: 'left .1s',
marginRight: theme.spacing(2),
left: -200,
background: '#3f51b5',
'& div:first-element': {
marginTop: 100
}
},
menuOpen: {
left: 0,
transition: 'left .1s',
},
menuClose: {
left: -200,
transition: 'left .1s',
},
When my menu is closed:
.makeStyles-menuClose-7 {
left: -200px;
transition: left .1s;
}
.makeStyles-menu-5 {
top: 48px;
left: -200px;
width: 200px;
height: 100%;
z-index: 1;
position: fixed;
background: #3f51b5;
transition: left .1s;
margin-right: 16px;
}
.makeStyles-toolBar-4 {
transition: left .1s;
}
When my menu is open:
.makeStyles-menuOpen-6 {
left: 0;
transition: left .1s;
}
.makeStyles-menu-5 {
top: 48px;
left: -200px;
width: 200px;
height: 100%;
z-index: 1;
position: fixed;
background: #3f51b5;
transition: left .1s;
margin-right: 16px;
}
.makeStyles-toolBar-4 {
transition: left .1s;
}
Edit 2: Here is my Sandbox link.
Any ideas?
Upvotes: 3
Views: 2941
Reputation: 6607
You could define a base class with all the common attributes, and then have only the specific attributes in menuOpen
and menuClose
. Then, you can use a library such as classnames
or clsx
to apply the base class always, and then conditionally apply also either menuOpen
or menuClose
based on your state variable.
Would look something like this:
import clsx from 'clsx';
...
const useStyles = makeStyles((theme: Theme) =>
createStyles({
menu: {
zIndex: 1,
width: 200,
height: '100%',
position: 'fixed',
top: 48,
transition: 'left .1s',
marginRight: theme.spacing(2),
background: '#3f51b5',
'& div:first-element': {
marginTop: 100
}
}
menuOpen: {
left: 0,
},
menuClose: {
left: -200,
},
}),
);
...
const YourStyledCommponent = ({ classes }) => {
const [isOpen, setOpen] = useState(false);
return (
<SomeMuiComponent
className={clsx(classes.menu, {
[classes.menuOpen]: isOpen,
[classes.menuClose]: !isOpen,
})}
/>
);
}
Of course you could also say that your base menu style will be the close state, and then you end up having only one additional style:
import clsx from "clsx";
...
const useStyles = makeStyles((theme: Theme) =>
createStyles({
menu: {
zIndex: 1,
width: 200,
height: '100%',
position: 'fixed',
top: 48,
transition: 'left .1s',
marginRight: theme.spacing(2),
background: '#3f51b5',
left: -200,
'& div:first-element': {
marginTop: 100
}
}
menuOpen: {
left: 0,
},
}),
);
...
const YourStyledCommponent = ({ classes }) => {
const [isOpen, setOpen] = useState(false);
return (
<SomeMuiComponent
className={clsx(classes.menu, {
[classes.menuOpen]: isOpen,
})}
/>
);
}
EDIT: as stated by @Ryan Cogswell in the comments, clsx
would be the recommended library if you are using Material UI >= v4.0, since it already comes included in it 😁.
Upvotes: 3