Skip to content
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

Open
jtag05 opened this issue Nov 22, 2016 · 47 comments
Open

[react-native] React Native Support #368

jtag05 opened this issue Nov 22, 2016 · 47 comments
Labels
complexity:high Best brains need to talk about it. important The thing you do when you wake up!

Comments

@jtag05
Copy link

jtag05 commented Nov 22, 2016

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.

@kof
Copy link
Member

kof commented Nov 22, 2016

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.

@fmsouza
Copy link

fmsouza commented Jan 15, 2017

@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:
https://github.com/fmsouza/rn-seed-simple/blob/master/src/common/searchbar.js

@kof
Copy link
Member

kof commented Jan 16, 2017

@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.

@fmsouza
Copy link

fmsouza commented Jan 17, 2017

@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 hover and active to deal with in RN. For RN the output will be mostly a raw js object for each element.

@kof
Copy link
Member

kof commented Jan 17, 2017

Yeah, cross-platform styles will need to use only subset of css supported by rn.

@kof
Copy link
Member

kof commented Jan 17, 2017

I think its a matter of just structuring the code, one can put it in separate dirs or use suffixes.

@kof
Copy link
Member

kof commented Jan 17, 2017

I guess we are not using exact same presentational components for rn and web, right?

@dagatsoin
Copy link

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.

@DenisIzmaylov
Copy link
Contributor

DenisIzmaylov commented Feb 18, 2017

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 fromCSS function by using Template Strings. According to #220.

@kof
Copy link
Member

kof commented May 14, 2017

Media queries for react-native https://github.com/tuckerconnelly/uranium

@grigored
Copy link

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

//platform.js
export function createStyles(styles, component) {
    return injectSheet(styles, component);
}
//platform.native.js

export function createStyles(styles){
    return WrappedComponent => class extends React.Component {
        render() {

            return (
                <WrappedComponent
                    classes={StyleSheet.create(styles)}
                    {...this.props}
                />
            );
        }
    }
}
//commonComponent.js
import createStyles from "./platform.js"
const styles = {button: {backgroundColor: 'blue'}}

@createStyles(styles)
export class SearchListView extends React.Component {
	render() {
            const {classes} = this.props;
            return <View style={classes.button}/>;
        }
}

@kof
Copy link
Member

kof commented May 31, 2017

Sounds good, what about structure? How do you organize react-native, web and shared styles? Please write a blog post about this stuff!

@iamstarkov
Copy link
Member

iamstarkov commented Jun 5, 2017

@kof you have:

  • button/index.js for web
  • button/index.ios.js for ios
  • button/index.android.js for android

@grigored
Copy link

grigored commented Jun 5, 2017

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.

@iamstarkov
Copy link
Member

there is also interesting react-primitives project

@kof kof added the complexity:high Best brains need to talk about it. label Aug 20, 2017
@canercandan
Copy link

@grigored also interested by this stuff feel free to share more examples. thanks.

@grigored
Copy link

@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.
The key points:

  1. have most of the material-ui components available on native, with a native Android/IOS look and feel. And have other native components available for web.
  2. be able to write your own styles like this:
const styles = {
  container: {
    ios: {
      padding: 5,
    },
    web: {
      margin: 5
    },
  }
}

or

 const styles = {
  container: {
    padding: {
      ios: 5,
      web: 10,
      sketch: 15
    },
  }
}
  1. be able to reuse navigation/ redux etc across platforms.

@canercandan
Copy link

@grigored look nice thanks for sharing it, I am definitely interested for seeing more about this API

@kof kof added important The thing you do when you wake up! and removed task labels Mar 19, 2018
@yordis
Copy link
Contributor

yordis commented Mar 27, 2018

Just a little feedback folks, coming from styled-components which I love it,

but I learned two things from there.

  1. I wouldn't like to see any string based driven styles, JS objects are fine specially creating tooling around, it is always easier to work with than manipulating strings.

  2. I wouldn't expect any unit added to anything from the package. styled-components assumes that px are the unitless unit for RN and creates more chaos than helping the project and one of the main reason for them is that they were Web developers forcing Mobile developer to their decisions. As a 6+ web developer and less than 1 year on RN, I can't agree on that at all. I used it and I added more chaos to the code without any reason. Each platform has it own unique constrains and it is better to embrace them and improve the quality of the development with the tools, but definitely do not force things on developers.

