-
-
Notifications
You must be signed in to change notification settings - Fork 400
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
[react-native] React Native Support #368
Comments
Not yet, also I need to learn react-native first, so can't predict when this may happen. If someone is experienced in react native and can tell what jss needs to addd to support it I am happy to support it of course. Will leave this issue as a reminder in case some one wants to help out. |
@kof In the case of ReactNative, the styling is already a JS object configuration written inside a js module. And the styling attributes are sort of camelcase CSS attributes, just like this tool. I'm attaching here a component I've created which behaves as a searchbar for ReactNative, you can take it as reference to understand how it works: |
@fmsouza thanks, yes, the question is what specifically does jss needs to do to have a full RN support. If its just about sharing style declarations, it should work already. |
@kof If this solution idea is to make these styles cross-platform between web and mobile, maybe it can be a little more tricky, as you don't have nested styles or events like |
Yeah, cross-platform styles will need to use only subset of css supported by rn. |
I think its a matter of just structuring the code, one can put it in separate dirs or use suffixes. |
I guess we are not using exact same presentational components for rn and web, right? |
Indeed, the fondamental element are different. For example DIV is VIEW in rn. Here is another CSS in JS project which is compatible with RN. Maybe worth to take a look but I agree that the main effort should be to lint all incompatible rules. |
Sample from Official Documentation: const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
})
class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
)
}
} We could use this wrapper: To get API like: import { fromCSS } from 'jss-react-native'
const styles = fromCSS`
bigblue {
color: blue,
font-weight: 'bold',
font-size: 30px
}
red {
color: 'red'
}
`
class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles['red']}>just red</Text>
<Text style={styles['bigblue']}>just bigblue</Text>
<Text style={[styles['bigblue'], styles['red']]}>bigblue, then red</Text>
<Text style={[styles['red'], styles['bigblue']]}>red, then bigblue</Text>
</View>
)
}
} The same approach we could apply for original JSS. I meant |
Media queries for react-native https://github.com/tuckerconnelly/uranium |
Not sure if it's the best approach, but we are using the following structure for sharing JSS on React Web and Stylesheets on React Native
|
Sounds good, what about structure? How do you organize react-native, web and shared styles? Please write a blog post about this stuff! |
@kof you have:
|
We have just began unifying the React and React Native components, will write a blog post/sample github repo once we are ready to deploy in production, as we still have to sort some issues. But basically we are using what @iamstarkov mentioned: we use file.js, file.native.js (if we need separate ios/android files, then file.ios.js and file.android.js also works). Webpack only looks at file.js when bundling our web app, and the react native packager is smart enough to pick the right file. |
there is also interesting react-primitives project |
@grigored also interested by this stuff feel free to share more examples. thanks. |
@canercandan tldr: have a look here https://github.com/grigored/cross-platform-react/tree/master/src/primitives/createStyles . long story: I'm in the very early stage of open sourcing a library to help with writing code once, rendering everywhere (web, native, sketch). Should have an alpha in a week or two. This is based on a project on which my team worked in the past two-three years.
or
|
@grigored look nice thanks for sharing it, I am definitely interested for seeing more about this API |
Just a little feedback folks, coming from but I learned two things from there.
|
How about the following ideas: (I'm thinking about this from the context of the JSS configuration Material UI uses)
|
I love this withStyles({
foo: {
backgroundColor: 'red',
[JSSPlatform('web')]: {
...
},
[JSSPlatform('native')]: {
...
},
[JSSPlatform('android')]: {
...
},
[JSSPlatform('ios')]: {
...
},
}
}) Yes it could be more noice but it is really clear what is going on. Also withStyles({
foo: {
backgroundColor: 'red',
...JSSPlatform({
// insert platform key here
web: {},
ios: {}
})
}
}) |
@yordis your last code block just made me remember this is actually 90% taken care of. withStyles({
foo: {
backgroundColor: 'red',
...Platform.select({
web: {},
ios: {}
})
}
}) We just need to wrap react-native's If we're going to go that route, we might as well also implement a babel transform that will see |
Maybe I'll change my suggestion on this. Like how JSS acts as an enhancement for browser CSS (camel cased named, automatic prefixing, nesting selectors and media queries, etc...) perhaps we should actually think of it also as an enhancer for React Native StyleSheets.
This of course won't be perfect, we will still need to emit warnings for things like |
I am also wondering if it makes sense to mix cross-platform styles in one rule. How much can mobile styles be similar to the web? Wouldn't it be easier to just maintain separate styles for e.g. by using separate files for web/mobile? Or/and extract common styles for all platforms and just import/merge them. Then you only need something that picks the right file, for e.g. during build step for just a function. |
@kof They are billed at about 90% as just a subset of css styles. The 10% being a custom i.e. If you write styles for RN's StyleSheet.create and then just dump them into JSS they will pretty much just work. In fact instead of using screenshots or emulators RN's own styling documentation now just uses a In fact there is already a react-primitives project that exposes View, Text, and StyleSheet that have the RN api but are used on the web.It does attempt to handle specificity by mocking the RN behaviour by controlling the order of the css classes from the effect of the |
90% between web and mobile? It might heavily depend on design. I can imagine some buttons being 90% the same, but layouts, margins and more complex components… |
Also depending on wether the same person is working on mobile and web, it might be better to have stronger separation if people are different or even teams are different. If you have one component, mobile developer needs to test on the web for each change. It might be handy though if really 90% of the code are the same and same people work on web and mobile. |
So I can see both cases useful:
// commonStyles.js
export default {
button: {
// common styles
}
}
// buttonStyles.web.js
import styles from './commonStyles'
export default merge({}, styles, {
button: {
// specific web styles
}
} Then picking the file based on a platform evtl using some build magic. Separate builds can allow to have separate bundles and not load mobile code on the web and vice-versa.
const styles = {
button: {
// common styles
display: 'inline-block',
web: {
fontSize: X
},
mobile: {
fontSize: Y
},
android: {
// something specific to android only
}
}
} For the later we would need a JSS plugin which takes the platform specific names and merges/removes them based on a platform. All platforms code would be loaded in that case. A babel plugin could optimize that though. |
Also for RN, it could be a different preset for e.g. "jss-react-native-preset" which will only use plugins which make sense there. |
As a sample, here are the
https://gistpreview.github.io/?0f6ee2998220b2965e2e0280bccd4852 As you can see the majority of the styles that define what the component looks like could be used with JSS in both the web and React Native. The web-only styles are generally things like :hover, animations, and a few css properties that are only necessary on the web because of the long legacy of things we don't really want anymore. |
This is library code and no layout stuff.
…On Sun, Apr 1, 2018, 16:13 Daniel Friesen ***@***.***> wrote:
As a sample, here are the src/List/ListItem.js styles from Material UI
annotated with how they relate to React Native:
- red lines are only relevant to the browser
- green lines should work the same in RN and browsers
- yellow lines are relevant to RN but need a tweak to work in RN (e.g border:
'1px ... -> borderWidth: 1, ...) which a react-jss plugin could do
automatically
- grey lines need to be moved to a separate class since you need to
apply them to a different element in RN, but the style otherwise works the
same and you can use the same 2 css classes in both web and React Native
(the yellow textDecoration line also needs this)
https://gistpreview.github.io/?0f6ee2998220b2965e2e0280bccd4852
As you can see the majority of the styles that define what the component
looks like could be used with JSS in both the web and React Native. The
web-only styles are generally things like :hover, animations, and a few css
properties that are only necessary on the web because of the long legacy of
things we don't really want anymore.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#368 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AADOWPEXX5sXRIVQ7B_zqGWXfSQa5nI9ks5tkOBvgaJpZM4K5toz>
.
|
That's what I have to work with. And if we can get libraries working in both RDom and RN this will still be legitimately useful. Then even if you have to do layout differently, for all the components you use you can just use the same library on RN and RDom. I'd be happy to look at any website layout examples you have. |
Yes, totally, just saying that the amount of same code is because it is lib code. As I said before, this will be different in application code, which leads me to: "We need both strategies" |
Ok, but I still would enjoy seeing an application code example that I can annotate to see how it behaves in web vs mobile. My latest projects have all been Material Design based and focused on components, so a lot of that large blob of application styles has just disappeared for me. And my current project is one that started in Polymer 2.x, went to Polymer+React, and only started using React+Material UI now. My major application styles are still in a |
Btw. more ideas for the syntax with built-in platform dependent code: const styles = {
button: {
// common styles
display: 'inline-block',
},
'button:web': {
fontSize: X
},
'button:mobile': {
fontSize: Y
},
'button:android': {
// something specific to android only
}
} Benefit here:
downside - quotes (mb a different separator can be used though). |
Another idea: const styles = {
button: {
// common styles
display: 'inline-block',
},
buttonWeb: {
extend: 'button',
fontSize: X
},
'buttonMobile': {
extend: 'button',
fontSize: Y
},
'buttonAndroid': {
extend: 'button',
// something specific to android only
}
} When using it, just do this: A helper function: const styles = {
button: {
// common styles
display: 'inline-block',
},
[pl('button', 'web')]: {
extend: 'button',
fontSize: X
}
}
Update: looks worse than other suggestions. |
Hmmm... I was going to say switching styles is probably irrelevant because it's possible to do this without However I just realized, while that is sort of true. The import Platform from 'a-react-native-like-platform-wrapper-we-create';
const styles = {
button: {
background: 'red',
'&:focus': {
// Assume we have a plugin that makes &:focus work in native
background: 'blue',
},
...Platform.switch({
web: {
// Uh oh... this will overwrite &:focus instead of merging
// the background and outline together. We will have a confusing
// error unless we use `...Platform.switch({` multiple times.
'&:focus': {
// Web needs a few resets for the default styles
outline: 'none'
}
},
})
}
} Though perhaps it could work if it was inside a |
Not really, switch() could be doing a deep merge or it could be Platform.switch and Platform.merge |
Here is an example: It can work for any browser media query as well as native const styles = {
button: {
background: 'red',
media: {
type: 'screen',
query: {
width: 360
},
background: 'yellow',
color: 'red'
}
}
} Similar to how @media query is currently supported, here is an example for top level media DSL: const styles = {
button: {
background: 'red'
},
media: {
type: ['android', 'ios']
query: {
width: 360
},
button: {
background: 'yellow',
color: 'red'
}
}
} It maps exactly to how @media is designed: |
The problem stems from the fact that the That is why I mentioned a JssPlatform alternative at the end of my comment. We could still implement a |
Please don't merge the unitless from the native platform with units from the web. I really wouldn't like to see any Don't commit the same mistake of others where every single RN and Native developer hate the decision driven by Web developers (included me after so many years on web, I dont want to see this happening on jss, specially that carry more issues than the one that solves). If you want to keep separate the For example, https://github.com/straw-hat-team/design/blob/e707bc3d6094aa2c36a5a94cb764638390ab99c0/src/modular-scale.ts#L21-L26 that package let you to configure if you have units or not so every time you do Please, don't go for that route, or at least, do not force me to write Just a note because some folks mention the |
I don't think anyone has suggested that we force RN code to use explicit My first suggestion was a jss plugin and/or eslint plugin that will emit warnings when using unit values like Then I changed my mind. Since JSS is partially an enhancement over CSS (nesting selectors and media queries, scoping, etc) it makes sense for it to be an enhancement over The goal is to make as much code as possible work on both web and native (otherwise there is no value in bringing native support to JSS), not to force once platform's conventions on the other. |
@kof any updates on this? |
Would be interesting to see this working. It seems like |
Sorry to necro such an old thread but I'm wondering if any progress has been made recently. We are currently developing our RN app and would love to be able to share styles between web and mobile. We are using a Typescript enum to store colors which we share, but sharing a font style etc would be amazing. What are the current blockers/limitations in terms of getting it working at a high or low level? |
@kof I have a css parser for react native if you are willing to we can discuss about add this feature to this lib, it will be awesome because the way this handles the css traverse is really good, but I dont have much knowledge about css on web, but I know how RN works and make it compatible with basic css. |
First of all, thank you for the incredible library. It really solves so many fundamental issues I had with embedding CSS in my react projects.
I recently began work on a bit of a test project using react-native to build a universal app and would really like to incorporate JSS. I see that react-native support is on the roadmap, so I was wondering if there has been any attempts at this thus far? If not, I may be so inclined to take a stab at it on a fork.
The text was updated successfully, but these errors were encountered: