Replies: 2 comments 2 replies
-
Wow, this is some write up! Thank you 🚀 I'm all for standardising this and coincidentally had also considered exposing a
Haha, it definitely won't! That was just to show how I expected
I'm intrigued how this idea would be typed with TS. I'm not sure my TS experience stretches far enough to know how to grab prop types of an undefined tuple length. I'd love to hear some thoughts on the TS side to this all because we have also been discussing this part internally. Performance for polymorphism is not great. Things we have discussed are typing the |
Beta Was this translation helpful? Give feedback.
-
I really like this idea. I think the symbol should be specific to React while unspecific to Radix or Stitches. A symbol like Creating a polymorphic symbol: let polymorphic = Symbol.for('react.polymorphic') Creating a polymorphic component: function PolymorphicComponent() {}
PolymorphicComponent[polymorphic] = true Testing whether a component is polymorphic: if (PolymorphicComponent[polymorphic]) {
// component is polymorphic
} if (polymorphic in PolymorphicComponent) {
// component is polymorphic
} Why a symbol? Because symbols are far less likely to collide with keys any other code might add to the object, and because symbols are hidden from mechanisms other code will typically use to access the object, like for-in loops or |
Beta Was this translation helpful? Give feedback.
-
I'm a fan of the polymorphic
as
prop. I've been using it in React Interactive since 2016 (I think this was the first occurrence), and since then it's seen wide spread use with Styled Components helping to popularize it. With multiple libraries implementing the polymorphicas
prop, I think composability needs to be added to polymorphism (the lack of composability has already caused multiple issues, for example #448). A standardized polymorphic API that libraries and components can implement would accomplish this, and would allow multiple polymorphic components to work together seamlessly.The idea for this is something that I've been thinking about on and off for a bit, and was inspired by this clever
styled
function PoC by @jjenzz.⚡️ API ideas (below) ⚡️ Proof of concept npm package
Try out the proof of concept in CodeSandbox
API ideas
The API needs to define a standardized way to:
styled
function)Determine at runtime if the API is implemented
The simplest solution is probably to add a property to the component indicating support for the API (the
polymorphicAsArray
name will be explained in the next section).Create multilevel polymorphism
Polymorphic components can support multilevel polymorphism by accepting an array for the
as
prop.polymorphicAsArray
API would need to:as
propas
array and check if it supports thepolymorphicAsArray
API, if yes render it and pass through the remainingas
array. If it doesn't implement the API, discard it, and check the next item. Repeat until either it finds a component that supports thepolymorphicAsArray
API, or it gets to the last item in the array, then always render it.polymorphicAsArray
API and pass through theas
prop to that component untouched.polymorphicAsArray
property on the component totrue
.ref
forwarding (not done in the below example).Note that the PoC npm package exports a helper function
polymorphicAsArrayUtil
that implements theas
array logic.Merge two lines of polymorphism with a create function
polymorphicAsArray
API and merges two lines of polymorphism would need to:as
array as the first argument (additional arguments can be supported for specific functionality, e.g. a styles object, default props object, etc).as
prop.as
prop to the end of theas
array argument passed to the create function.as
array as describe above in Create multilevel polymorphism (render the first item that supports thepolymorphicAsArray
API and pass through the remaining array).polymorphicAsArray
property set totrue
.ref
forwarding (not done in below example).Note that the PoC npm package exports a helper function
polymorphicAsArrayUtil
that implements theas
array logic.Related to
as
prop onstyled(Component)
components #448 (and dupes Wrapping Radix DropdownMenu.Item withstyled
breaks keyboard navigation #479, Issue composing downas
prop #561)Beta Was this translation helpful? Give feedback.
All reactions