dripsy: Recursively creating themed component doesn't work
What
There’s a bug with createThemedComponent
(and thus styled
), where passing a component made by dripsy to it doesn’t work.
import { styled, View } from 'dripsy'
import * as Native from 'react-native'
const Container = styled(View) // 🚨error
const Wrapper = styled(Native.View) // 👍 works
Same goes for createThemedComponent
:
import { createThemedComponent, View } from 'dripsy'
import * as Native from 'react-native'
const Container = createThemedComponent(View) // 🚨error
const Wrapper = createThemedComponent(Native.View) // 👍 works
Why
First, this bug needs to be fixed for the custom pragma from #31 to get merged.
Second, I’ve really enjoyed using the styled
function from the fresnel-2
branch in my real-world app. styled
is a wrapper around createThemedComponent
with a cooler name and syntax.
While using the sx
prop is the central API, I would like to treat styled
syntax as a first-class citizen, too.
import { styled } from 'dripsy'
const Container = styled(View)({
maxWidth: 10
})
I’ve enjoyed the API of naming UI elements outside of the component scope. It prevents cluttering the return statement with styles.
With styled-components
, this was pretty annoying, because I had to pass a function to my styles, redeclare prop types, and it was just a mess. But with dripsy
, it’s easy; I can still pass an sx
prop to the component returned by styled
if it needs render-specific variables in its styles, like so:
const Container = styled(View)({
maxWidth: 10
})
const Box = ({ height }) => <Container sx={{ height }} />
How
I’m not fully sure why this bug is exists, but I could see issues with recursively wrapping components in HOCs.
I think an easy solution would be to add something like a static isDripsyComponent
field to any component returned by createThemedComponent
. Then, in createThemedComponent
, we check if it already is a dripsy component. If it is, we just return the component itself and forward the props down – nothing special.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 17 (17 by maintainers)
For whatever reason, I cannot get the TS suggestions for
SxProps['sx']
type to work when it’s a return type of a function.I’ve also tried using
SxStyleProp
andThemeUIObject
, but no luck yet. When I use my own custom type, it works fine.Here’s the updated
createThemedComponent
file:Once I get this fixed I’ll clean up the code and remove old stuff that went unused. The naming is a bit confusing in a number of places, too.
@cmaycumber I haven’t updated to put your explicit return type changes yet, I can add that once I figure this out.
Got it, I’ll try this out.
ComponentType
probably makes more sense. I see that@expo/html-elements
is usingReact.PropsWithChildren
, I haven’t used that type before.I’m also working on figuring out a way to get
React.memo
to work without using@ts-ignore
, such that it forwards the correct details. Something like this might work to forward the props generic:But I’m not sure if it works with forwarding refs too yet.
Another temporary workaround building off my previous one that fixes @expo/html-elements would add an additional optional child prop:
Another thing to note
React.FC
can be replaced withComponentType
which may be more accurate because it shows aReact.ForwardRefExoticComponent
as the return type.Okay I think it actually is just a TS error for
createThemedComponent
, and that it’s actually breaking forstyled
. I need to keep testing to be sure. If it is, @cmaycumber’s work-around should do it:In any case, I should probably re-write
styled
, either to 1) matchcreateThemedComponent
from scratch, or 2) to simply returncreateThemedComponent
. Option 1 would allow us to pass a pure function to determine styles, option 2 would only allow a plain sx object.The simplest rewrite would look like this:
Which would allow this usage:
…but it would not allow this usage:
The passing around of props and
ref
s gets pretty messy in React with this many HOCs. It seems like the current (and admittedly messy) implementation ofstyled
is breaking somewhere along the way of recursively forwarding props and refs (or so I would guess).I’ll test that out.
It actually is more than a TS error, for some reason the actual renders don’t work properly.
This might be a decent workaround if the types are the only issue.
I’ve tried to make some work-arounds but still haven’t been able to debug this.