Git Product home page Git Product logo

react-platform's Introduction

@react-platform

Cross-platform React interoperability APIs, component wrappers and polyfills for all React (Native) platforms.

This exists primarily as an experimental and unofficial community-led project to explore and help push forward standards and progress for React as a platform.

The project is inspired by and builds on top of Leland’s react-primitives project and Nicolas’s react-native-web. While not integrated with, this may pull ideas/research from reactxp.

Please feel free to post any questions or proposals in issues, or feel free to contact me (via issues/Twitter).

What is @react-platform?

@react-platform is an npm package ecosystem of primitive components and APIs that can be used for cross-platform React codebases/libraries, with polyfills/fallbacks for platforms that don't have appropriate native/JS equivalents.

As an example, @react-platform/native exports React Native components like <ScrollView> and <SafeAreaView> that fallback to <View> on unsupported platforms.

As this is in alpha, all versions are 0.x.x and packages may be deprecated or change in the future. Where possible, we will try our best to follow semantic versioning and issue deprecation notices.

Supported Platforms

Planned Platforms

Getting Started

Example of @react-platform/native, a React Native interoperability layer with polyfills and primitive fallbacks:

npm install --save @react-platform/native

On a React web, React Native or React Sketch.app project:

import { Text, View } from 'react-primitives';
import { ScrollView, SafeAreaView, TextInput } from '@react-platform/native';

export default function HomeScreen() {
  return (
    <ScrollView style={{ flex: 1 }}>
      <SafeAreaView style={{ height: 64 }}>
        <Text>
          Header Here
        </Text>
      </SafeAreaView>
      <View>
        <TextInput initialValue="Hello World" onChangeText={(value) => console.log(value)}>
      </View>
    </ScrollView>
  )
}

Terminology

Bridge

Messaging tunnel between native code and JavaScript/React runtime.

Layout

Yoga layout (native Flexbox port).

Threads

Communication between threads is asynchronous.

UI Thread (Platform UI)

Bridge to layout thread with view.appendChild(RCTView)

Layout Thread (Shadow Tree)

React reconciliation tree.

Bridge to JavaScript thread with [..., createView(id, RCTView, ...)]

JavaScript Thread (React Runtime)

Reading

Talks

Contributing

Open to contributions :)

License

MIT

react-platform's People

Contributors

macintoshhelper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

react-platform's Issues

styled-components and emotion package

Create styled-components package wrapper that lets you use components without react-native-web.

This may be necessary for styled-components/primitives SSR support, or for use cases where react-native-web isn't installed.

We should encourage the use of styled-components/primitives instead, in documentation.

This could be a new package like @react-platform/styled

Pseudo-code for the wrapper:

const styled = Platform.select({
  web: () => require('styled-components'),
  default: () => require('styled-components/primitives'),
})();

if (Platform.OS === 'web') {
  styled.View = styled.div;
  styled.Text = styled.span;
  styled.Image = styled.img;
} else {
  styled.div = styled.View;
  styled.img = styled.Image;
  styled.span = styled.Text;
}

module.exports = styled;

Test useWindowDimensions polyfill for web

It appears that web window.screen.width and window.innerWidth have some unreliable behaviour on desktop, e.g. when resizing a window to mobile width, and on a mobile device, where the viewport is artificial, but innerWidth isn't.

I've implemented a hack with a comparison operator, but this needs to be tested, and needs feedback.

This deviates from using react-native-web, which uses window.innerHeight and window.innerWidth, which in my testing seem to not render density independent pixels, as they do on React Native: https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/useWindowDimensions/index.js#L19 . So maybe this should be raised as an issue there?

Documentation and examples

Need some better documentation around the react-primitives ecosystem, and examples of using the @react-platform namespace in each platform: e.g.

Expo compatibility

As I haven't used Expo for React Native before, and generally like having control over native linking/code, would be great to have some feedback/testing from others on this.

I think this should be Expo compatible? Dependencies should already be installed and should just resolve fine?

Dimensions and PixelRatio API

Do we want to support React Native's Dimensions and PixelRatio? Or discourage their use?

I propose supporting them, and adding injection systems for react-sketchapp to use global screen dimensions and pixel ratio values, but to later have an opt-out console warning layer to discourage their use and push for using useWindowDimensions instead, as dimensions should not be used as static values.

The main use-case for this would be aliasing react-sketchapp/react-figma to @react-platform/native and keeping things somewhat working. While aliasing will be discouraged by this project, it's a nice way to get a quick proof-of-concept running before refactoring a codebase to import common primitives.

Rollup plugin

Develop a Rollup plugin to resolve platform cascades/extensions.

This could be accompanied by a Webpack plugin, for web entrypoints, but extension resolving for apps could be avoided by using this code pattern:

core.js

let _module;

if (typeof window !== 'undefined) {
  _module = require('./core.web');
} else {
  _module = require('./polyfill'); // JS/React only implementation e.g. render null + console.warns
}

module.exports = _module;

React Native API parity

Implemented components:

Hooks

  • useWindowDimensions7f98478
  • useColorScheme

Components

APIs

  • AppState
  • Alert
  • Dimensions #3
  • PixelRatio #3
  • Linking (requires runtime I think? Is react-sketchapp support possible?)
  • Share – Maybe this'll have to be a hook ? May need a context provider to handle the UI.
  • TODO: Populate from https://reactnative.dev/docs/accessibilityinfo

What is a React Platform?

[WIP umbrella issue for discussion/ideas, to help surface proposals]

What counts as a React platform?

Is using react-reconciler enough to count as a platform? Or does react-test-renderer count, for the case of react-sketchapp?

Will Metro be an explicit requirement, or will Webpack/ be supported as entrypoint bundlers?

  • Some runtime environments may be in sandboxes where running bundlers like Metro aren't appropriate, such as in design software plugins, where file extensions are nice as a universally accepted standard across bundlers, especially with Babel extension preferences.
  • Should file extensions remain a stable/supported default for out-of-tree platforms?

How should imports work?

  • Is import { ... } from 'react-native'; a safe pattern for out-of-tree platforms?
  • How can we make sure that props are types without tsconfig hacks?

Proposal

Standardise platform-specific imports around react-native-ios, react-native-windows, or @react-native/ios.

Support react-native as a common API surface across platforms, or have react-platform/react-primitives as a common API layer that maps to react-native-windows, etc. Or have react-primitives for react-reconciler platforms that don't have the full Metro/Fabric setup (e.g. react-primitives View import aliases to react-native-<platform> <View>, and react-native for those that do.

Core package

We should decide how the core package: @react-platform/core will work. For now, it should probably remain unpublished, and provide a set of common APIs like Platform, and maybe supported platform enums? With a core injection API that doesn't depend on platform specific internals like react-native-web?

Or just re-export react-primitives for now?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.