I'm working on a reusable sidebar, with React & CSS-in-JS with the @emotion/react library
I have a ReactComponent that returns something like this:
return (
<s.SidebarContainer
backgroundImage={backgroundImage}
isOpen={isOpen}>
<s.TogglerContainer
onClick={() => setIsOpen(!isOpen)}
isOpen={isOpen}>
</s.TogglerContainer>
<s.SidebarHeader
font={fonts.header}
>
{header}
</s.SidebarHeader>
<s.MenuContainer>{menuItemsJSX}</s.MenuContainer>
</s.SidebarContainer>
)
As you can see, I attach the props to each style component. And this is my style.js:
import styled from '@emotion/styled';
export const SidebarContainer = styled.div`
width: ${p => p.isOpen ? '18%' : '5%'} ;
background-image:
linear-gradient(
315deg,
rgba(252,82,150,0.8) 0%,
rgba(246,112, 98, 0.8) 74%),
url(${p => p.backgroundImage}
);
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
color: white;
position: relative; // Toggler
transition: .2s ease-in all;
@media (max-width: 576.97px){
width: ${p => p.isOpen ? '80%' : '15%'} ;
}
@media (min-width: 577px) and (max-width: 992px){
width: ${p => p.isOpen ? '30%' : '7%'} ;
}
`
export const SidebarHeader = styled.h3`
text-align: center;
height:10%;
margin-top: .5em;
letter-spacing: .1em;
font-size: 1em;
font-family: ${p => p.font};
overflow: hidden;
padding: 0em .3em;
`
export const TogglerContainer = styled.div`
position: relative;
&:after{
${p => p.isOpen ? `content:'<';`
: `content:'>';`}
text-align:center;
position:absolute;
background-color: #E58C8A;
background-image: linear-gradient(315deg, #E58C8A 0%, #EEC0C6 74%);
right:0;
transform: translateX(12px);
width: 24px;
height: 24px;
margin-top:2em;
border-radius: 50%;
color:rgb(19,15,64);
box-shadow: 4px 2px 2px rgba(0,0,0,0.3);
transition: .2s ease-in box-shadow;
}
&:hover{
&:after{
box-shadow: 5px 3px 3px rgba(0,0,0,0.3);
transition: .2s ease-in all;
}
}
`
I just put a part of code to avoid fill your display. My question is:
There's some way to send the props to .style.js file only once (through file instead through component), and then in .style.js file recive it and use it globally?
For example, i want had something like this,
<s.SidebarContainer
backgroundImage={backgroundImage} >
<s.TogglerContainer
onClick={() => setIsOpen(!isOpen)}>
(see what i removed isOpen={isOpen}
)
You must provide the prop to each styled component that depends on the prop.
Each styled component is a react component, and emotion will re-render the component when the props change, allowing you to adjust the styles based on props. It would not be possible to pass the
isOpen
state to only one styled component and share that state with the rest of the styled components because each component must receive theisOpen
state via its own props.