Support React Native #593

Open
chadobado opened this Issue Apr 28, 2015 · 71 comments

Projects

None yet
@chadobado

Absolutely beautiful library.

Any plans to port it to React-Native in the future?

@bparadie

Just discovered this repo: https://github.com/lightningtgc/react-native-material-ui
Don't know whether it's any good, though.

@hai-cea hai-cea changed the title from React-native? to Create material-ui React-native Jun 19, 2015
@hai-cea
Member
hai-cea commented Jun 19, 2015

Thanks @chadobado - We've talked about it for sure and it would be a fun project to start. However, we've got our hands full with this project at the moment. I'll keep this issue open and update if we ever create a native library.

@quanglam2807

This is actually a great idea. I have tried to test porting material-ui to React-Native. We only need to stylesheets a little bit, change all div to View, change all h1, h2, etc to Text and it'll work great. The only problem I've found is that React Native doesn't fully support boxShadow so it's hard to implement Paper component at the moment. Also, it would be great if we can great a script to auto-port the code to React-Native as it's not very different.

@oliviertassinari
Member

change all div to View, change all h1, h2, etc to Text and it'll work great

Couldn't we use a babel-plugin-transformer to do it?

This is actually a great idea

Do you have a demo project?

@quanglam2807

@oliviertassinari

Couldn't we use a babel-plugin-transformer to do it?

I'm not sure as the stylesheet of React Native is quite different from CSS so it'll be quite complicated to make the transformer.

Do you have a demo project?

Not yet cause' I'm quite busy but I'll try to show you a small demo soon.
But here is what we need to do

Stylesheets

let styles = {
      root: {
        zIndex: 5,
        width: '100%',
        display: '-webkit-box; display: -webkit-flex; display: flex',
        minHeight: themeVariables.height,
        backgroundColor: themeVariables.color,
        paddingLeft: spacing.desktopGutter,
        paddingRight: spacing.desktopGutter,
      }
}

to

let styles = StyleSheet.create({
      root: {
        // zIndex: 5, (not supported)
        //width: '100%', (number only)
        //display: '-webkit-box; display: -webkit-flex; display: flex', (React Native always use Flex)
        minHeight: themeVariables.height,
        backgroundColor: themeVariables.color,
        paddingLeft: spacing.desktopGutter,
        paddingRight: spacing.desktopGutter,
      }
})

zIndex solution

JSX

<div {...other} style={this.prepareStyles(styles, style)}>
  <h1 style={styles.text}>Hello world</h1>
</div>

to

<View {...other} style={this.prepareStyles(styles, style)}>
  <Text style={styles.text}>Hello world</Text>
</View>

We also need to modify styles/transition.jsx (React Native use object instead of string), mixins/style-propable.jsx as we don't need to deal with multiple browsers, etc

@lenaten
lenaten commented Dec 4, 2015

I just publish a WIP forking to react-native in https://github.com/lenaten/material-ui-native.
Currently only Card and RaiseButton is working, but without style (WIP remember?)

@oliviertassinari
Member

@lenaten Interesting!
I also wanted to start working on a wrapper between this project and mrn (https://github.com/oliviertassinari/react-material).
It seems that your fork is only working with react-native, how would you make it work with the browser too?
I think that it's the most difficult point and should be addressed now, since you say that you have two working component. I can help if you want.
As said before, I also wanted to investigate https://github.com/binggg/mrn for our native implementation.

When it's answered, I think that we could merge your fork back here.

@lenaten
lenaten commented Dec 4, 2015

Material-UI is mature project against mrn project that misses a lot of material components. If my POC will work as excepted, merge it to cross platform file structure should be easy. I have no time to reinvent the wheel and start from scratch project.

Anyway, your help in thoughts and code is very welcome.

@quanglam2807

@oliviertassinari Me, too.

My idea to make material-ui works with both browser and native is to use filename structure, similar to the way react-active handles iOS and Android at the same time.

app-bar.native.jsx
app-bar.browser.jsx
common.jsx

or we can still use the same components for both browser and native and then write a wrapper to handle them. For example, react-native uses View, browser use div then do it like this:

div.browser.jsx

export class ... {
  render() {
    return </div>
  }
}

div.native.jsx

export class ... {
  render() {
    return </View>
  }
}

app-bar.jsx

import {div} from "div"

We can actually create a separated project for this wrapper.

@oliviertassinari
Member

@quanglam2807 I'm glad to hear it.

Regarding the code organisation, I like the idea of having separate file extensions.
I would take https://github.com/benoitvallon/react-native-nw-react-calculator/tree/master/src/common/components example as the way to do it.

Regarding the project organisation, I may have changed my mind.
I think that it's better to follow Google approach and work on a big single repository. Hence working on a fork sync with material-ui or here could be good way to do it.

To begin with our .native files, we could depend on

components.

@lenaten
lenaten commented Dec 4, 2015

@oliviertassinari I also love the idea of "file extension" model. The most important to me now, is working native components. If you want to help with code abstraction you welcome. I commits to remove the "native" suffix from the repo name :)

@alitaheri alitaheri added the Deployment label Dec 8, 2015
@mvayngrib

@lenaten is material-ui-native compatible with tcomb-form-native, or if not, how big a project would that be?

@lenaten
lenaten commented Dec 15, 2015

@mvayngrib I stopped to work on this project for a while..

@mvayngrib

@lenaten that's a shame, thanks for responding

@oliviertassinari
Member

Alright, I have started working in this #2611.
That's going to take some time!

@mvayngrib

@oliviertassinari awesome! very very excited

@dorthwein

so is the port endeavor still open? If so what was the settled on process to implementing components?

@oliviertassinari
Member

@dorthwein It's still open.

From my point of view, the process is the following:

  • Upgrade to the latest version of react-native and remove react-native-webpack-server. I have already done it on this project. #3829
  • Play with react-look and see how well we can use it for the muiTheme that is coming from the context. #3829
  • Wait on the folder reorganisation so we have somewhere to put the new components
  • Start working on the documentation app that we will use to showcase new component.
  • Start working on the native version of components.
@dorthwein

@oliviertassinari - I can contribute a little bit of time porting some of the components over once the way forward is set. Looking at your list the only unknown right now is the react-look stuff right?

@oliviertassinari
Member

@dorthwein we are happy to hear it.
I'm using react-look here #3829. The only issue I have is a minor one. React Native is displaying some warning regarding wrong usage of the StyleSheet API. I haven't looked a it in detail but I believe that it can be solved.

@PublicParadise

@oliviertassinari @dorthwein I am happy that this effort (that is, bringing material-ui to react-native) is not dead. I just wanted to point out that there is also another new material-ui to react-native project that hasn't been mentioned in this thread: https://github.com/react-native-material-design/react-native-material-design . That project seems to be based on https://github.com/binggg/mrn.

@dorthwein
dorthwein commented Apr 6, 2016 edited

@oliviertassinari I saw in another thread if supporting iOS made sense for this port - I think it absolutely does especially when you look at how Google Maps & other Google Material + iOS apps are out there. Where it makes sense and there is a strong pre existing iOS component (e.g. switches) it should use to the iOS switch on iOS. Implementing Android & iOS isn't much of a burden as well.

@dorthwein
dorthwein commented Apr 6, 2016 edited

@oliviertassinari The component.native.js, component.android.js, component.ios.js file structure also seems to make the most sense to me.

@dorthwein

@oliviertassinari I tried getting the docs up and running no luck. Few issues:

  • package.json: react-native does not like the package name material-ui - changing to materialUI resolved the issue
  • The current material-ui/react-native branch is having an issue with the react-native packager and not creating the mainjs.bundle file. I haven't been able to figure out what was going on here.
  • I can't seem to get a working react-native app going on top of the existing material-ui repo. If any one has had any luck on this front lets get a stable heres how to contribute/develop native components set.
@oliviertassinari
Member

@dorthwein Thanks for the feedback. The react-native branch is highly experimental. We need to solve this.
On the other hand, I haven't any issue on my side (#3829).
I should try to start from a fresh git clone.

@dorthwein

Yeah so the next stage of my current project is working on a mobile app using material design - I'd like to use this as all our web stuff is in this as well. If we can get a working environment going I'll start knocking it out along with our project.

@dorthwein

Was reading up on some stuff and noticed this tidbit from the FB React Native Page.

"The most fundamental component for building UI, View is a container that supports layout with flexbox, style, some touch handling, and accessibility controls, and is designed to be nested inside other views and to have 0 to many children of any type. View maps directly to the native view equivalent on whatever platform React is running on, whether that is a UIView,

, android.view, etc. This example creates a View that wraps two colored boxes and custom component in a row with padding."

Source: https://facebook.github.io/react-native/docs/view.html

In light of this I think our current approach maybe a bit off given that a huge portion of the generic work can be done by switching divs to Views. Headers and other related tags would also have to be mapped in a more universal way as well.

Thoughts?

@dorthwein

Also found this resource - trying it out now. Seems pretty straight forward and maybe worth a gander

https://github.com/necolas/react-native-web

@quanglam2807

