jpudysz / react-native-unistyles

Level up your React Native StyleSheet

Home Page:https://unistyl.es

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dynamic functions ignore variants

b4lk0n opened this issue · comments

Description

When describing a stylesheet using dynamic functions, variants are ignored.
The linked repository includes two branches demonstrating the issue on a simple Text component with variants.

In both branches the component is used in the identical way:

import { Text } from '../ui/text'
import { View } from 'react-native'

export default function HomePage() {
  return (
    <View style={{ padding: 70 }}>
      <View>
        <Text variant="title">Title</Text>
      </View>
      <View>
        <Text variant="body">Body</Text>
      </View>
    </View>
  )
}

The main branch contains the component with stylesheets declared as an object as follows:

import { Text as NativeText, TextProps as NativeTextProps } from 'react-native'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

type TextProps = NativeTextProps & {
  variant?: 'body' | 'title'
  color?: 'neutral' | 'primary'
}

export function Text({ variant = 'body', color = 'neutral', ...props }: TextProps) {
  const { styles } = useStyles(stylesheet, {
    variant,
    color,
  })

  return <NativeText {...props} style={styles.root} />
}

const stylesheet = createStyleSheet((theme) => ({
  // NOTE - `root` is an object
  root: {
    fontStyle: 'italic',

    variants: {
      variant: {
        title: {
          fontSize: 90,
        },
        body: {
          fontSize: 18,
        },
      },
      color: {
        neutral: {
          color: theme.colors.neutral,
        },
        primary: {
          color: theme.colors.primary,
        },
      },
    },
  },
}))

The result is as expected. Both texts are italicized. The first one is of a large size, while the second one is smaller:
Simulator Screenshot - iPhone 15 Pro - 2023-12-20 at 13 45 12

The dynamic_funcs branch contains the same component, but the stylesheet is defined as a function:

import { Text as NativeText, TextProps as NativeTextProps } from 'react-native'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

type TextProps = NativeTextProps & {
  variant?: 'body' | 'title'
  color?: 'neutral' | 'primary'
}

export function Text({ variant = 'body', color = 'neutral', ...props }: TextProps) {
  const { styles } = useStyles(stylesheet, {
    variant,
    color,
  })

  return <NativeText {...props} style={styles.root()} />
}

const stylesheet = createStyleSheet((theme) => ({
  // NOTE - `root` is a function
  root: () => ({
    fontStyle: 'italic',

    variants: {
      variant: {
        title: {
          fontSize: 90,
        },
        body: {
          fontSize: 18,
        },
      },
      color: {
        neutral: {
          color: theme.colors.neutral,
        },
        primary: {
          color: theme.colors.primary,
        },
      },
    },
  }),
}))

The result of the above code is weird. Both texts are still italic, meaning that the common fontStyle: 'italic' was applied. However, the variants are completely ignored, reverting text sizes and colors to their default values:
Simulator Screenshot - iPhone 15 Pro - 2023-12-20 at 13 46 52

Steps to reproduce

  1. Clone https://github.com/b4lk0n/unistyles-dynamic-functions-variants
  2. Install dependencies via yarn
  3. Staying on the main branch, launch the app by yarn ios
  4. Observe the large "Title" and smaller "Body" words, both are italic
  5. git switch dynamic_func
  6. Reload app
  7. Observe the variants styles for the words "Title" and "Body" have gone

Snack or a link to a repository (optional)

https://github.com/b4lk0n/unistyles-dynamic-functions-variants

Unistyles version

2.0.0-rc.2

React Native version

0.72.6

Platforms

iOS

Engine

Hermes

Architecture

Fabric (new)

Thanks for the detailed report, I will take a look 🙏

Published with RC.3

confirm that RC.3 fixes the issue. Thanks for such a quick fix, @jpudysz ⚡💪🏻

Haha, I immediately knew where the issue was 😃 Thank you for pointing it out. That's the first bug reported for 2.0!