Material-ui: Support React Native

Created on 28 Apr 2015  ·  119Comments  ·  Source: mui-org/material-ui

Absolutely beautiful library.

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

enhancement

Most helpful comment

@rogerstorm funded this issue with $200. See it on IssueHunt

All 119 comments

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

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.

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.

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?

@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

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?)

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

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.

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

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

@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 :)

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

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

@lenaten that's a shame, thanks for responding

Alright, I have started working in this https://github.com/callemall/material-ui/pull/2611.
That's going to take some time!

@oliviertassinari awesome! very very excited

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

@dorthwein It's still open.

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

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

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

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

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

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

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

@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 (https://github.com/callemall/material-ui/pull/3829).
I should try to start from a fresh git clone.

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.

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?

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

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

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

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

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

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

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

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

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 :+1:.
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.

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

@wordyallen : looks good 👍

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

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

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

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 ;)

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

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

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.

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.

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

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

@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 ;)

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.

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.

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

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

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.

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.

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

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

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

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?

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

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

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.

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

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

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

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

@tuckerconnelly u made my day

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

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

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.

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

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

So for 2017/2018 after the v1.0.0 will RN be the next goal for material-ui ?

As seen of :

  • The community participation to v1
  • The number of people who want RN support
  • The fact that many projects have been based or inspired by Material-ui to offer RN components
  • Experience gained from all this and the fact that a lot of time has passed since this issue has been opened

If you'd start (probably after v1 launch) a project to offer RN components a lot of people would help you. You'd just need to start and define a clear path and it'd be good to go. You have a great community let's use it to make the best product possible.

@NitroBAY 1.0 uses JSS instead of JS objects for styling so it relies on cssinjs/jss#368 to support React Native. But I think it's better to develop a parallel version for React Native like this one: https://github.com/xotahal/react-native-material-ui. Then we can the React Native version runs on web using https://github.com/necolas/react-native-web

So is this a wont-fix? If so can it please be tagged as such?

@jhabdas I would love to see a good library bringing the material specification into React Native.
From the links posted in the thread, there is already a good list of candidates.

If we keep that issue opened it's regarding unifying the web and the native. Providing a consistent API between the two platforms. I wish I had time to work on that but I don't and I doubt it's going to change.
@callemall/material-ui team would love to see someone taking the lead on that issue.

Still supporting carbon-ui :) I only add components as I need them (not pro-actively trying to fill out the entire spec), but I think there's a good framework there for people to rally behind.

  • It auto-generates docs from the component comments
  • Has docs site (carbon-ui.com)
  • Supports native and web with same components

Would help anyone who wants to add components :)

@tuckerconnelly What do you think about https://github.com/xotahal/react-native-material-ui? It doesn't work on the web due to a bug with Elevation, but if we applied your code https://github.com/tuckerconnelly/carbon-ui/blob/master/src/style/Elevation.js, I think it would work. @oliviertassinari makes a good point that we need to decide on a main project to work together.

@quangbuule wait you say that we should develop apps as RN apps and then use that tool to transform RN to a WEB version ?
I never heard of that thing but okay. But then it means that we wouldn't use material-ui anymore but more a RN fork ?

@NitroBAY We basically port material-ui to a RN fork and I think when it's ready, it will become the official version for both web and native. I think it's fine considering material-ui is using a similar approach with the next branch.

Sorry for all the noob questions but I land into ReactLand since about 1 week.

You think that your package is going to replace this one ?
You're approach seem to be multi-platfom and so very good. Material-ui stick to only web because they don't have time but they have time to next, why ?
You say next use isomorphic approach on next but if I take whatever component i.e paper it will work only for web as there's a div component.
Who are we, are you a part of this team ?
Regardless technical considerations, don't you think using MD on IOS may annoy users ?

EDIT : off topic but no one answered me, what advantages does jss-theme-reactor brings when it comes to compare it to jss-react ?

@NitroBAY:

  1. I'm not the developer of this project or any React Native project. But I have watched this issue for months, and at the moment, I am looking forward to starting contributing to react-native-material-ui.
  2. paper or the shadow thingy is now working on web, iOS, Android. So it's not a big deal.
  3. material-ui master branch uses objects to define the stylesheets but to improve the performance (30% boost), the contributors switch to JSS (CSS in JS) in the next branch. At the moment, JSS is not compatible with React Native.
  4. Google use Material Design on iOS and I don't think users mind a lot. Of course, you should modify some parts to fit into the platform such as changing the status bar's color, using iOS sharing icon, etc. I used material-ui for my Windows 10 & macOS app and I didn't see many users complained about it (http://moderntranslator.com/). Some even said MD was easier to use.