@dorthwein Great idea! But if we follow this path, I think developing a version for React Native only would be better.

We can rewrite the whole project under React Native APIs instead of separate codes for Native and DOMs. Amazing! I have never thought about this.

@dorthwein

@quanglam2807 yeah - that way new features etc... Stay in line with each other. Biggest challenge I think is then having the styles and animations working. Also other big plus is that we can gradually add support for different components.

Down side is everything will need to be using flex boxes.

Given that this is a major refactoring of the code base - who all needs to sign off on this to go forward? I still need to play around and see how robust the react-native-web stuff is also.

@dorthwein

@quanglam2807 @oliviertassinari another advantage with this approach is that material-ui will easily port over to https://github.com/ptmt/react-native-desktop as well.

@dorthwein

@oliviertassinari is using react-native-web something that the maintainers on this project can get behind if it works out as expected?

@oliviertassinari
Member

@dorthwein I love the idea behind this project. But I don't think that it would help in the near future.
Don't we first need to write a native version of our components before we can use react-native-web?

@dorthwein

@oliviertassinari no, what react-native-web does is use the most "native" component depending on the platform. So for example given a View tag, it'd use a div in the browser, a UIView in iOS and what ever the equivalent to UIView is Android.

The process would then be instead of writing native versions of each component, that we'd just have to convert the existing ones to use View instead of div and style Text instead of using things like h1 and label.

Definitely not a small undertaking but the process would then be updating the existing components instead of trying to create & maintain multiple versions.

@oliviertassinari
Member

The process would then be instead of writing native versions of each component, that we'd just have to convert the existing ones to use View instead of div and style Text instead of using things like h1 and label.

That sounds exactly like writing a native version that hopefully, work in the browser too. As far as I know react-native-web is bringing react native to the web and not the otherway around.
Still, that can be really handy to share the same code 👍.
I have seen one small issue with this lib so far. Their StyleSheet.create implementation doesn't support dynamic values (needed for the muiTheme). We could use react look for this use case.

@dorthwein

@oliviertassinari your right - I was understanding it backwards. Step 1 it seems is still building react-native versions of the components. Step 2 would be potentially merging them into a single code base using something like react-native web.

@pgangwani

@wordyallen : looks good 👍

@wordyallen

@pgangwani I just started messing with it... Its not ready yet.

@joncursi

Ive been using https://github.com/react-native-material-design/react-native-material-design to fill the gap but it's very rough around the edges as well and no active development

This was referenced Aug 25, 2016
@wordyallen
wordyallen commented Aug 29, 2016 edited

I would donate financially to this endeavor, if I could.

@xotahal
xotahal commented Sep 22, 2016

Hi guys,

I work on react-native-material-ui, that is inspired by this library. Feel free to try - I would like to hear any feedback ;)

@jhabdas
jhabdas commented Sep 23, 2016 edited

@xotahal et. al, Instead of creating from scratch what we should be doing IMHO is forking this library and porting existing components rather than recreating them. The need for the material style inputs is sorely needed in the RN space, if you ask me. Thanks to all for your OSS efforts.

@antoinerousseau
Contributor

I don't think there is much common code, I think creating from scratch makes sense. Styling in RN will be 90% different than this one. And there is quite some platform specific mechanic like animations...

@jhabdas
jhabdas commented Sep 23, 2016 edited

It seems adopting the component structure, props (and docs) and having a clear upstream, even if a lot changes, would be beneficial long-term for those shifting back and forth from web to native and is of most importance. The rest becomes an implementation detail.

@joncursi

I agree with @jhabdas ; the more similar the APIs can look for each component, the less jarring it will be for developers to switch out of web projects and native projects. The less jarring the experience, the more productive they can be. I'd expect the platform-specific details to be abstracted behind the scenes of the component.

@jhabdas
jhabdas commented Sep 23, 2016

@chadobado or maintainer, would you kindly rename this issue to "Support React Native" to raise visibility when searching this repo? Currently searching "React Native" buries this in the list because the term is hyphenated in the title.

@oliviertassinari oliviertassinari changed the title from Create material-ui React-native to Support React Native Sep 23, 2016
@jhabdas
jhabdas commented Sep 26, 2016

FWIW, this caught my eye.

@necolas on Web support for react-native-material-kit:

You're unlikely to need to port much if any Stylesheet as compatibility is provided by the web implementation of React Native

@antoinerousseau
Contributor

@jhabdas if you play a bit with react native you'll see that it's not that straightforward. The StyleSheet API is awesome but you do have to rewrite quite some stuff ;)

@jhabdas
jhabdas commented Sep 27, 2016

Fair point @antoinerousseau. I keep thinking back to a quote from James Long on RN:

Think of it as a prototype for a different direction for the web

If I'm understanding the purpose of the library @necolas is working it seems a sane approach would be to inverse the problem: rather than porting the CSS to RN just rebuild the whole thing in RN and back port for web using a shim. React Native Material Kit already has a good jump on the problem.

@mattferrin

Since react-native-web appears awesome, I'm just going to create material-ui.android.js, material-ios.ios.js, and material-ui.web.js files in my own personal project and calling it good. If I follow the material-ui API by wrapping everything else, it will eventually work out. If material-ui surprises me and just works, I'll only need to remove the .web from the .web.js and delete the other files. This way I can selectively transition to material-ui per component.

@mattferrin

@oliviertassinari So I added the react-native branch as an NPM dependency and installed all the Babel plugins. I got this message when importing any component:

EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.

My goal is to use material-ui the soonest it becomes feasible per component. Granted, I did a git rebase master and should have done a git rebase next if anything. Are all individual react-native components roadblocked by next branch work preparation right now?

And I wrote some code that allows me to consume react-native-vector-icons in exactly the same way I consume material-ui icons:

// @flow

import React from 'react'
import {
  Text,
  View
} from 'react-native'
import Mui from './app/material-ui'
import Icons from './app/material-ui/icons'

export default React.createClass({
  render: function() {
    return (<View>
      <Icons.AccountCircle />
      <Mui.IconAccountCircle />
    </View>)
  }
})

Though at the moment react-native-vector-icons and material-ui have incompatible import syntax. @oblador I had to import glyphMap and iterate over it and export the entire list as one big object.

import { glyphMap } from 'react-native-vector-icons/MaterialIcons'

It would be nice if react-native-vector-icons Material icons were grouped by category like material-ui allowing individual exports from within a category:

import ActionHome from 'material-ui/svg-icons/action/home'

Should we work on a pull request to make react-native-vector-icons compatible with material-ui import conventions?

@oliviertassinari
Member

@mattferrin The react-native branch is quite old now. It's not intended to be consumed by users. It was a Proof Of Concept regarding the way ahead.
As far as I have looked at this issue, one of the promising approach would be to rewrite it to target react-native. Then react-native-web would do the hard part for us.
However, there are some challenges:

  • How much react-native-web is production ready? E.g. I haven't seen visual tests.
  • How do you handle media queries?
  • How do you handle a complex theming solution?

react-with-styles is worth looking at too.

@mattferrin

How much react-native-web is production ready?

@oliviertassinari I'm currently porting a website to react-native-web, and feel that it's worth embracing. It is missing a cross-platform anchor-tag href component and might be missing other niceties, but the underlying ReactDOM is production ready and that's what we need.

How do you handle media queries?

Should material-ui care? There are ways to find a component's or a screen's dimensions on all platforms. As long as material-ui components can be passed props that control styling, which they do, we're golden, I think.

Does material-ui perform media queries? Do we need to?

How do you handle a complex theming solution?

Can't we just check Platform to omit or rename React Native unsupported props, since (if memory serves me right) padding and margin are essentially reversed in React Native. All we would have to do is wrap the createStyleSheet equivalent method to transform/filter the result into non-"web" platform specific compatible styles.

I haven't used it as of yet, but Fela aims to be cross platform, and I think that is important. Since the author of Fela wrote React Look and since that seems to have been a prior choice, it feels like a natural choice.

I also haven't used it but something like react-tunnel seems nice for theming context. We could simply use and expose it, again only because it feels more community sharable. There might be a more popular equivalent.

@necolas
necolas commented Oct 4, 2016

How much react-native-web is production ready? E.g. I haven't seen visual tests.

There are interactive examples here: https://necolas.github.io/react-native-web/storybook/

How do you handle media queries?

In JavaScript, using matchMedia (or using Dimension) to determine which styles and components to render.

It is missing a cross-platform anchor-tag href component

Yeah I'm not sure what a "proper" solution should be, but you can use View and Text like links for now (web support only, of course):

<Text accessibilityRole='link' href={href}>{text}</Text>

How do you handle a complex theming solution?

React Native doesn't mind how you do this. You can still use context to determine which style objects to apply. I quite like Fela's API within components, but the implementation and plugin API looks like overkill if you were to use react-native-web.

All we would have to do is wrap the createStyleSheet equivalent method to transform/filter the result into non-"web" platform specific compatible styles.

Is the problem that you expose a style API that isn't RN compatible? If so, I'd suggest you expose a RN-compatible style API and let react-native-web convert it to DOM styles.

