I'd like to have a component, styled with Emotion, that takes props that ultimately control the styling. For example, consider a GridCol
component that has various props that change the padding and width (the width can be changed across different viewport widths).
I'd like to use an API like this:
<GridCol gutter size="2>
// or alternatively, like this:
<GridCol gutter size={{
m: 2,
l: 4
}}>
There are three things happening here:
- the
gutter
is a boolean prop that adds some horizontal padding to the column - the
size
prop can be a string or an object. If it is a string, we just add a few lines of CSS and we're good, however, if it is an object, we need to insert some media-queries based on a breakpoints object that is set elsewhere.
Emotion's docs are not clear how to handle styling of this nature, at least I have not seen it, so I was hoping that a common solution could be found.
For the gutter
prop, it is trivial:
const GridCol = props => styled('div')`
display: block;
box-sizing: border-box;
flex: 1 0 0;
min-width: 0;
padding: ${props.gutter ? `0 10px` : '0'};
`
For the size
prop, it becomes more complicated, I'd like the resultant CSS to look something like this:
const GridCol = props => styled('div')`
display: block;
box-sizing: border-box;
flex: 1 0 0;
min-width: 0;
padding: ${props.gutter ? `0 10px` : '0'};
/* styles here if `size` is a string */
width: 10%;
/* styles here if `size` is an object */
@media screen and (min-width: 500px) {
width: 20%;
}
@media screen and (min-width: 800px) {
width: 30%;
}
@media screen and (min-width: 1100px) {
width: 40%;
}
`
The width
values will be determined by the prop's key, which corresponds to a value in a breakpoints
object, this part is not trivial, but I don't know how to dynamically generate the css needed.
I'm sure there's more info that I could add, I have made some attempts but none of them are working at the moment. My feeling is that I should create a stateless functional component that generates the css for each condition, then joins the CSS at the end..