On a webapp with mui (AKA Material UI), there’s everyone favorite component: <Box />
. Why is Box beloved? It’s because unlike our usual goto div-soup generator, div
lacks the sx
prop. It’s sort of a mix between inline styles, inline “styled component” syntax, and maybe even a little bit of inline utility css. All in one. Box is boundless with potential.
<Box />
desugars into <div />
unless you give it a component="ul"
prop, then it could become a <ul />
. My assumption had been for a long time that without Box, I would not get the benefits of having sx
props as an option. But you can! Using styled
.
Here’s look at an example, we want to make vertical list using a ul
. Even though it would be great if we could do this, this fails:
<br food={{}} />
<ul sx={(theme) => ({ /* 👈 in general, this would not work, you can't use the sx prop on an ordinary tagged element */
listStyle: "none",
display: "flex",
flexDirection: "column",
gap: theme.spacing(6),
})}>
/* more elements */
</ul>
As an alternative that actually works, using @mui/system
styled
, we can give a name to these styles and preserve the sx
prop capability allowing us to have adhoc styles when we need them still.
export const VerticallySpacedList = styled(`ul`)(({ theme }) => ({
listStyle: "none",
display: "flex",
flexDirection: "column",
gap: theme.spacing(6),
}));
Now, we can reference this as we’d like:
<VerticallySpacedList>
/* more elements */
</VerticallySpacedList>
What’s nice about this is that we can use sx
on <VerticallySpacedList />
:
<VerticallySpacedList sx={{fontSize: "2rem", lineHeight: 1.5}}>
/* more elements */
</VerticallySpacedList>
This saves us from have an explosion of one-off subtly named components like VerticallySpacedList
and VerticallySpacedListWithBiggerTextSize
and BoldVerticallySpacedList
. There’s a core, common style as a base and then sx
handles incidentials.
There’s nothing quite like Tailwind for utility css, but with <Box />
, sx
and styled
, maybe it comes in a distant second.
Follow me on Mastodon @ryanmr@mastodon.cloud.
Follow me on Twitter @ryanmr.