But I still don't understand in which way the next branch may work in RN if the components are using HTML elements such as span or div. I may have missed something but to develop in RN you need to use RN components, isn't it ?
I'm quoting you :

it will become the official version for both web and native. I think it's fine considering material-ui is using a similar approach with the next branch.

But may I didn't get it correctly. DO you mean next branch will make us able to use components in RN ?

@NitroBAY: next branch will make material-ui less compatible with React Native. Also, even though RN component doesn't support span or div, by using conditional rules, you can something like this:

if (platform === 'web') return <span/>;
else return <View />;

You can check: https://github.com/necolas/react-native-web

Oh okay I thought you mean that they made RN compatible.

Is the TL;DR that this project has no interest in multi-platform support via the React Native API, and that effort should move to https://github.com/xotahal/react-native-material-ui?

The docs for carbon-ui are better, and it already works on web. What's the benefit of react-native-material-ui?

So everyone agree that material-ui is gonna be stopped to be used and recommended in a few time ? Then that's a pity that owners of this package don't want RN ?

carbon-ui looks like it will have performance issues from not using StyleSheet and from injecting so many web fonts

screen shot 2017-03-15 at 1 10 26 pm

Calm down, guys! It's still coming.

TL;DR: If you build a component for React Native, it will work on RN and web. But if you build a component for web, it won't work on RN. And material-ui is built for web, optimized for web => To make it works on RN, the performance has to be sacrificed (at least, at the moment). Thus, I think it's better to keep the two projects separate until RN is more mature.

optimized for web => To make it works on RN, the performance has to be sacrificed (at least, at the moment)

Do you have any data to share about that?

Here are my findings for RNW so far:

@necolas #4066

Hmm, I can look into using StyleSheet with Uranium. I will say, haven't noticed any CSS-related performance issues, but will see if I can integrate better with your StyleSheet stuff.

The biggest performance hit comes from Animated: https://github.com/animatedjs/animated/issues/48 But that affects all RNW applications.

Does injecting web fonts meaningfully decrease performance? It loads them directly from google fonts, so they're already likely cached on the user's system.

Most important thing I think is for everyone to rally behind a single library. And I don't think material-ui is going to support React Native.

@necolas The TL;DR is that the path going forward is unclear.

union

A=react-native
B=the web

1. The most constrained platform

A possible approach is to target the most constrained platform, hence starting from react-native. Then to extend the features to the web. In order to extend the features to the web, we could be using:

However, that comes with a tradeoff, we would win code sharing. But I'm expecting to lose in some dimensions.

Bringing the native API to the web

The API has to be reimplemented to work with the browser. What's the overhead?

Handling missing web API in native

As we start from the most constrained platform we would need to reimplement some web available feature. What about media queries? CSS inheritance, CSS animations?
Who would we implement accessibility and keyboard events without bloating the native version?

2. The less constrained platform

Another solution is to start from the less constrained platform, hence the web. Then creating reimplement missing native features.

However, that comes with a tradeoff, we would win code sharing. But I'm expecting to lose in some dimensions.

Bringing the web API to the native

We gonna have to make sacrifices, I'm expecting some web feature to be really hard to implement on native, for instance, the CSS media queries, the CSS animations. (advanced CSS rules)

Handling missing native API in the web

Some of the missing web API features is around touch handling, scroll & infinite list view, native components like a DatePicker or a Drawer.

3. Contract sharing

A third solution could be to set up an infrastructure to share API & tests then reimplement the components in the two underlying platform. From my perception, it's how react-native is approaching iOS and Android.
Then using a mixed approach of the two previous one to full fill the contract. I mean, using code branching when that makes sense and code sharing as much as we can.
For instance:

  • Why using animated.js on the browser when we can use CSS transitions?
  • Why implementing the Drawer logic on react-native when we can use the native component?

I think that option 3. is the most promising one. It's how I have tried to solve the problem in react-swipeable-views.

https://github.com/tuckerconnelly/uranium supports cross-platform media queries :)

The beauty of RN is that you have a simple library of abstract APIs and primitives, and the low-level implementations are taken care of. Animated is same--simple library for animations, low-level implementations (native animations on iOS/Android, css transitions on web) are taken care of.

I think animated.js could be jiggered to use css transitions. Would for sure improve performance.

@quanglam2807 that thread is very long, what should I be looked at?

In order to extend the features to the web, we could be using: https://github.com/necolas/react-native-web, https://github.com/taobaofed/react-web

react-web is pretty far from being performant or functionally correct IMO.

The API has to be reimplemented to work with the browser. What's the overhead?

