Allow component authors to force component consumers to provide the `as` prop
See original GitHub issueIs your feature request related to a problem? Please describe. The feature request is pretty well captured by the title, I think. But here’s an example use case:
I’d like to make a generic Heading
component, which would have a different size
variants to control how big the text is. The issue is that it’s very difficult to know what HTML element this component should render:
- the visually-bigger headings likely want a higher-numbered
<hx>
tag, but I want a single Heading component, not a different component for each tag<h1>
-<h6>
that might be appropriate; - even if I had multiple components that used different default
<hx>
tags, I might want the user to have to consciously pick a heading level for semantic/SEO reasons, accounting for the other headings on the page.
Describe the solution you’d like
One possible API I’d like is for the author of the component to be able to use null
to indicate that the component user must provide the base element/component, as in:
const Heading = styled(null, {
variants: {
size: {
1: { fontSize: 30 },
2: { fontSize: 25 },
// ... etc
}
}
});
// user of component... omitting `as` triggers a type and/or runtime error
<Heading as="h1" size={1}>Some text</Heading>
Describe alternatives you’ve considered
For solving this specific use case, I considered creating multiple components (const H1 = styled("h1", ...); const H2 = styled("h2", ...)
), but rejected that because it’s clunkier (lots more to define – and then to import everywhere), and it still doesn’t force the component user to opt-in to an appropriate heading level.
Beyond this one use case, I didn’t spend too much time thinking about alternate APIs, but many could work.
Additional context Add any other context or screenshots about the feature request here.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
+1 on creating multiple components
Example:
I personally love this approach. Statically defining stuff. You only gotta do it once haha
Let me know what you think
Glad it helped. In our design system, we have a
Heading
Component that we do something very similar. It’s the “smart” component on top of the low levelText
. And it’s responsible for applying the correct variants based on itssize
variant.Have a look: https://github.com/radix-ui/design-system/blob/master/components/Heading.tsx
The power of this approach is that we delegate the logic to React (or JS), instead of bloating Stitches.
Stitches is meant to be as low level as possible. You can create variants, and they are immutable. If you need logic on how to apply, thats the responsibility of the product.