vitalets / react-native-extended-stylesheet Goto Github PK
View Code? Open in Web Editor NEWExtended StyleSheets for React Native
License: MIT License
Extended StyleSheets for React Native
License: MIT License
Brilliant extension, thanks.
It'd be nice to be able to magically do:
// But really get EStyleSheet
import {StyleSheet} from "react-native";
I'm currently settling on this (until I figure out a nice way to do the above):
import StyleSheet from "react-native-extended-stylesheet";
The problem is EStyleSheet is not a drop-in replacement for the core StyleSheet.
It'd be neat if flatten
, harilineWidth
, etc. were exposed on EStyleSheet.
My case
EStyleSheet.value('2.3rem')
returns value for default rem value but I had set other build option
EStyleSheet.build({rem: 20});
Hi
Is it possible to use medai queries while setting global variables?
I want to set different values depending on IOS/android while EStyleSheet.build but it doesn't work
PS I know that I can do it with native Platform, but probably I'll use other media queries
and thanks for great extension
It is possible to have global styles, like we have in CSS?
So the library works great on iOS, but when I try to run the same library on Android, I receive the following error on startup.
It's on this line: const res = Object.keys(obj).reduce((res, key) => {
I've read up on the other issues and it looks like Android is not setting these properties correctly. Can you please advise?
My code:
How about to add Composition?
something like that:
const styles = EStyleSheet.create({
icon: {
color: '$dark',
fontSize: '1.4rem',
},
icon__succes: {
composes: 'icon',
fontSize: '1rem',
},
});
I have posted this on Stack Overflow too. Kindly take a look
EStyleSheet.build(DarkTheme)
in the index.js
. How to change to Light Theme? Calling build
again does not seem to work.<View>
<Button theme='dark'>Dark Button</Button>
<Button theme='light'>Light Button</Button>
<View>
Thanks for this repo! Help me a lot.
I just read a post which introduce a interesting idea(chinese post), I do not know it is worth to embedded here or not, I just post the code here.
Because iOS and android display different in same style. So they wrap things like this:
import { StyleSheet as RNStyleSheet, Platform } from 'react-native'
class StyleSheet {
static create(styles: Object): {[name: string]: number} {
const platformStyles = {}
Object.keys(styles).forEach((name) => {
const { ios, android, ...style } = { ...styles[name] }
let outputStyle = style
if (ios && Platform.OS === 'ios') outputStyle = { ...style, ...ios }
if (android && Platform.OS === 'android') outputStyle = { ...style, ...android }
platformStyles[name] = outputStyle
})
return RNStyleSheet.create(platformStyles)
}
}
export default StyleSheet
Then we can use style like this:
export default StyleSheet.create({
container: {
flex: 1,
paddingLeft: 20,
paddingRight: 20,
ios: {
paddingTop: 15,
paddingBottom: 15,
},
android: {
paddingTop: 10,
paddingBottom: 10,
},
backgroundColor: 'white',
},
)}
Interesting?
Hey,
Cool module! I had similar idea a while ago and created that gist to demo how my internal implementation works -> https://gist.github.com/grabbou/72767db51f97fe86cfea
I don't think there's a need for yet another stylesheet package, so I was thinking we could add that in here.
Happy to merge that in, let me know what you think.
Hi
Is it possible to get style value directly to pass it to props?
for example I want to count it from rem or use global variable
for example
<SomeComponent height={EStyleSheet.get('$globalHeight - 10rem')} />
or something like this
Hi, thanks for this great library for styling,
I've used the old version of EStyleSheet, and it works :)
but now i'm in a new project with RN 0.41 and the EStyleSheet 0.3.2,
i got plenty warning that invalid property type of style, it
here's where i declare the build in my app.js:
'use` strict';
import React,{ Component } from 'react';
import { StyleSheet, Dimensions, Image, Alert, BackAndroid } from 'react-native';
import { Container, Content, Text, View } from 'native-base';
import EStyleSheet from 'react-native-extended-stylesheet';
import AppNavigator from './AppNavigator';
let {height, width} = Dimensions.get('window');
let styles = StyleSheet.create({
container: {
flex: 1,
width: null,
height: null,
},
box: {
padding: 10,
backgroundColor: 'transparent',
flex: 1,
height: height-70
},
space: {
marginTop: 10,
marginBottom: 10,
justifyContent: 'center'
},
modal: {
justifyContent: 'center',
alignItems: 'center'
},
modal1: {
height: 300
},
modal2: {
height: height-78,
position: 'relative',
justifyContent: 'center',
},
});
class App extends Component {
constructor(props) {
super(props);
}
render() {
//some render
}
}
EStyleSheet.build({
rem: width > 500 ? 2 : 1,
$scale: width > 500 ? 1 : 1
});
export default App
and my class
import React, { Component } from 'react';
import { Image, Platform, StyleSheet } from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { Container, Content, Text, Item, Input, Button, Icon, View, Form, Header } from 'native-base';
import styles from './styles';
const backgroundImage = require('../../../../images/login.png');
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
scroll: false,
};
}
render() {
return (
<Container>
<Content scrollEnabled={true} bounces={false}>
<Image source={backgroundImage} style={styles.container}>
<View style={styles.bg}>
<Button style={styles.buttonLoginFacebook} onPress={() => Actions.main()}>
<Text style={styles.buttonTextLogin}>
Login with facebook
</Text>
</Button>
<Button style={styles.buttonRegisterFacebook} onPress={() => Actions.signUp()}>
<Text style={styles.buttonTextLogin}>
Register with facebook
</Text>
</Button>
</View>
</Image>
</Content>
</Container>
);
}
}
export default connect()(Login);`
and finally, my style.js:
'use strict';
const React = require('react-native');
import EStyleSheet from 'react-native-extended-stylesheet';
const { StyleSheet, Dimensions, Platform } = React;
const deviceHeight = Dimensions.get('window').height;
module.exports = EStyleSheet.create({
$outline: 1,
container: {
flex: 1,
width: null,
height: '100%',
resizeMode: 'cover',
alignItems: 'center',
},
buttonTextLogin: {
color: '#000',
width: '90%',
textAlign: 'center'
},
buttonRegisterFacebook: {
backgroundColor: '#cf4965',
width: '90%'
},
shadow: {
flex: 1,
marginTop: (deviceHeight < 600) ? -40 : -10,
width: null,
height: null,
backgroundColor: 'transparent',
},
bg: {
backgroundColor: 'rgba(255,0,0,0)',
},
buttonLoginFacebook: {
backgroundColor: '#454190',
width: '90%'
},
});
But the style doesn't make any effect on my layout, and i keep getting lots of warning,
Warning: Failed prop type: Invalid prop 'style' of type 'number' supplied to 'Styled(Text)', expected 'object' Warning: Failed prop type: Invalid prop 'style' of type 'number' supplied to 'Styled(Button)', expected 'object' Warning: Failed prop type: Invalid prop 'style' of type 'number' supplied to 'Styled(Content)', expected 'object' Warning: Failed prop type: Invalid prop 'style' of type 'number' supplied to 'Styled(Button)', expected 'object'
Fyi, i did make sure the path is correct, so it's not import problem.
and my package.json
{
"name": "xxx",
"version": "6.0.0",
"private": true,
"scripts": {
"postinstall": "remotedev-debugger",
"start": "node_modules/react-native/packager/packager.sh",
"eslint": "eslint"
},
"dependencies": {
"@remobile/react-native-cordova": "^1.1.1",
"@remobile/react-native-file-transfer": "^1.0.7",
"bugsnag-react-native": "^2.2.0",
"color": "^0.11.3",
"lodash": "^4.13.1",
"moment": "^2.13.0",
"native-base": "2.1.0-rc.2",
"react": "15.4.2",
"react-native": "0.41.0",
"react-native-button": "^1.6.0",
"react-native-code-push": "^1.17.0-beta",
"react-native-extended-stylesheet": "^0.3.2",
"react-native-fcm": "^6.2.0",
"react-native-gifted-messenger": "^0.1.4",
"react-native-gifted-spinner": "0.0.5",
"react-native-image-picker": "^0.26.2",
"react-native-loading-spinner-overlay": "^0.4.2",
"react-native-modalbox": "^1.3.7",
"react-native-navigation-redux-helpers": "^0.5.0",
"react-native-router-flux": "^3.38.0",
"react-native-scrollable-tab-view": "^0.7.2",
"react-native-storage": "^0.1.5",
"react-redux": "^4.4.5",
"redux": "^3.5.2",
"redux-persist": "^3.2.2",
"redux-thunk": "^2.1.0",
"remote-redux-devtools": "^0.3.3",
"remote-redux-devtools-on-debugger": "^0.4.6"
},
"devDependencies": {
"chai": "^3.5.0",
"babel-eslint": "^6.1.2",
"eslint": "^3.5.0",
"eslint-config-airbnb": "^11.1.0",
"eslint-plugin-import": "^1.14.0",
"eslint-plugin-jsx-a11y": "^2.2.1",
"eslint-plugin-react": "^6.2.0",
"eslint-plugin-react-native": "^2.0.0",
"mocha": "^2.5.3",
"babel-jest": "19.0.0",
"jest": "19.0.2"
},
"jest": {
"preset": "react-native"
}
}
*updated:
render() {
console.log(StyleSheet.flatten(styles));
return (
<Container>
<Content scrollEnabled={true} bounces={false}>
<Image source={backgroundImage} style={StyleSheet.flatten(styles.container)}>
<View style={StyleSheet.flatten(styles.bg)}>
<Button style={StyleSheet.flatten(styles.buttonLoginFacebook)} onPress={() => Actions.main()}>
<Text style={StyleSheet.flatten(styles.buttonTextLogin)}>
Login with facebook
</Text>
</Button>
<Button style={StyleSheet.flatten(styles.buttonRegisterFacebook)} onPress={() => Actions.signUp()}>
<Text style={StyleSheet.flatten(styles.buttonTextLogin)}>
Register with facebook
</Text>
</Button>
</View>
</Image>
</Content>
</Container>
);
}
if i use the flatten method in react-native Stylesheet, it worked, it rendered the outline correctly (for $outline: 1), everything works, but it's kinda absurd to write Stylesheet.flatten() everytime, right?
Would it be possible to deliver a TypeScript type definitions file, for those people how use react-native with typescript
Is it feasible to use css psudo class or psudo elements selectors like after, before, etc in react native? Or any other way around out there?
Or could we do something to make it feasible in this amazing package?
Hi, thanks for this package.
I just that my app crashes whenever i declare a percentage value. Example code below.
import EStyleSheet from "react-native-extended-stylesheet";
const styles = EStyleSheet.create({
root: {
flex: 1
},
meetupCard: {
height: 200,
width: 175,
marginLeft: '1.5%',
backgroundColor: "#f56d79"
}
});
export default styles;
When ever I comment out the percentage line, Everything works find.
Seems this only happens when I use it on any margin
value
Is this a bug? Thakns
EStyleSheet.build({
dashboard: {
$valueFontSize: 26 * fontScale,
}
});
Currently, this is not possible because the check is against the first letter (charAt(0)
).
Say I want to use:
EStyleSheet.create({
text: {
fontSize: '16 * dashboard.$valueFontSize',
}
});
Could we have this support?
After implementing media queries in #5 I'm thinking about supporting orientation change somehow.
As it will allow to get full power of media queries.
Technically I see these steps:
I quickly searched for that topic but did not found ready to use concept how it can be implemented in RN.
If you have some ideas or experience, please feel free to share it here and we will think how to add it.
Thanks!
Hello.
How can i set rem or scale make it display as expected on different screen.
IOS 4S
IOS 5
IOS 6
IOS 6S+
ANDROID etc
From: https://github.com/vitalets/react-native-extended-stylesheet#outline-for-debug
I just gave it a try but didn't manage to get it working. Any ideas?
import EStyleSheet from 'react-native-extended-stylesheet';
EStyleSheet.build({ $outline: 1 });
In my app/index.js
uncaught error Error: SyntaxError: Unexpected token ...
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Module._extensions..js (module.js:422:10)
at Object.require.extensions.(anonymous function) [as .js] (/Users/samliu/Projects/weather/node_modules/babel-register/lib/node.js:138:7)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at OptionManager.mergePresets (/Users/samliu/Projects/weather/node_modules/babel-core/lib/transformation/file/options/option-manager.js:324:28)
TransformError: /Users/samliu/Projects/weather/node_modules/react-native-extended-stylesheet/src/index.js: Unexpected token ...
See logs /var/folders/qh/1pg8d2s57k52gqxszrwf6f940000gn/T/react-packager.log
at SocketClient._handleMessage (SocketClient.js:139:23)
at BunserBuf.<anonymous> (SocketClient.js:53:42)
at emitOne (events.js:90:13)
at BunserBuf.emit (events.js:182:7)
at BunserBuf.process (/Users/samliu/Projects/weather/node_modules/bser/index.js:289:10)
at /Users/samliu/Projects/weather/node_modules/bser/index.js:244:12
at nextTickCallbackWith0Args (node.js:452:9)
at process._tickCallback (node.js:381:13)
Command /bin/sh failed with exit code 1
Unexpected token
Lets move the logic in order to speed up parsing
facebook/react-native@3f49e74
Not sure if i'm making a mistake but, :first-child pseudo class doesn't seem to be working for me, last-child, even, and odd all seem to work fine?
It still takes the 'left: 50' for first child
In my styles:
event_guest: {
position: "absolute",
height: 40,
borderColor: "white",
width: 40,
marginTop: 10,
left: 30,
borderRadius: 20,
borderWidth: 2,
borderColor: "#FFF"
},
'event_guest:nth-child-even': {
left:50,
},
'event_guest:first-child': {
left:10,
},
I have tried something like this but I got an error. I think this is needed. Thanks.
EStyleSheet.build (
container: {
flex: 1,
backgroundColor:'white'
}
)
const styles = EStyleSheet.create({
container: '$container'
})
How to use aspect-ratio media query. Need example. Thanks!
Variables declared with $<var-name>
are included in the computed styles _style
and are thus "applied" to elements. They don't seem to be removed correctly because warnings are being logged reminding that the variable is an invalid style prop key.
Is it possible?
I tried the following but it's not working.
if (module.hot) {
module.hot.accept(() => {
EStyleSheet.build();
});
}
Getting this error when running my project after adding this dependency. We're running babel (stage-2). Any idea why this is happening?
I have zero global variables for stylesheets, yet quite some changes depending on the device orientation and thus on media queries.
Therefore I am calling create()
on every rotation. How should I memoize()
stylesheets in such a situation not to recalculate same sheet many times or is it possible at all?
Hey vitalets!
Awesome library man. It would be super cool if this could compile on web too. Do you think that would be much effort? If not, I might look into trying to do that. I'm looking for something that works in native and progressively enhances if it can (eg. inside browser).
Cheers
1- Is it possible to use static theme and no app reload to theme change? for example when I want to change theme , Just call EStyleSheet.build
and forceUpdate
again
2- Is dynamic theme need cashing ? IS dynamic theme need stylesheet creation in every render() call?
Hi,
I tried to use this module without success, I always got an empty object as a result, even with the simple example on the readme.
I looked at the code and I was able to make it work by changing (in api.js) : if (this.builded)
to if (!this.builded)
since in my test this.builded
was always false and it looks like it needs to go through sheet.calc()
Maybe i'm missing something...
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 !
If you pass objects to a memoized function, it considers that the value is the same, due to use of Object.toString
(indirectly called, when it uses Array.join
) when creating the cache key.
Code to reproduce the error:
import EStyleSheet from 'react-native-extended-stylesheet';
const memoized = EStyleSheet.memoize((data) => console.log(data));
// These two work as expected:
memoized({id: 1}); // should log
memoized({id: 1}); // should not log
// This one won't
memoized({id: 2}); // should log
I have read the docs about underscored styles
but don't know what to use & why ❓
Currently, I'm using styles._text
styles everywhere bcz once styles.text
was not working.
So @vitalets if u can explain when to use underscored styles
❓
If livereload is on, I get error on every update Unhandled JS Exception: No need to call EStyleSheet.build() more than once
And thanks for your work!!!
In my view I have a main view with this I have no problems, but their children are calculated by percentages and I take the dimensions of the previous screen there any solution to this bug.
Is there currently any way to implement division with a variable? Take the following example which creates a label with rounded sides:
const styles = EStyleSheet.create({
label: {
$height: 30,
borderRadius: '$height / 2',
height: '$height',
}
});
This is throwing an error that says $height / 2
is an unresolved variable. The docs also suggest that division isn't implemented.
Is there a reason for that or is it just unimplemented? I could take a look into it if there's nothing blocking it.
I saw the commit at #633058c and thought complex operations would be a really handy feature actually. What do you think?
Currently only 1 operator is supported, so if I have to do the following I can't
{
height: '$deviceHeight/2-100'
}
Instead I have to do
{
$halfDeviceHeight: '$deviceHeight/2',
height: '$halfDeviceHeight-100'
}
So for many operators this becomes unnecessary & this happens for quite a few use cases that I've encountered in the past few weeks or so
Is there any way to create Common styles since I'm repeating a lot of code.
Currently, my approach is
<View style={[styles.commonStyle, styles.A]} />
<View style={[styles.commonStyle, styles.B]} />
But, I think the following approach would be much better
EStylesheet.create({
$commonStyles: {
margin: 10,
padding: 10,
},
A: {
...$commonStyles,
color: 'red',
},
B: {
...$commonStyles,
color: 'green',
},
})
So that in my component I will only do this -
<View style={styles.A} />
<View style={styles.B} />
Someway the Component would be much more readable. What do u think @vitalets ❔
I was led to this project because someone said you could do something to the effect of width='100%' height='auto'
.
I can't get it to work. Does this functionality exist?
On ios it's possible to change font scale in accessibility settings. Right now you can control if to allow the font scaling at all in the specific text component. anyway you can't set the max scale value for that text. Hopefully there's pixel ratio api which seems to allow query for current font scale.
That said, I think there should be an Api to set the max font size in the specific text field:
{
fontSize: '1rem',
maxFontSize: '2rem',
}
Which should be equivalent of
{
fontSize: `1rem * {Math.min(2, PixelRatio.getFontScale())}`,
}
Thanks.
Hi, i have define a lightTheme
how default, how could i get a value of the another theme?
something like:
import lightTheme from './lightTheme'
import darkTheme from './darkTheme'
EStyleSheet.build(lightTheme) // set light theme
const font = EStyleSheet.value('$font', darkTheme) // get value of dark theme
is there any way to do this?
thanks :-)
I have a styles.js file and themes/default.js theme.
in styles.js:
import { Platform } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import theme from './themes/default';
const styles = EStyleSheet.create({
PrimaryButton: {
backgroundColor: 'lightblue',
borderColor: 'lightblue',
borderRadius: 0,
},
Badge: {
borderRadius: 5,
backgroundColor: '#ffc900',
paddingHorizontal: 5,
paddingVertical: 2,
alignSelf: 'center'
},
LabelWithBadgeSpaceBetween: {
justifyContent: 'space-between',
flexDirection: 'row',
paddingVertical: 5,
paddingHorizontal: 10,
backgroundColor: '#eee'
},
AlertButton: {
backgroundColor: '$alertColor',
borderColor: '$alertColor',
borderRadius: 0,
marginTop: 4,
marginBottom: 0,
},
});
EStyleSheet.build(theme);
export default styles;
this returns an empty Object {}.
react-native: 0.42.3
Hi all.
I have used react-native-extended-stylesheet with rn 40 but when I create stylesheet it not working. Style object react-native-extended-stylesheet no Properties when i console it. Thank all.
I was wondering why round all calculated variables?
I blocked on this because I have a borderWidth
variable of 0.5
but it gets rounded to 1
and it's frustrating..
React Native already round the style for pixel snapping so it seems unneeded.
There is a known issue with Dimensions in Android that cause it to report wrong values. I guess it might be different on different devices, in my Galaxy S5 Mini running Android 5 it always gets stuck with the values app had on launch (e.g. if you start in Portrait, dimensions will be stating narrow screen width forever, even if you rotate the device). Naturally media queries relying on Dimensions do not work properly then. I think I've heard of some similar issues on iOS, but as for Android they are present for sure.
The proper way for fetching the screen size seems to use Android's native DisplayMetrics
, there is even an npm module doing it - https://www.npmjs.com/package/react-native-extra-dimensions-android (maybe react-native-extended-stylesheet
could depend on this one?).
Another option for tracking the real screen size (that I am using in my app at the moment) is to have one View
that takes the whole screen and watch for its onLayout
event - its parameters seem to deliver real view size quite reliably. That is useless for react-native-extended-stylesheet
at the moment, but possibly you could allow overriding the default dimensions with whatever clients wants e.g. via .build(forcedCurrentDimensions)
?
P.S.
Sorry if I am producing too many issues, @vitalets You made an awesome module that simplifies styling for the different devices a lot, so I am reporting what I discover when getting it into use.
EStyleSheet doesn't change view styles on Android apps. (It works for iOS apps).
Below is an example...
<Text style={styles.header}>Hello</Text>
const styles = EStyleSheet.create({ header: { color: 'red', } });
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.