jaredh159 / tailwind-react-native-classnames

simple, expressive API for tailwindcss + react-native
2.01k stars 82 forks source link

V2: TouchableHighlight activeOpacity prop somehow seems to create a twrn style object that bleeds into the next use #68

Closed wayne-thorley closed 2 years ago

wayne-thorley commented 2 years ago

I'm having a weird issue whereby the activeOpacity prop of <TouchableHighlight> seems to create a new twrn style object that then merges with the next use of the twrn style function.

For example, using:

<TouchableHighlight activeOpacity={ 0.9 } underlayColor={ color( 'steel-50' ) } onPress={ () => navigation.navigate( item.screen ) }>
    <Text style={ tailwind( 'text-lg' ) }>{ item.title }</Text>
</TouchableHighlight>

My <Text> component receives the following as a style prop:

[{"fontSize": 18, "lineHeight": 28}, {"opacity": 0.9}]

As you can see it's been transformed into an array and a new style object appended to it. That opacity value always reflects whatever is set as the activeOpacity value.

Stranger still, is that it only seems to happen when the TouchableHighlight is pressed.

Any ideas? I'm using version 2.0.0-rc.4

Files below for reference.

My Settings component:

import React from 'react';
import { View, FlatList, TouchableHighlight } from 'react-native';
import { Button, Text } from '../../components';
import tailwind, { color } from '../../lib/tailwind';

const screens = [
    {
        title: 'Account',
        screen: 'Account Settings'
    },
    {
        title: 'Subscriptions',
        screen: 'Subscriptions Settings'
    },
    {
        title: 'Billing',
        screen: 'Billing Settings'
    },
    {
        title: 'Payments',
        screen: 'Payments Settings'
    }
];

function Settings({ navigation }) {

    const renderItem = ({ item }) => (
        <TouchableHighlight activeOpacity={ 0.9 } underlayColor={ color( 'steel-50' ) } onPress={ () => navigation.navigate( item.screen ) } style={ tailwind( 'p-4', 'border-b', 'border-steel-50' ) }>
            <Text style={ tailwind( 'text-lg' ) }>{ item.title }</Text>
        </TouchableHighlight>
    );

    return (
        <React.Fragment>
            <View style={ tailwind( 'flex', 'flex-grow', 'bg-white' ) }>
                <FlatList data={ screens } renderItem={ renderItem } keyExtractor={ item => item.screen }/>
            </View>
        </React.Fragment>
    );
}

export default Settings;

My Text component:

import React from 'react';
import PropTypes from 'prop-types';
import { Text as RNText } from 'react-native';
import tailwind from '../lib/tailwind';

function Text({ style, children, ...rest }) {

    // console.log( style );
    // [{"fontSize": 18, "lineHeight": 28}, {"opacity": 0.9}]

    const defaultStyle = tailwind( 'font-regular', 'text-base', 'text-steel-900' );

    return (
        <RNText style={ { ...defaultStyle, ...style } } { ...rest }>{ children }</RNText>
    )
}

Text.propTypes = {
    children: PropTypes.any,
    style: PropTypes.object
}

Text.defaultProps = {
    children: '',
    style: {}
}

export default Text;

My lib/tailwind.js file:

import { create } from 'twrnc';

const tw = create( require( '../../tailwind.config.js' ) );
const { style: tailwind, color } = tw;

export default tailwind;
export { color };
jaredh159 commented 2 years ago

I think this might be fixed already. Can you update to 2.0.1 and let me know if it is still broken?

Sent from my iPhone

On Oct 20, 2021, at 9:37 AM, Wayne Thorley @.***> wrote:

 I'm having a weird issue whereby the activeOpacity prop of seems to create a new twrn style object that then merges with the next use of the twrn style function.

For example, using:

<TouchableHighlight activeOpacity={ 0.9 } underlayColor={ color( 'steel-50' ) } onPress={ () => navigation.navigate( item.screen ) }> <Text style={ tailwind( 'text-lg' ) }>{ item.title } My component receives the following as a style prop:

[{"fontSize": 18, "lineHeight": 28}, {"opacity": 0.9}]

As you can see it's been transformed into an array and a new style object appended to it. That opacity value always reflects whatever is set as the activeOpacity value.

Stranger still, is that it only seems to happen when the TouchableHighlight is pressed.

Any ideas? I'm using version 2.0.0-rc.4

Files below for reference.

My Settings component:

import React from 'react'; import { View, FlatList, TouchableHighlight } from 'react-native'; import { Button, Text } from '../../components'; import tailwind, { color } from '../../lib/tailwind';

const screens = [ { title: 'Account', screen: 'Account Settings' }, { title: 'Subscriptions', screen: 'Subscriptions Settings' }, { title: 'Billing', screen: 'Billing Settings' }, { title: 'Payments', screen: 'Payments Settings' } ];

function Settings({ navigation }) {

const renderItem = ({ item }) => (
    <TouchableHighlight activeOpacity={ 0.9 } underlayColor={ color( 'steel-50' ) } onPress={ () => navigation.navigate( item.screen ) } style={ tailwind( 'p-4', 'border-b', 'border-steel-50' ) }>
        <Text style={ tailwind( 'text-lg' ) }>{ item.title }</Text>
    </TouchableHighlight>
);

return (
    <React.Fragment>
        <View style={ tailwind( 'flex', 'flex-grow', 'bg-white' ) }>
            <FlatList data={ screens } renderItem={ renderItem } keyExtractor={ item => item.screen }/>
        </View>
    </React.Fragment>
);

}

export default Settings; My Text component:

import React from 'react'; import PropTypes from 'prop-types'; import { Text as RNText } from 'react-native'; import tailwind from '../lib/tailwind';

function Text({ style, children, ...rest }) {

// console.log( style );
// [{"fontSize": 18, "lineHeight": 28}, {"opacity": 0.9}]

const defaultStyle = tailwind( 'font-regular', 'text-base', 'text-steel-900' );

return (
  <RNText style={ { ...defaultStyle, ...style } } { ...rest }>{ children }</RNText>

) }

Text.propTypes = { children: PropTypes.any, style: PropTypes.object }

Text.defaultProps = { children: '', style: {} }

export default Text; My lib/tailwind.js file:

import { create } from 'twrnc';

const tw = create( require( '../../tailwind.config.js' ) ); const { style: tailwind, color } = tw;

export default tailwind; export { color }; — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

wayne-thorley commented 2 years ago

Yeah it's still happening in v2.0.1. Wrapping the <Text> component in a <React.Fragment> seems to work as a temporary workaround.

jaredh159 commented 2 years ago

Ok, when i looked from my phone earlier it seemed like a caching bug I had already fixed, but on reviewing your code closely, I don't think that's the case.

Could you try to temporarily remove twrnc from the equation by just using raw style objects manually, and see if the problem persists? If so, then it's not related to this library. But if that solves it, I'll dig in and try to reproduce when I get a chance.

wayne-thorley commented 2 years ago

Huh. You're spot on. I'm away from my machine, but it's right there in the source - it's the <TouchableHighlight> component that actually passes the style prop through to it's child. Nothing at all to do with this library.

Never really noticed that before. Thanks for the swift response. Much appreciated 👍