Skip to content

vicentedealencar/react-agnostic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

react-agnostic

Platform agnostic react components


Build Status Code Coverage version downloads MIT License

All Contributors PRs Welcome Code of Conduct

Watch on GitHub Star on GitHub Tweet

The problem

React is known to be a multi-platform UI library, but it is not that simple to get done. There are many renderers (as: react-dom, react-native, react-primitives, reactxp, react-blessed, react-tv, react-pdf, redocx, react-360, etc) which allow components to run in different platforms. When you write a component that dependends directly on a component specific to some platform, this means it wont run on any other platform.

This solution

react-agnostic makes it so you can write your components without any direct dependencies from platform specific components. It applies inversion of control using react context pass around components.

Table of Contents

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies:

npm install --save react-agnostic

Usage

This library exports a component and a HOC (Higher Order Component)

ComponentsProvider

This component allows the components augmented by withComponents to access platform specific components.

At the top level of your app, setup specific platform components and render the ComponentsProvider component passing a components prop.

If you're using create-react-app, your App.js file would look something like this:

import React from 'react'
import {ComponentsProvider} from 'react-agnostic'
import UpdateCartItem from './components/UpdateCartItem'

const Text = props => (
  <span
    {...props}
    style={{fontFamily: 'monospace', padding: 10, fontSize: 24}}
  />
)
const View = props => (
  <div
    {...props}
    style={{backgroundColor: '#222', padding: 20, color: 'white'}}
  />
)
const Button = props => (
  <button
    {...props}
    style={{
      border: '1px solid orange',
      display: 'inline',
      backgroundColor: 'gray',
      color: 'white',
      width: 30,
      height: 30,
      borderRadius: 15,
    }}
  />
)

const components = {
  View,
  Text,
  Button,
}

class App extends React.Component {
  state = {
    item: {
      name: 'ball',
      amount: 3,
    },
  }

  render() {
    return (
      <ComponentsProvider components={components}>
        <UpdateCartItem
          item={this.state.item}
          updateCartItem={item => this.setState({item})}
        />
      </ComponentsProvider>
    )
  }
}

export default App

withComponents

This HOC injects a components that you to access specific platform components.

Example usage:

import React from 'react'
import {withComponents} from 'react-agnostic'

const UpdateCartItem = ({item, updateCartItem, components}) => {
  const {Button, Text, View} = components

  return updateCartItem ? (
    <View>
      <Button
        disabled={item.amount <= 0}
        onClick={() => updateCartItem({...item, amount: item.amount - 1})}
      >
        -
      </Button>
      <Text>{item.amount}</Text>
      <Button
        onClick={() => updateCartItem({...item, amount: item.amount + 1})}
      >
        +
      </Button>
    </View>
  ) : (
    <Text>{item.amount}</Text>
  )
}

export default withComponents(UpdateCartItem)

Examples

Begin by cloning this repository, then cd into it.

git clone https://github.com/vicentedealencar/react-agnostic
cd react-agnostic

Create React App

create-react-app

cd examples/cra
npm install
npm start

Create React Native App

create-react-native-app

npm install -g expo-cli
cd examples/crna
npm install
expo start

Proton Native

proton-native

cd examples/proton
npm install
npm start

ReactXP

reactxp

cd examples/reactxp
npm install

# web
npm web-watch
start index.html

# native
npm start
npm run android
npm run ios

Inspiration

Repository based on kcd-oss

Blog with many react supported renderers: https://dev.to/kayis/react-can-do-it-31di

Renderers

Other Solutions

I'm not aware of any, if you are please make a pull request and add it here!

Contributors

Thanks goes to these people (emoji key):


Vicente de Alencar

πŸ’» πŸ“– πŸš‡ ⚠️

This project follows the all-contributors specification. Contributions of any kind welcome!

LICENSE

MIT

About

Platform agnostic react components

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published