question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow component authors to force component consumers to provide the `as` prop

See original GitHub issue

Is 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:open
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
peduartecommented, Sep 20, 2021

+1 on creating multiple components

  • It’s clearer on the layout side which markup is being rendered
  • It doesn’t require polymorphism (as prop), meaning better TS experience
  • You rely on a base style composition

Example:

const baseHeading = css({ 
  variants: { 
    size: { 
      1: { fontSize: 30 },
      2: { fontSize: 25 },
      // ... etc
    }
  }
});

const H1 = styled('h1', baseHeading, {
  defaultVariants: {
    size: '1'
  }
}

const H2 = styled('h2', baseHeading, {
  defaultVariants: {
    size: '2'
  }
}

const H3 = styled('h4', baseHeading, {
  defaultVariants: {
    size: '3'
  }
}

I personally love this approach. Statically defining stuff. You only gotta do it once haha

Let me know what you think

1reaction
peduartecommented, Sep 21, 2021

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 level Text. And it’s responsible for applying the correct variants based on its size 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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Context - React
Context provides a way to pass data through the component tree without having to pass props down manually at every level. In a...
Read more >
A better way of solving prop drilling in React apps
In the spirit of "using the platform," learn how the React library provides a workaround for prop drilling without Redux or the Context...
Read more >
How can I force a component to re-render with hooks in React?
This is possible with useState or useReducer , since useState uses useReducer internally: const [, updateState] = React.useState(); const forceUpdate ...
Read more >
Typing Svelte Component Props/Events/Slots [Feedback ...
Objective. Given the user-specified multiple prop, infer the type of the value prop.
Read more >
Better Reusable React Components with the Overrides Pattern
Similarly, component authors sometimes offer props like getFooStyle or ... and forces you to think more critically about how consumers will ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found