nandorojo / dripsy

🍷 Responsive, unstyled UI primitives for React Native + Web.
https://dripsy.xyz
MIT License
1.99k stars 77 forks source link

fix: add types for `ElementRef` support #237

Closed jjenzz closed 1 year ago

jjenzz commented 1 year ago

Note: Easier to review with hidden whitespace changes

Closes #225

vercel[bot] commented 1 year ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
dripsy ❌ Failed (Inspect) Sep 14, 2022 at 8:46PM (UTC)
nandorojo commented 1 year ago

This is 🔥🔥🔥

I never knew how to get inferred refs to get to work. I'd love to get this to work for moti too. I'll try to copy this over there.

nandorojo commented 1 year ago

One thing – I'm getting this error when I run yarn (which triggers yarn prepare):

src/css/create-themed-component.tsx(48,52): error TS2345: Argument of type 'PropsWithChildren<StyledProps<ThemeKey> & Props>' is not assignable to parameter of type 'ExtraProps'.
  'ExtraProps' could be instantiated with an arbitrary type which could be unrelated to 'PropsWithChildren<StyledProps<ThemeKey> & Props>'.
nandorojo commented 1 year ago

I added a commit to ignore it – I think it's fine since it's just an implementation detail.

nandorojo commented 1 year ago

Let me know if it's good to go, and I'll merge + release.

jjenzz commented 1 year ago

i'll take a quick look at that issue, i think i know the cause...

jjenzz commented 1 year ago

@nandorojo all should be good to go now :)

nandorojo commented 1 year ago

Published in 3.8.0!

jjenzz commented 1 year ago

@nandorojo hmmm, i've pulled the latest version and for some reason the following code is fine in this project but errors in mine. does this work for you?

interface CircleProps {
  size?: number
  color?: 'red' | 'green'
}

const Circle = styled(View)<CircleProps>((props) => ({
  width: props.size || 56,
  height: props.size || 56,
  backgroundColor: props.color ?? 'transparent',
  borderRadius: 9999,
  justifyContent: 'center',
  alignItems: 'center',
  overflow: 'hidden',
}))

export const Foo = () => {
  return (
    <Circle
      size={20}
      sx={{
        backgroundColor: 'crimson',
        position: 'absolute',
        right: -6,
        bottom: 2,
      }}
    />
  )
}
nandorojo commented 1 year ago

Oh, it's because the first generic of styled became C, when it used to be Props, right?

nandorojo commented 1 year ago
const Circle = styled(View)((props: CircleProps) => ({

This fixes it, but it still keeps a breaking change.

nandorojo commented 1 year ago

I think this should fix it:

export function styled<
  Props,
  C extends ComponentType<any>,
  ThemeKey extends keyof DripsyFinalTheme = keyof DripsyFinalTheme
>(
  Component: C,
  {
    themeKey,
    defaultVariant,
  }: Pick<ThemedOptions<any, ThemeKey>, 'themeKey' | 'defaultVariant'> = {}
) {
  return function dripsyFactory<Extra>(
    defaultStyle?: ThemedOptions<Extra & Props, ThemeKey>['defaultStyle']
  ) {
    return createThemedComponent<C, Extra & Props, ThemeKey>(Component, {
      defaultVariant,
      themeKey,
      defaultStyle,
    })
  }
}

This way, we can still explicitly pass a props generic to styled()

nandorojo commented 1 year ago

Hm, that actually did not fix it for me. I'll have to keep looking.