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.