@dantman
Copy link

dantman commented Mar 27, 2018

How about the following ideas: (I'm thinking about this from the context of the JSS configuration Material UI uses)

  • On RN create style objects with StyleSheet.create using the style object instead of css classes. Though allow for a factory to be passed in to use instead of StyleSheet.create (in case a wrapper exists)
  • For now, keep a permanent registry of styles that have been registered and use shallowEqual to re-use style objects. StyleSheet.create currently permanently registers object and never releases them, so if JSS is used dynamically like primaryButton: { color: theme.palette.primary } and when the theme changes (primary color blue, then green, then back to blue) we create styles for {color: 'blue'}, then {color: 'green'}, then {color: 'blue'} the first two objects will still exist in memory. And if this is done continually (flipping between two colors for some reason) we will leak memory. So we should at least re-use styles when they haven't changed. (This issue could be solved if work on this and this is resumed)
  • (Or we could just skip this issue for now by just passing inline style objects to be used in style instead of registering stylesheets)
  • Pass the StyleSheet.create ids instead of classes. Though maybe we should pass styles instead of classes. Hard to say, there are pros and cons.
  • Ignore css selectors and media queries. By default just discard them on native (let them be used for doing things like creating hover styles on the desktop which are irrelevant in RN). But keep the metadata around, in case someone wants to write plugins that do things with them on native. For example someone might want to turn {foo: {color: 'red', '&:active': {color: 'blue'}}} into styles = {foo: {color: 'red'}, fooActive: {'color': 'blue'}} then write something like web:className={classes.foo} native:style={this.state.isPressed ? styles.fooActive : styles.foo}.
  • However as a special case if the css query matches /^\&+$/ then merge the styles from that into the main object.
    • i.e. '&' which is just explicitly the class on it's own and sometimes used like foo: {'&': {...mainStyles}, 'span': {...labelStyles}} to keep things on the same level instead of writing foo: {...mainStyles, 'span': {...labelStyles}} and '&&', '&&&', etc which are used to make selectors like .foo-1.foo-1 that have a higher specificity and override other styles.
    • In RN, there is no selector specificity, you just give an array of styles and the later styles override the styles earlier in the array. So by merging styles in native we can write styles with '&&' that override others on the web and on native just put them at the end of the array and use the same style object code (instead of having to explicitly copy them to the root for native and use '&&' on web for specificity).
  • Write an optional plugin that will warn you about coding mistakes that work on web but will break React Native. For example, when {width: '24px'} is written emit a warning that it should be written as {width: 24} instead so it'll work in both React DOM and React Native. This will help avoid having people write a bunch of code for the web and have it work fine, then switch over to the native version of their app and find it's breaking and they need to refactor a bunch of things like '24px' to 24 just to see that the actual code they wrote works fine in React Native.
    • We could also write an eslint plugin.
  • Optionally we could also write a plugin that would make it easier to write platform-specific styles:
    withStyles({
      foo: {
        backgroundColor: 'red',
        web: {
          // We use a h2 on the web, so reset a few things on web
          margin: 0,
          padding: 0,
          fontSize: 'inherit',
          color: 'inherit',
        },
        native: {
          aspectRatio: 16/9,
        },
        android: {
          elevation: 1,
        },
        ios: {
          ...shadowStylesInsteadOfElevation,
        },
      }
    })
    Or perhaps more web-like without overloading the selector pattern and forcing us to hard code a platform list (others exist like windows/uwp and hopefully people will create more platform implementation):
    withStyles({
      foo: {
        backgroundColor: 'red',
        '@media (platform: web)': {
          ...
        },
        '@media (platform: native)': {
          ...
        },
        '@media (platform: android)': {
          ...
        },
        '@media (platform: ios)': {
          ...
        },
      }
    })
    Or if we don't want to come up with special cased non-standard css and instead want to go the JS route using Symbols or special prefixes:
    withStyles({
      foo: {
        backgroundColor: 'red',
        [JSSPlatform('web')]: {
          ...
        },
        [JSSPlatform('native')]: {
          ...
        },
        [JSSPlatform('android')]: {
          ...
        },
        [JSSPlatform('ios')]: {
          ...
        },
      }
    })
    Where JSSPlatform is a function (which could be given a better name) that just accepts a platform name (or 'web' or 'native') and outputs a Symbol (or just prefixes the string with a special internal prefix).

@yordis
Copy link
Contributor

yordis commented Mar 27, 2018

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: {}
    })
  }
})

@dantman
Copy link

dantman commented Mar 28, 2018

@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 Platform module with one that exposes a browser/web version and accepts the native key to refer to all react-native platforms (it'll have to be up to react-native-web what it wants to consider itself, depending on how it handles jss like web styles). Heck, someone has been squatting on the react-platform package name all this time, we could easily take that package name over and provide a standard-ish react package for universal platform code splitting of React.

If we're going to go that route, we might as well also implement a babel transform that will see Platform.select and strip out certain keys. It can be set to a web preset that will strip out everything except web, a native preset that will strip out web, and any other string will be presumed to be a specific native platform (even if it's something like 'windows' which isn't part of the standard react-native) and will strip out any thing except native and a platform key matching the string given. Note that this may need extra though for the electron platform. Maybe the transform should just accept either an includes or an excludes array. (includes: ['web'], excludes: ['web'], includes: ['native', 'android'], includes: ['web', 'electron'])

@dantman
Copy link

dantman commented Mar 28, 2018

Write an optional plugin that will warn you about coding mistakes that work on web but will break React Native. For example, when {width: '24px'} is written emit a warning that it should be written as {width: 24} instead so it'll work in both React DOM and React Native. This will help avoid having people write a bunch of code for the web and have it work fine, then switch over to the native version of their app and find it's breaking and they need to refactor a bunch of things like '24px' to 24 just to see that the actual code they wrote works fine in React Native.
We could also write an eslint plugin.

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.

  • Automatically transform values like '24px' values to 24
  • Automatically transform shorthands like padding: '0 24px to their longer versions paddingLeft: 24, paddingRight: 24, paddingTop: 0, paddingBottom: 0. Likewise for most other basic css shorthands. Especially the flexbox ones.

This of course won't be perfect, we will still need to emit warnings for things like width: '50%' because RN doesn't support any type of size value except density-independent pixels.

@kof
Copy link
Member

kof commented Mar 28, 2018

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.

@dantman
Copy link

dantman commented Mar 28, 2018

@kof They are billed at about 90% as just a subset of css styles. The 10% being a custom aspectRatio, elevation for Android, maybe some quirks in the flexbox implementation though they've been fixing things, the fact you pass objects/styles/arrays of those to style instead of classes to className and a single object with bad practice inline styles to style, and the fact that specificity is based on order in the styles array instead CSS's rules on cascading.

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 react-native-web based player to display examples live in your browser.

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 style prop. And it seems to support selectors. But then you're designing your web code based on React Native's api (which is a problem if your library is web first but also wants to support native apps.

@kof
Copy link
Member

kof commented Mar 29, 2018

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…

@kof
Copy link
Member

kof commented Mar 29, 2018

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.

@kof
Copy link
Member

kof commented Mar 29, 2018

So I can see both cases useful:

  1. More separation:
// 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.

  1. Less separation
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.

@kof
Copy link
Member

kof commented Mar 29, 2018

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.

@dantman
Copy link

dantman commented Apr 1, 2018

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.

@kof
Copy link
Member

kof commented Apr 2, 2018 via email

@kof kof changed the title React Native Support [react-native] React Native Support Apr 2, 2018
@dantman
Copy link

dantman commented Apr 2, 2018

This is library code and no layout stuff.

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.

@kof
Copy link
Member

kof commented Apr 2, 2018

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"

@dantman
Copy link

dantman commented Apr 2, 2018

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 <custom-style> and this project is web only.

@kof
Copy link
Member

kof commented Apr 2, 2018

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:

  • less nesting
  • explicit about not being usable inside of some deeply nested structures, has to be top level explicitely

downside - quotes (mb a different separator can be used though).

@kof
Copy link
Member

kof commented Apr 2, 2018

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: className={classes[`${button}${platform}`]}

A helper function: const ps = (name, platform) => name + platform || currentPlatform could result in:

const styles = {
  button: {
    // common styles
    display: 'inline-block',
  },
 [pl('button', 'web')]: {
    extend: 'button', 
    fontSize: X
  }
}

className={classes[pl('button')]}

Update: looks worse than other suggestions.

@dantman
Copy link

dantman commented Apr 2, 2018

Hmmm... I was going to say switching styles is probably irrelevant because it's possible to do this without jss handling it by using Platform.switch and by taking advantage of fooStyles.web.js, fooStyles.android.js, fooStyles.native.js (proposal if we need it), fooStyles.common.js (import 'fooStyles.common').

However I just realized, while that is sort of true. The Platform.switch pattern falls apart when you don't want something to be overriden.

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 JssPlatform.switch and knew how to merge styles. Then we'd tell everyone to use an all key instead of using ....

@kof
Copy link
Member

kof commented Apr 2, 2018

However I just realized, while that is sort of true. The Platform.switch pattern falls apart when you don't want something to be overriden.

Not really, switch() could be doing a deep merge or it could be Platform.switch and Platform.merge

@kof
Copy link
Member

kof commented Apr 2, 2018

Btw. looking back at previous proposals, @media android looks semantically the best. What I dislike about @media in CSSinJS is that it requires the quotes and stuff inside needs expensive parsing. What if we introduce a new dsl for @media and leverage it to implement that switch thing?

@kof
Copy link
Member

kof commented Apr 2, 2018

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: @media {type} ($condition) { {rules} }

@dantman
Copy link

dantman commented Apr 2, 2018

Not really, switch() could be doing a deep merge or it could be Platform.switch and Platform.merge

The problem stems from the fact that the Platform I was proposing is not a Jss feature. It's a generic tool useful for everyone which is just a light polyfill/wrapper over what React Native already provides. And the use of ... to merge with the common styles. And merging isn't supposed to be part of Platform.switch's job. In fact, a proper Platform.switch would do the opposite, given {all: 'a', native: 'b', android: 'c'} a proper Platform.switch would return 'c' on Android, 'b' on iOS, and 'a' everywhere else. It would not try to merge anything.

That is why I mentioned a JssPlatform alternative at the end of my comment. We could still implement a react-platform to handle the general use case. But we could use that as a base to create a JssPlatform that knows how to merge things in the best way for Jss.

@yordis
Copy link
Contributor

yordis commented Apr 10, 2018

Please don't merge the unitless from the native platform with units from the web. I really wouldn't like to see any px to non-unit thing at all, leave each platform as it is.

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 unit vs non-unit then create a factory for your values that knows when to add unit or not.

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 modularScale.scale(number) you don't need to pay attention to the unit issues.

Please, don't go for that route, or at least, do not force me to write px for my RN code, each platform has it own advantage.

Just a note because some folks mention the px to nothing idea, this is CSS driven by Javascript anyway, let the people decide how to manage that (it is not that hard to deal with this at the end of the day, the example above is one solution).

@dantman
Copy link

dantman commented Apr 10, 2018

Please, don't go for that route, or at least, do not force me to write px for my RN code, each platform has it own advantage.

I don't think anyone has suggested that we force RN code to use explicit px units.

My first suggestion was a jss plugin and/or eslint plugin that will emit warnings when using unit values like 4px in common styles so while developing for the web you know you're accidentally writing code that won't work in the native version.

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 StyleSheet.create as well. So I switched to a "if it makes sense it should work" ideal, instead of forcing everyone to write styles one way for native compatibility JSS should just make whatever the user writes work on the platform if it's a trivial difference. In this case meaning, if it's a px value then in RN convert it to a unitless number so you can just use either one.

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.

@yordis
Copy link
Contributor

yordis commented Jun 3, 2018

@kof any updates on this?

@yagudaev
Copy link

yagudaev commented Jun 4, 2018

Would be interesting to see this working. It seems like styled-components support react-native https://www.styled-components.com/docs/basics#react-native

@kof kof removed the help wanted label Jul 5, 2018
@just-Bri
Copy link

just-Bri commented Sep 17, 2020

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?

@chrisarts
Copy link

chrisarts commented Apr 21, 2023

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
complexity:high Best brains need to talk about it. important The thing you do when you wake up!
Projects
None yet
Development

No branches or pull requests