vitalets / react-native-extended-stylesheet

Extended StyleSheets for React Native
MIT License
2.93k stars 132 forks source link

Global Objects #62

Closed deadcoder0904 closed 7 years ago

deadcoder0904 commented 7 years ago

So I am running into an use case where I have default themes.

Suppose I'm creating a H1 component with default styling & the app also has variety of themes of H1 component.

Now if I make a global variable $H1

EStyleSheet.build({
     $H1: {
        fontSize: 24,
        fontWeight: 'bold',
        color: 'black'
    }
})

Then if I want to use it in styling of H1 I have to do

{
   H1: {
     fontSize: '$H1.fontSize',
     fontWeight: '$H1.fontWeight',
     color: '$H1.color',
   }
}

So this approach is tedious because now when I put some default style in the global object, I've to add it to the local object as well.

So if I can use Global Objects (denoted by $$), it would be much easier to make Global Default Styles like

EStyleSheet.build({
   $$H1: {
        fontSize: 24,
        fontWeight: 'bold',
        color: 'black'
   }
})

Then if I want to use it in styling of H1 I will do

{
   H1: '$$H1'
}
vitalets commented 7 years ago

How about using EStyleSheet.value to put default style:

EStyleSheet.create({
   H1: EStyleSheet.value('$H1')
});

and to extend default style with custom property:

EStyleSheet.create({
   H1: Object.assign({fontSize: 25}, EStyleSheet.value('$H1'))
});
deadcoder0904 commented 7 years ago

Well, I don't realise there exists value()

My bad 😂 but let me check

deadcoder0904 commented 7 years ago

Hey also, another problem is I am using themes so I am exporting just plain JS objects. So how would I do this with themeing 🤔

vitalets commented 7 years ago

oh, I think I was a bit wrong. It should be:

EStyleSheet.create({
   H1: () => EStyleSheet.value('$H1')
});

and

EStyleSheet.create({
   H1: () => Object.assign({fontSize: 25}, EStyleSheet.value('$H1'))
});

But for me syntax looks complex. I believe styles should be clean and easy to read. It should be more declarative way to do this. I will think for a while.

deadcoder0904 commented 7 years ago

Sorry to make this SO but I thought this feature didn't existed.

What I am doing is like this -

I have 2 themes - light & dark

light.js

const lightTheme = {
     $H1: {
        fontSize: 24,
        fontWeight: 'bold',
        color: 'black',
        backgroundColor: 'white'
    }
};

dark.js

const darkTheme = {
     $H1: {
        fontSize: 24,
        fontWeight: 'bold',
        color: 'white',
        backgroundColor: 'black'
    }
};

Then I build my StyleSheet

App.js

EStyleSheet.build(lightTheme)

& then use styles in my application like

{
   H1: {
     fontSize: '$H1.fontSize',
     fontWeight: '$H1.fontWeight',
     color: '$H1.color',
   }
}
deadcoder0904 commented 7 years ago

Man that's what I thought but it wasn't working. Wait I'll check again.

deadcoder0904 commented 7 years ago

@vitalets I'm getting confused.

I didn't get this one, is $H1 created in EStyleSheet.build() already

EStyleSheet.create({
   H1: () => EStyleSheet.value('$H1')
});

The later part I got. This is used while styling a particular component.

EStyleSheet.create({
   H1: () => Object.assign({fontSize: 25}, EStyleSheet.value('$H1'))
});

My problem is I am using Themes & it gives error that Unresolved Variable $H1 bcz it is not created yet.

Can u give me an answer for my use-case ❔

Is it possible to use value with Themes ❓

Bcz Value cannot be used in Exported JS objects. as building takes place later on, before creating.

vitalets commented 7 years ago

Yes, $H1 is assumed to be global variable created by EStyleSheet.build():

EStyleSheet.build({
  $H1: {
    fontSize: 24,
    ...
  }
})

Then it can be used in sheet creation:

EStyleSheet.create({
   H1: () => EStyleSheet.value('$H1')
});

Is it possible to use value with Themes

Yes, it is possible.

Bcz Value cannot be used in Exported JS objects

Yes. EStyleSheet.value() is intended to be used inside value as a function, because build occurs later (as you correctly mentioned)

deadcoder0904 commented 7 years ago

This doesn't work. I did the following.

light.js

export const lightTheme = {
     $H1: {
        fontSize: 24,
        fontWeight: 'bold',
        color: 'black',
        backgroundColor: 'white'
    }
};

App.js

EStyleSheet.build(lightTheme)

Now in my styles

EStyleSheet.create({
   H1: () => EStyleSheet.value('$H1')
});
vitalets commented 7 years ago

Hmm.. I should re-check it.

vitalets commented 7 years ago

@deadcoder0904 I've re-checked - yes, currently style as a function is not supported. Only value as a function. That's why this does not work:

EStyleSheet.create({
   H1: () => EStyleSheet.value('$H1')
});

I've done this locally - it works normally on your code. I will add some tests and release within 1-2 days. Thanks for the ideas =)

deadcoder0904 commented 7 years ago

So it doesn't work, right ❔ Are u adding this feature ❓

vitalets commented 7 years ago

So it doesn't work, right ❔ Are u adding this feature ❓

Yes. It does not work now. I will release it soon.

vitalets commented 7 years ago

Released as 0.8.0. I will appreciate your feedback!

deadcoder0904 commented 6 years ago

Sorry @vitalets I didn't do it yet. I'll test it now 😄

deadcoder0904 commented 6 years ago

@vitalets Dude, you are absolutely amazing 👍 Thank you soooooo much ❤️

vitalets commented 6 years ago

You are welcome! 😉