Overhead in what dimensions? Hard to determine in terms of bundle-size. You'd probably be able to drop some of your existing code; but if you were to depend on anything beyond the RNW core exports, it will add up quickly. In style-heavy components for mobile.twitter.com, I've been seeing 20-40% reduction in component size converting styles from css-modules to RNW StyleSheet. In terms of runtime performance, it's currently not far off css-modules.

What about media queries?

You can use matchMedia to change styles and component structure, although the benefits of using media queries to alter components aren't clear to me.

CSS inheritance, CSS animations?

RNW supports CSS animations (although I need to add an API to define keyframes). What's the question related to CSS inheritance?

How would we implement accessibility and keyboard events without bloating the native version?

Not sure what this means. I suspect the threshold for "bloat" in a native app is far higher than for a web app.

so maybe comparing how react-native-web handles styles to render css performances to css-modules performances is less pertinent now

Why would that be?

It'd be great to have a kind of react-native-web who use something like aphrodite or jss

Both of those libraries are slower, larger, and not well suited to providing deterministic styles

@necolas material-ui is providing a great effort to switch from a css-in-js method to a stylesheet method (css in <style>). They have been active efforts for months to switch the components. Reasons are here. From what I read using jss is an huge advantage and seem to be the most perfect solution to handle style so far.

By the way by reading the Roadmap.md again the RN support is on the Roadmap.

I'm very interested in using Material-UI with react-native, any word on progress?

@wswoodruff You can check this one for now - https://github.com/xotahal/react-native-material-ui

Currently, we have three awesome libraries for that:

Enjoy!

There's also the lesser known Carbon UI if you're going universal. But for my time I'd probably stick to one of these.

its been touched on a couple of times in this thread, but i want to call it out again because of how it impacts my interest in this change: the main benefit of react-native support that i see isn't actually about react-native, but instead about being built on the primitives that enable the same components to be used on _both_ native and web.

if that type of primitive were used, other tools like react-sketchup and react-pdf could also be enabled.

personally, those are more interesting to me than native, but would be enabled by the same changes.

@jhabdas How is ur experience using Carbon UI ? Bcz to me it looks pretty good but didn't use it yet.

@deadcoder0904 haven't used it yet personally. probably try reaching out to one of the guys at infinite red. they run the RN newsletter and should be the subject-matter experts. if and when I do build another RN app (okay, when...) I won't be clobbering things together this time or building another boilerplate—IMHO the space is solved by existing boilerplates and components.

Here are some of the hurdles that I can think of that would need to be overcome to make MUI available in React Native. Assuming v1 MUI and we keep JSS, the classes pattern, and other things that are at this point key parts of MUI's api design.

  • JSS needs to support RN, namely making style objects in such a way that withStyles just works. More on this in https://github.com/cssinjs/jss/issues/368#issuecomment-376708219.
  • Assuming there is no hacky wrapper or babel transform, we'll need to augment the classes pattern so it works the same but accounts for the fact that on RN it should instead pass an array to style, and probably should be named styles. Perhaps this could be handled by dropping classnames and adding spreadable helpers that behind the scenes switch between classes/className handling and styles/styles.
    Maybe:
    js const styleProps = props.composeStyles( 'root', (raised || fab) && 'raised', fab && 'fab', fab && mini && 'mini', color === 'inherit' && 'colorInherit', flat && color === 'primary' && 'flatPrimary', flat && color === 'secondary' && 'flatSecondary', !flat && color === 'primary' && 'raisedPrimary', !flat && color === 'secondary' && 'raisedSecondary', size !== 'medium' && `size${capitalize(size)}`, disabled && 'disabled', fullWidth && 'fullWidth', ); return <ButtonBase {...styleProps} ... />
    composeStyles would accept a list of style names (and ignore falsy values). On web it would look in props.classes and output {classNames}. On native it would look in props.styles and output a {style}.
    Originally I thought of this.composeStyles with a decorator, but instead of that withStyles could just pass a style composition helper in as part of props.
  • As others mentioned after all this to make basic styled components work, we'll need extra work to make animations, touchables, etc... work.
  • However for animations I don't consider this a bad thing. It is a small loss for simple transitions, where you're just automatically transitioning opacity, backgroundColor, etc we may want helpers that keep those simple. But from what I've seen, the actual material transition implementations other than those look overly complicated/cryptic and won't scale up well. react-transition-group has some nice ideals for handling the low level portion of things (entry/exit handling, etc), but is problematic / in the way in others. Also instead of the css transitions based design I think the forward thinking way to go would be to use the new Web Animations API and require the polyfill for it.
    In other words, I think there is room for the creation of a new library to handle animations in React that uses Web Animations in the browser and the Animated API in React Native and is a general improvement over how MUI handles animation.
  • MUI needs to ditch the expectation that cascading behaviour is available. And the theme setup needs to be enhanced to support easily applying modifications to the theme within a subtree.
    Right now things like AppBar + Icons work by setting text color, using an explicit color='inherit' and assuming the color will cascade down. And it's possible that this is the same in other parts of MUI.
    There is no cascading like this in React Native. Instead you must declare your styles explicitly for each View. For these types of things AppBar and other components will need to be able to easily provide a modified version of the theme they are provided with a modification like changing the theme within that context to dark so icons get the correct contrasting icon colors (and can be based on the actual icon colors spec instead of text color). Note that this may have implications on things like menus nested in app bars.
  • As an extension of this cascading issue. MUI is also designed around things like <Button>Text</Button>, where it's assumed that MUI can just style the fontFace/color, etc... of the button's root, let you insert anything in the children, and just let React DOM insert a mix of elements and text nodes and the text nodes get the right styling.
    This falls apart in React Native. All text must be part of a <Text>, all text styles must be on that component's styles, and a text element cannot contain non-text children (i.e. ).
    There are a few options:

    • The <Button text='Text' /> pattern works much better in React Native. Unfortunately that's fundamentally different from MUI's ethos, so it's not an option.

    • We could map the children and replace strings with styled Text elements. However this is brittle, the moment you wrap the string in anything it falls apart (even react-intl would make it fall apart). Ugh.

    • It's not the prettiest way to do it, we'd have to wait, and I do not 100% understand the performance implications. But we could use React 16.3's new context api, and expose a <MuiText>Text</MuiText>. Basically MUI components like Button would have providers that would provide information about the current context's styles (font, text color, etc...) and MuiText would just consume that data and apply it to a Text element.

Today v1 released so what are the plans of React Native❓

For React Native Material Support, there is a beautiful library called React Native Paper which will be maintained & supported by CallStack team.

But are there any plans to port this to React Native because I think Paper works perfectly fine❓

If not, then you can probably close this issue :)

Thanks for sharing @deadcoder0904. I've added Paper to Awesome React Components. Haven't heard of CallStack. At first I read it as Call-Em-All. Guessing they're not the same peeps, ya?

@jhabdas Nope they're not same

@dantman Here are my thoughts on the best way to go about achieving native support

  • if sticking to jss isn't an absolute requirement, I think fela is a viable alternative:
  • react-native-animatable has keyframe support, and could probably be used instead of transition-group as well, which may or may not work with native.
  • I agree with subverting the no-cascading view of react-native. It could be opt-in at provider and consumer with cascade and inherit props.
    Every react-native library I've tried working with has been painful or unusable because of overly-rigid apis and un-overridable styles, with the exception of ones that use @shoutem/theme to allow overrides (like native-base).

Still waiting for this support. Using beautifully on Web but I develop on mobile too!

any update about support react native?

@oliviertassinari I intend to fork and start exploring the implementation path I outlined above. My priority is going to be getting the components I need for another project working, so I probably won't be PRing robust React Native support anytime soon, but I'll try to keep it "in sync" with master as much as I can in hopes it'll one day be useful (or possibly merged)

@micimize Thanks for letting me know. I wish you good luck in this project! :) Regarding why we haven't been working on react-native yet. I think that it comes in different flavors. Most importantly, we have no core maintainer interested in doing such. I can understand it, react-dom usage grows faster than react-native and it's hard.

Update on this: We migrated a substantial chunk of functionality to a somewhat-usable state, including lists, buttons, cards, icons, selection controls, text fields, and backdrop. Unfortunately, once we were finally developing our app itself on react-native, a multitude of issues cropped up and compelled us to move to Flutter.

At some point I would like to go back and salvage some of the work we did, chiefly the port of withStyles / classes styling solution which leveraged css-shorthand-properties and some other neat stuff, however it is no longer a priority for me.

@rogerstorm funded this issue with $200. See it on IssueHunt

Working on the problem would be an opportunity cost for us. I'm closing. We will double down on better supporting the browser use cases.

@oliviertassinari , does it mean that react native support is out of scope and in near future (e.g. 1 year) it won't be on radar?

Yes

https://github.com/lightningtgc/react-native-material-ui Is nothing but another scam npm package

Was this page helpful?
0 / 5 - 0 ratings

Related issues

finaiized picture finaiized  ·  3Comments

ghost picture ghost  ·  3Comments

ghost picture ghost  ·  3Comments

revskill10 picture revskill10  ·  3Comments

iamzhouyi picture iamzhouyi  ·  3Comments