renatorib / react-powerplug
- среда, 13 сентября 2017 г. в 10:17:29
🔌 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>
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
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>
Props: { initial }
Args: { on, off, toggle, setOn }
<Toggle initial={true}>
{({ on, toggle }) => (
<Checkbox checked={on} onChange={toggle} />
)}
</Toggle>
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>
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>
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>
Props: { initial, getter }
Args: { value, setValue, bind }
<Bind initial="hello world">
{({ bind, value }) => (
<div>
<ControlledInput {...bind} />
<div>You typed {value}</div>
</div>
)}
</Bind>
Props: { states }
Args: depends on passed states
For an example, see below.
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.
yarn add react-powerplug
npm i react-powerplug
<script src="https://unpkg.com/react-powerplug/dist/react-powerplug.min.js"></script>
exposed as ReactPowerPlug
You can help improving this project sending PRs and helping with issues.
Also you ping me at Twitter