@mattferrin

@necolas

Is the problem that you expose a style API that isn't RN compatible? If so, I'd suggest you expose a RN-compatible style API and let react-native-web convert it to DOM styles.

Good point. Does react-native-web have a sense of :hover for example?

@mattferrin
mattferrin commented Oct 4, 2016 edited

@necolas And the particular work I am doing only needs to support evergreen browsers, but is there a possibility porting to react-native-web would cost material-ui browser compatibility with any older versions? I don't know anything about that really. I just really think react-native-web is the right approach.

@necolas
necolas commented Oct 5, 2016

It doesn't provide anything special for hover styles (neither does RN). I wonder if the desktop implementations for Windows and Ubuntu bundle anything for mouse interfaces or leave it to you via events.

I'm not sure what browser support you need but may be able to accommodate when issues arise

@mattferrin

I think it might be necessary to inject a boolean into the component hierarchy context via MuiThemeProvider to choose between a react-native-web versus a react-dom component style API.

The best answer is to just switch to the react-native-web style API, and that is what I'd advocate, but that would probably cause an upset.

@oliviertassinari Could we get away with switching material-ui to a react-native style API? Maybe allow mouse specific styles to leak through?

@mattferrin

@necolas @oliviertassinari Just as an FYI. It's sloppy right now, but I've been working on porting a branch (https://github.com/mattferrin/material-ui-build/tree/mine) to be cross-platform for the last 2-3 days because I really need it myself (to reduce my total work in the long term).

I've been porting everything to react-native-web syntax and commenting out styles that don't port, but I think I'll end up commenting them back in and using Platform.OS == 'web' to retain the original code essentially unchanged once I'm done porting the website I'm working on. At that point only the things I personally need will be ported and imperfectly.

It's a total mess (until I touch it up later on) because I push to jump between Mac and Windows machines on the fly.

@jhabdas
jhabdas commented Nov 25, 2016

For those who can't wait for MUI to come to RN there are alternatives, and some pretty nice looking ones at that. I'm maintaining an evergreen list here: https://habd.as/awesome-react-components/#react-native

@mattferrin

I knew the entire styling solution was changing, but I missed the part where the library is being rewritten from scratch. That is my fault. I had assumed, from looking at some code, that the end styles would essentially remain the same and that only the technology would change. I was incorrect. I didn't completely ignore the roadmap, I just made assumptions that are very wrong. I guess I'll have to bail on my attempt here.

@mbrookes
Member
mbrookes commented Dec 6, 2016 edited

@mattferrin Not quite from scratch (although in some cases that's true, for example Table) although the style solution change requires many API changes, but in addition gives us the opportunity to rationalise the API in other areas for many components. I'm sorry if your efforts were wasted - I hope it doesn't put you off Material-UI!

@mattferrin

@mbrookes It hasn't. I made the mistake of branching off master instead of next and underestimating the difference (and the total work in general). It was my fault and I knew there was risk. I'll simply return empty Text elements as placeholders until later in my React Native material-ui facade. When I've fully ported my website to react-native-web I'll come back and attempt to rebase new changes off next.

@tuckerconnelly

Releasing this guy today: https://carbon-ui.com

Inspired by material-ui, works on web and react-native :)

@wowzaaa
wowzaaa commented Dec 8, 2016

@tuckerconnelly u made my day

@jhabdas
jhabdas commented Dec 8, 2016 edited

@tuckerconnelly just gave you your own section to enjoy on Awesome React Components: https://habd.as/awesome-react-components/#universal. Godspeed and good luck!

@joncursi
joncursi commented Dec 8, 2016

@tuckerconnelly wow, lots of potential on this project... well done! Here's to hoping that the larger community will rally behind this effort! 🍻

@mattferrin

@tuckerconnelly I'm a little confused. I found that it is actually pretty easy to make material-ui conditionally cross-platform (despite my mistake of branching off master instead of next and wasting my time). I'm curious what benefits you see to an independent project?

@tuckerconnelly

I tried it back in February, and had a hard time with it, in particular with the ripple component and with cross-platform media queries.

Sometimes it's easier just to start from scratch.

@wowzaaa
wowzaaa commented Dec 8, 2016

for me it does not make sense to have React components that do not work on React Native ... and since the devs of material-ui did not consider RN a priority ... it is only fair/logical to start on a new path

@mattferrin
mattferrin commented Dec 8, 2016 edited

@tuckerconnelly I don't think it matters how components are implemented. I just hope both projects attempt to implement the same API (and agree on the same names) for their components. I'm glad you worked on this and shared.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment