TheMightyPenguin / dessert-box

An utility to create a Box component from your vanilla-extract + sprinkles tokens.
MIT License
343 stars 20 forks source link

Apply `as` in advance #6

Closed waynevanson closed 3 years ago

waynevanson commented 3 years ago

I'm looking to achieve something similar to styled(Component). I really need to find out the types for the props when as is applied.

// imagine this does something fancy or stateful
const MyComponent = (props) => <div {...props}  />;

const Box = createBoxWithAtomsProp(atoms);
const AsBox = (props/*: Calculate Me */) => <Box {...props} as={MyCompent} />

Trying a few things with little success.

TheMightyPenguin commented 3 years ago

@waynevanson at the moment the as prop only supports html elements, I'll update it so it supports any React component 👍

graup commented 3 years ago

Just as a heads up, other frameworks are struggling with fully polymorphic as.

https://mobile.twitter.com/peduarte/status/1424032229659979778 https://mobile.twitter.com/jjenzz/status/1423766700885954562

TheMightyPenguin commented 3 years ago

@graup Yeah thanks a lot for the heads up! I've been also seeing this trend lately, and actually struggled with Type inference performance in this library, I just put out a new version improving type performance by simplifying the logic for it! It implies also a bit less precise inference, but good enough to make the tradeoff (specially in big projects, this will help a lot with the editor experience and compiling times).

TheMightyPenguin commented 3 years ago

@waynevanson sorry for the delay here, you can solve this by doing something like:

const Button = (props: { text: string } & React.ComponentProps<"button">) => {
  return <button {...props}>{props.text}</button>;
};

const ButtonAsBox = (
  props: React.ComponentProps<typeof Box> & React.ComponentProps<typeof Button>
) => <Box as={Button} {...props} />;

// And then use it like:
< ButtonAsBox background="yellow" padding="extraLarge" text="Hello" />

The important part here is using React.ComponentProps to get the props from both Box and the other component you're interested in!

Also, a useBox hook will be coming soon that will make using the Box props in other components a bit easier.

I'd also recommend using Box directly of that other component if you're in control of that, as Box is meant to be used as a styling primitive inside of our apps, I recommend reading the FAQ section in our READMe (just added ✨).

Closing this @waynevanson, please feel free to reopen if this didn't help.

waynevanson commented 3 years ago

Great work, I've got nothing more to add!