Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v3] Multiple variants children styles not being applied #591

Closed
jordmccord opened this issue Feb 13, 2025 · 6 comments
Closed

[v3] Multiple variants children styles not being applied #591

jordmccord opened this issue Feb 13, 2025 · 6 comments

Comments

@jordmccord
Copy link

Description

Hey guys, I've noticed when adding multiple compound variants of a component to a screen that some of the child elements do not have their styles applied

Correct button text colours Incorrect button text colours
Image Image
Image Image
Image Image

Steps to Reproduce

  1. Create a component with multiple compound variants e.g Button
  2. Create a nested child component with compound variants e.g ButtonText
  3. Add the all different variants to a screen and notice that the child styles are not applied, whereas they are when in isolation e.g Variants Story vs Kitchen Sink story

Snack or Repository Link (Optional)

https://github.com/utilitywarehouse/design-systems/tree/uwds-2978/packages/native-ui/src/components/Button

Unistyles Version

3.0.0-beta.7

React Native Version

0.77

Platforms

Android, iOS, Web

Expo

Yes

@jordmccord
Copy link
Author

Interestingly, the disabled state Text and Spinner components have the correct colours, which are also compound variants

@jpudysz
Copy link
Owner

jpudysz commented Feb 13, 2025

Well it's getting harder 😆

Thanks, will take a look!

PS: You selected web, so it's also a web issue?

@jordmccord
Copy link
Author

jordmccord commented Feb 13, 2025

Yes, all three platforms have the same issue (see the 3rd screenshots)

@jpudysz jpudysz added this to the 3.0.0-beta.8 milestone Feb 13, 2025
@jpudysz
Copy link
Owner

jpudysz commented Feb 14, 2025

@jordmccord I need a small repro, as it works as intended on my side.
Not sure if that's your context or something, but you can always console.log styles and verify the output.

I created 2 components:

Button:

import { Pressable } from 'react-native'
import { StyleSheet, UnistylesVariants } from 'react-native-unistyles'
import { ButtonText } from './ButtonText'

type ButtonProps = {
    text: string,
    onPress: () => void
} & UnistylesVariants<typeof styles>

export const Button: React.FunctionComponent<ButtonProps> = ({ text, onPress, variant, size, color }) => {
    styles.useVariants({
        variant,
        size,
        color
    })

    console.log(styles)

    return (
        <Pressable onPress={onPress} style={styles.container}>
            <ButtonText text={text} color={color} size={size} />
        </Pressable>
    )
}

const styles = StyleSheet.create(theme => ({
    container: {
        width: '100%',
        justifyContent: 'center',
        alignItems: 'center',
        variants: {
            variant: {
                solid: {},
                outline: {
                    backgroundColor: 'transparent',
                    borderWidth: 2,
                },
                ghost: {
                    backgroundColor: 'transparent',
                    borderWidth: 0,
                },
            },
            size: {
                small: {
                    paddingVertical: theme.gap(1),
                    height: 32,
                },
                medium: {
                    paddingVertical: theme.gap(2),
                    height: 48,
                },
                large: {
                    paddingVertical: theme.gap(3),
                    height: 78,
                },
            },
            color: {
                cyan: {
                    backgroundColor: 'cyan'
                },
                red: {
                    backgroundColor: 'red'
                },
                blue: {
                    backgroundColor: 'blue'
                },
            }
        },
        compoundVariants: [
            {
                color: 'cyan',
                size: 'large',
                styles: {
                    borderWidth: 4,
                    borderColor: 'black'
                }
            },
            {
                color: 'red',
                size: 'large',
                styles: {
                    borderWidth: 4,
                    borderColor: 'black'
                }
            },
            {
                color: 'blue',
                size: 'large',
                styles: {
                    borderWidth: 4,
                    borderColor: 'black'
                }
            }
        ]
    },
    text: {
        fontWeight: 'bold',
        fontSize: 20
    }
}))

and ButtonText:

import { StyleSheet, UnistylesVariants } from 'react-native-unistyles'
import { TextStyle, Text } from 'react-native'

type ButtonTextProps = {
    style?: TextStyle
    text: string
} & UnistylesVariants<typeof styles>

export const ButtonText: React.FunctionComponent<ButtonTextProps> = ({ text, style, color, size }) => {
    styles.useVariants({
        color,
        size
    })

    console.log(styles)

    return (
        <Text style={[styles.text, style]}>
            {text}
        </Text>
    )
}

const styles = StyleSheet.create(theme => ({
    text: {
        lineHeight: 20,
        variants: {
            size: {
                small: {
                    fontSize: 12
                },
                medium: {
                    fontSize: 16
                },
                large: {
                    fontSize: 22
                },
            },
            color: {
                cyan: {
                    color: 'white'
                },
                red: {
                    color: 'green'
                },
                blue: {
                    color: 'red'
                },
            }
        },
        compoundVariants: [
            {
                color: 'cyan',
                size: 'large',
                styles: {
                    lineHeight: 18
                }
            },
            {
                color: 'red',
                size: 'large',
                styles: {
                    lineHeight: 22
                }
            },
            {
                color: 'blue',
                size: 'large',
                styles: {
                    lineHeight: 28
                }
            }
        ]
    }
}))

I created then two components:

export default function HomeScreen() {
    return (
        <View style={styles.container}>
            <Button
                text="Test 1"
                variant="solid"
                size="large"
                color="cyan"
                onPress={() => {}}
            />
            <Button
                text="Test 2"
                variant="solid"
                size="large"
                color="red"
                onPress={() => {}}
            />
        </View>
    )
}

Button1:

  • variant solid
  • size large
  • color cyan

so, i should get:

Button:

{
    // base
    width: '100%',
    justifyContent: 'center',
    alignItems: 'center',
    //variants
    paddingVertical: 24,
    height: 78,
    backgroundColor: 'cyan',
    // compound
    borderWidth: 4,
    borderColor: 'black'
}

ButtonText:

{
  //base
  lineHeight: 20, // <- overriden by compound
  //variants
 fontSize: 22,
 color: 'white',
 // compound
 lineHeight: 18
}

console.log output:

Image

Image

and the other button:

Button2:

  • variant solid
  • size large
  • color red

Image

Image

@jordmccord
Copy link
Author

My apologies. Since migrating from a dynamic function to compound variants, I was previously testing against a truthy value and not setting a default value for the props e.g disabled = false so when migrating to compound variants, the variant wasn't being applied 🙈. The stories that were working as expected had the arguments set. Sorry for wasting your time.

@jpudysz
Copy link
Owner

jpudysz commented Feb 14, 2025

No worries! Thanks for the confirmation that it works as intended 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants