vitalets/react-native-extended-stylesheet

Global styles 'Unresolved variable' error

Christopher2K opened this issue · 21 comments

Hi,

I'm trying to get all my style values in EStyleSheet.build({...}); but I'm experiencing some troubles with the error "Unresolved variable: $<VAR_NAME>".

Here's my code:

// style.js
const COLORS = {
    $ORANGE: '#D57C4C',
    $PURPLE: '#B36892',
    $WHITE: '#FFFFFF',
    $BLACK: '#000000',
    $GREY: '#C1C1C1',
    $LIGHT_GREY: '#EAEBED',
    $DEFAULT_IOS_BLUE: '#0e7afe',
};

const FONTS = {
    $FONT_XL: 20,
    $FONT_L: 17,
    $FONT_M: 14,
    $FONT_S: 12,
    $FONT_XS: 10,
};

const ICONS = {
    $ICON_XL: 30,
    $ICON_L: 25,
    $ICON_M: 20,
    $ICON_S: 15,
};

const VALUES = {
    $RAD: 4,
};

export default {
    ...COLORS,
    ...FONTS,
    ...ICONS,
    ...VALUES
};
// app.js, entry file

EStyleSheet.build({
    ...globalStyleVars
});

// my component code style
const styles = EStyleSheet.create({
    $padding: 10,

    container: {
        justifyContent: 'flex-start',
        alignItems: 'center',
        paddingLeft: '$padding',
        paddingRight: '$padding',

        borderStyle: 'solid',
        borderBottomColor: '$ORANGE',
        borderBottomWidth: 4,

    },

    inputContainer: {
        flex: 1,
        flexDirection: 'row',
        marginRight: 10
    },

    inputWrapper: {
        $padding: 5,
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'flex-start',
        alignItems: 'center',
        alignSelf: 'stretch',

        paddingLeft: '$padding',
        paddingRight: '$padding',

        backgroundColor: '$LIGHT_GREY',
        borderRadius: '$RAD',
        height: 25,
    },

    input: {
        flex: 1,
        paddingLeft: 8,
        fontSize: 14,
        padding: 0,
    },

    icon: {
        width: 15,
        height: 15
    },

    buttonContainer: {
        justifyContent: 'center',
        alignItems: 'center',
    },

    text: {
        color: '$DEFAULT_IOS_BLUE',
        alignSelf: 'stretch',
        paddingTop: 10,
        paddingBottom: 10
    },
});

And, the weird thing is that If I remove $RAD, it works with the others values ($ORANGE etc...)

Thank you for your help !

Hi @Christopher2K, sorry for delay.
Could you show exact error message, which variable is unresolved?

Hello, I am experiencing a similar problem. I am using Expo.
In my entry App.js I have the build call:

EStyleSheet.build({
  '$blue': '#0275d8',
  '$orange': '#FB7723',
});

Then in my component (it's a swiper):

const styles = EStyleSheet.create({
  dotStyle: {
    // ... other styles
    backgroundColor: '$blue'
  }
}

and that didn't work. And I tried this way too:

const $blue = EStyleSheet.value('$blue')

And I get the same error.

screen shot 2017-10-18 at 14 52 51

hi @faresite !
Could you add this line right before calling EStyleSheet.value('$blue'):

console.log('global vars', EStyleSheet.globalVars)

Let's see what is in global variables.

hi @vitalets , what I got was:

global vars null

Hi @faresite & @vitalets ,

Sorry I totally forgot about this issue. It was caused because I had the RN Debugger opened with Chrome with the device toolbar activated !
I fixed it by deactivating this toolbar.

@Christopher2K thanks for the info!
@faresite could you share the expo link so I can try to reproduce it?

I have the same issue too

@golestanirad could you show a sample code?

@vitalets

EStyleSheet.build({   
    $currencyFontColor: 'hsl(45, 100%, 94%)',
});

...

const styles = EStyleSheet.create({
    
   underlayColor: Color(EStyleSheet.value('$currencyFontColor')).darken(0.5),
});

I get
globalVars null
too

@golestanirad
I think it's because EStyleSheet.build() actually occurs after you try to get value of variable.
Have a look on this:

// app.js
EStyleSheet.build({   
    $currencyFontColor: 'hsl(45, 100%, 94%)',
});

const styles = EStyleSheet.create({
   underlayColor: Color(EStyleSheet.value('$currencyFontColor')).darken(0.5),
});

It works. But if we change the order:

const styles = EStyleSheet.create({
   underlayColor: Color(EStyleSheet.value('$currencyFontColor')).darken(0.5),
});

EStyleSheet.build({   
    $currencyFontColor: 'hsl(45, 100%, 94%)',
});

It throws Unresolved variable: ....

The solution is to wrap property with EStyleSheet.value into function. EStyleSheet guarantees that such function will be called after the styles build:

const styles = EStyleSheet.create({
   underlayColor: () => Color(EStyleSheet.value('$currencyFontColor')).darken(0.5),
});

EStyleSheet.build({   
    $currencyFontColor: 'hsl(45, 100%, 94%)',
});

Hi @vitalets thanks for your help
I used that fat-arrow thing and now it throws this new error:
"model" is not a valid style property

@golestanirad could you show more code? Because "model" does not apear in lib sources, it maybe error in other place of your code.

@vitalets

const RootNavigator = StackNavigator(
    {
        Home: {
            screen: Home,
            navigationOptions: {
                header: null,
            }
        },
        Themes: {
            screen: Themes,
            navigationOptions:{
                headerTitle: 'Themes',
            },
        }
    },
    {
        initialRouteName: 'Options',
        navigationOptions: {
            headerStyle: {
                borderColor: 'red',
                borderWidth: 3, 
                backgroundColor: 'gray',                
            },
            headerTitleStyle: {
                alignSelf: 'center',
                borderWidth: 2,
                borderColor: 'yellow',  
                color: () => EStyleSheet.value('$headerTitleColor'),
            },          
        },
    }
);

it doesn't work and gives me the waring:

Failed prop typeL Invalide prop 'color' supplied to 'Text': function color(){
return_reactNativeExtendedSheet2.default.value('$headerTitleColor')

@golestanirad
It seems that EStyleSheet.create() is not applied to headerTitleStyle: { ... }.
If StackNavigator does not call EStyleSheet.create() inside, you should add it explicitly:

headerTitleStyle: EStyleSheet.create({   // <-- note this
    alignSelf: 'center',
    borderWidth: 2,
    borderColor: 'yellow',  
    color: () => EStyleSheet.value('$headerTitleColor'),
}),     

Closed as outdated. Feel free to reopen if you need.

I also want to point this out, for futures devs with the same issue.

https://github.com/vitalets/react-native-extended-stylesheet#value

Please note that in most cases EStyleSheet.value() should be used inside function, not directly:

const styles = EStyleSheet.create({
    button1: {
        width: () => EStyleSheet.value('$contentWidth') + 10 // <-- Correct!
    },
    button2: {
        width: EStyleSheet.value('$contentWidth') + 10 // <-- Incorrect. Because EStyleSheet.build() may occur later and $contentWidth will be undefined at this moment.
    }
});

@BlaShadow thank you!

@BlaShadow hi, I am using .value for in-line styling, although I haven't had any issues so far, but that point got me a bit worried
in render

<ActivityIndicator size="small" color={EStyleSheet.value('$primary')} />

is the above wrong to do! and if so, what's the alternative in this case?

@ys-sherzad

<ActivityIndicator size="small" color={() => EStyleSheet.value('$primary')} />

Please note that there are certain characters that you shouldn't use in your global variable names such as ., -, etc. I made the mistake of defining my global variables in this way, using . / - which caused the error:

EStyleSheet.build({
	'$text-md': 16,
});

After going through the code, I realized that these characters are related to mathematical operations and hence causing an error. Replaced with an _ and works fine.

EStyleSheet.build({
	'$text_md': 16,
});

I think its important mentioning this in the README