github

renatorib / react-powerplug

  • среда, 13 сентября 2017 г. в 10:17:29
https://github.com/renatorib/react-powerplug


🔌 Give life to your Dumb Components.



react-powerplug

npm npm GitHub issues GitHub stars Twitter

🔌 Give life to your Dumb Components.

React PowerPlug is a Just add water™ set of function as children components that add different types of state logics in your dumb components. It creates a state and pass down the logic to the children, so you can handle your data/callbacks in dumb components.

It's has been created to (but not limited to) use with storybook, react styleguidist, documentations, etc. because it's the most common use case. Otherwise you can use in your normal components too, for example a Dropdown that needs to know if opened or not, and others cases.

Play with live Toggle example on CodeSandbox

import { Toggle } from 'react-powerplug'
import Checkbox from './MyDumbCheckbox'

<Toggle initial={true}>
  {({ on, toggle }) => (
    <Checkbox checked={on} onChange={toggle} />
  )}
</Toggle>

Components

Note: This is a kind of a cheat sheet for fast search.
If you want a more detailed API Reference and examples for each component see the Docs

State

Props: { initial }
Args: { state, setState }

<State initial={{ isLoading: false, data: null }}>
  {({ state, setState }) => (
    <DataReceiver
      data={state.data}
      onStart={() => setState({ isLoading: true })}
      onFinish={data => setState({ data, isLoading: false })}
    />
  )}
</State>

Toggle

Props: { initial }
Args: { on, off, toggle, setOn }

<Toggle initial={true}>
  {({ on, toggle }) => (
    <Checkbox checked={on} onChange={toggle} />
  )}
</Toggle>

Counter

Props: { initial }
Args: { count, inc, dec }

<Counter initial={0}>
  {({ count, inc, dec }) => (
    <CartItem
      productName="Lorem ipsum"
      unitPrice={19.90}
      count={count}
      onAdd={inc}
      onRemove={dec}
    />
  )}
</Counter>

Set

Props: { initial }
Args: { set, get, values }

<Set initial={{ sounds: true, graphics: 'medium' }}>
  {({ set, get }) => (
    <Settings>
      <ToggleCheck checked={get('sounds')} onChange={c => set('sounds', c)}>
        Game Sounds
      </ToggleCheck>
      <Select
        label="Graphics"
        options={['low', 'medium', 'high']}
        selected={get('graphics')}
        onSelect={value => set('graphics', value)}
      />
    </Settings>
  )}
</Set>

List

Props: { initial }
Args: { list, push, pull, sort, setList }

<List initial={['react', 'babel']}>
  {({ list, pull, push }) => (
    <div>
      <FormInput onSubmit={push} />
      {list.map(tag => (
        <Tag onRemove={() => pull(value => value === tag)}>
          {tag}
        </Tag>
      )}
    </div>
  )}
</List>

Bind

Props: { initial, getter }
Args: { value, setValue, bind }

<Bind initial="hello world">
  {({ bind, value }) => (
    <div>
      <ControlledInput {...bind} />
      <div>You typed {value}</div>
    </div>
  )}
</Bind>

Compose

Props: { states }
Args: depends on passed states

For an example, see below.

Composing Components

If you want to merge two of more components functionalities, you can compose they.
For complete guide see Compose docs

import { compose } from 'react-powerplug'

const ToggleCounter = compose(<Toggle initial={true} />, <Counter initial={2} />)

<ToggleCounter>
  {({ count, inc, dec, on, toggle }) => (
    <ProductCard
      {...productInfo}
      isFavorited={on}
      onFavorite={toggle}
      count={count}
      onAdd={inc}
      onRemove={dec}
    />
  )}
</ToggleCounter>

Also, you can use a built-in Compose component and pass components on states prop

import { Compose } from 'react-powerplug'

<Compose states={[<Toggle initial={true} />, <Counter initial={2} />]}>
  {({ on, toggle, count, inc, dec }) => (
    <ProductCard {...} />
  )}
</Compose>

It is the same to do this:

<Counter initial={2}>
  {({ count, inc, dec }) => (
    <Toggle initial={true}>
      {({ on, toggle }) => (
        <ProductCard
          {...productInfo}
          isFavorited={on}
          onFavorite={toggle}
          count={count}
          onAdd={inc}
          onRemove={dec}
        />
      )}
    </Toggle>
  )}
</Counter>

Because of this, when you use toggle function, only <Toggle> will be rerendered, but if you use inc or dec functions, both <Counter> and <Toggle> will be rerendered. Even using compose() utility.

Install

Node Module

yarn add react-powerplug
npm i react-powerplug

UMD library

<script src="https://unpkg.com/react-powerplug/dist/react-powerplug.min.js"></script>

exposed as ReactPowerPlug

Contribute

You can help improving this project sending PRs and helping with issues.
Also you ping me at Twitter