Skip to content

Commit

Permalink
Merge pull request #417 from jpudysz/fix/withUnistyles-types
Browse files Browse the repository at this point in the history
fix: withUnistyles types
  • Loading branch information
jpudysz authored Dec 11, 2024
2 parents 4473a52 + 73a9c3f commit 4dc3a31
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/core/withUnistyles/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import type { UnistylesTheme } from '../../types';
export const SUPPORTED_STYLE_PROPS = ['style', 'contentContainerStyle'] as const

export type SupportedStyleProps = typeof SUPPORTED_STYLE_PROPS[number]
export type Mappings<T extends Record<string, any> = {}> = (theme: UnistylesTheme, rt: UnistylesMiniRuntime) => Omit<Partial<T>, SupportedStyleProps>
export type Mappings<T = {}> = (theme: UnistylesTheme, rt: UnistylesMiniRuntime) => Omit<Partial<T>, SupportedStyleProps>
19 changes: 13 additions & 6 deletions src/core/withUnistyles/withUnistyles.native.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
import React, { type ComponentType, forwardRef, useEffect, useRef } from 'react'
import React, { forwardRef, useEffect, useRef, type ComponentType } from 'react'
import { StyleSheet, UnistyleDependency } from '../../specs'
import type { PartialBy } from '../../types/common'
import { deepMergeObjects } from '../../utils'
import { SUPPORTED_STYLE_PROPS } from './types'
import type { Mappings, SupportedStyleProps } from './types'
import { useDependencies } from './useDependencies'

export const withUnistyles = <TProps extends Record<string, any>, TMappings extends TProps>(Component: ComponentType<TProps>, mappings?: Mappings<TMappings>) => {
// @ts-expect-error
type GenericComponentProps<P> = ComponentProps<P>
// @ts-expect-error
type GenericComponentRef<T> = ComponentRef<T>

export const withUnistyles = <TComponent, TMappings extends GenericComponentProps<TComponent>>(Component: TComponent, mappings?: Mappings<TMappings>) => {
type TProps = GenericComponentProps<TComponent>
type PropsWithUnistyles = PartialBy<TProps, keyof TMappings | SupportedStyleProps> & {
uniProps?: Mappings<TProps>
}

return forwardRef<unknown, PropsWithUnistyles>((props, ref) => {
return forwardRef<GenericComponentRef<TComponent>, PropsWithUnistyles>((props, ref) => {
const narrowedProps = props as PropsWithUnistyles
const stylesRef = useRef<Record<string, any>>({})
const isForcedRef = useRef(false)
const NativeComponent = Component as ComponentType

if (!isForcedRef.current) {
SUPPORTED_STYLE_PROPS.forEach(propName => {
if (narrowedProps?.[propName]) {
if (Array.isArray(narrowedProps[propName])) {
console.error(`🦄 Unistyles: createUnistylesComponent requires ${propName} to be an object. Please check props for component: ${Component.displayName}`)
console.error(`🦄 Unistyles: createUnistylesComponent requires ${propName} to be an object. Please check props for component: ${NativeComponent.displayName}`)
}

// @ts-expect-error - this is hidden from TS
if (props[propName].__unistyles_name && !props[propName].__proto__?.getStyle) {
console.error(`🦄 Unistyles: createUnistylesComponent received style that is not bound. You likely used the spread operator on a Unistyle style. Please check props for component: ${Component.displayName}`)
console.error(`🦄 Unistyles: createUnistylesComponent received style that is not bound. You likely used the spread operator on a Unistyle style. Please check props for component: ${NativeComponent.displayName}`)
}

stylesRef.current = {
Expand Down Expand Up @@ -84,6 +91,6 @@ export const withUnistyles = <TProps extends Record<string, any>, TMappings exte

isForcedRef.current = false

return <Component {...finalProps as TProps} ref={ref} />
return <NativeComponent {...finalProps as TProps} ref={ref} />
})
}
19 changes: 14 additions & 5 deletions src/core/withUnistyles/withUnistyles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState, type ComponentType, forwardRef, useRef, useMemo } from 'react'
import React, { useEffect, useState, type ComponentType, forwardRef, useRef, useMemo, type ComponentProps, type ComponentRef } from 'react'
import type { PartialBy } from '../../types/common'
import { UnistylesListener } from '../../web/listener'
import { UnistylesShadowRegistry } from '../../web'
Expand All @@ -7,6 +7,7 @@ import { deepMergeObjects } from '../../utils'
import type { Mappings, SupportedStyleProps } from './types'
import { useDependencies } from './useDependencies'
import { UnistyleDependency } from '../../specs/NativePlatform'
import type { UnistylesValues } from '../../types'

const useShadowRegistry = (style?: Record<string, any>) => {
const [ref] = useState(document.createElement('div'))
Expand Down Expand Up @@ -37,12 +38,20 @@ const useShadowRegistry = (style?: Record<string, any>) => {
return classNames
}

export const withUnistyles = <TProps extends Record<string, any>, TMappings extends TProps>(Component: ComponentType<TProps>, mappings?: Mappings<TMappings>) => {
// @ts-expect-error
type GenericComponentProps<T> = ComponentProps<T>
// @ts-expect-error
type GenericComponentRef<T> = ComponentRef<T>

export const withUnistyles = <TComponent, TMappings extends GenericComponentProps<TComponent>>(Component: TComponent, mappings?: Mappings<TMappings>) => {
type TProps = GenericComponentProps<TComponent>
type PropsWithUnistyles = PartialBy<TProps, keyof TMappings | SupportedStyleProps> & {
uniProps?: Mappings<TProps>
style?: UnistylesValues,
contentContainerStyle?: UnistylesValues
}

return forwardRef<unknown, PropsWithUnistyles>((props, ref) => {
return forwardRef<GenericComponentRef<TComponent>, PropsWithUnistyles>((props, ref) => {
const narrowedProps = props as PropsWithUnistyles
const styleClassNames = useShadowRegistry(narrowedProps.style)
const contentContainerStyleClassNames = useShadowRegistry(narrowedProps.contentContainerStyle)
Expand Down Expand Up @@ -72,9 +81,9 @@ export const withUnistyles = <TProps extends Record<string, any>, TMappings exte
'unistyles': contentContainerStyleClassNames.join(' ')
},
} : {},
} as TProps
} as any

const NativeComponent = Component as ComponentType<TProps>
const NativeComponent = Component as ComponentType

return <NativeComponent {...combinedProps} ref={ref} />
})
Expand Down

0 comments on commit 4dc3a31

Please sign in to comment.