Skip to content

Commit 26d318d

Browse files
authored
Merge pull request #7 from renatorib/next
prepare 0.4.0
2 parents 0f78432 + 91ad7e4 commit 26d318d

39 files changed

+2314
-198
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"commonjs": {
77
"presets": ["es2015", "react", "stage-1"]
88
},
9+
"test": {
10+
"presets": ["es2015", "react", "stage-1"]
11+
},
912
"rollup": {
1013
"presets": [["es2015", { "modules": false }], "react", "stage-1"],
1114
"plugins": ["external-helpers"]

.eslintrc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515
},
1616
"env": {
1717
"browser": true,
18-
"node": true
18+
"node": true,
19+
"jest": true
1920
},
2021
"rules": {
2122
"valid-jsdoc": 2,
2223
"react/prop-types": 0,
2324
"react/jsx-uses-react": 1,
2425
"react/jsx-no-undef": 2,
25-
"import/no-unresolved": ["error", { "ignore": ["^react$"] }]
26+
"import/no-unresolved": ["error", { "ignore": ["^react$"] }],
27+
"import/unambiguous": 0,
28+
"react/jsx-key": 0
2629
},
2730
"plugins": [
2831
"import",

README.md

Lines changed: 198 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88

99
:electric_plug: Give life to your Dumb Components.
1010

11-
**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.
11+
---
12+
> I'm working on version 1.0. [Follow me on twitter](http://twitter.com/renatorib_) to know when news will come up.
13+
---
1214

13-
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.
15+
**React PowerPlug is a *Just add water™*** set of **render props (or function as children) components** that provides different types of state and logics so you can use with your dumb components. It creates a state and pass down the logic to the children, so you can handle your data/callbacks.
16+
17+
It's has been created to (but not limited to) use with **storybook, react styleguidist, documentations, prototypes**. You can also use to create a bunch of uncontrolled components where the outside app don't care about your state, for example a menu dropdown.
1418

15-
[Play with live Toggle example on CodeSandbox](https://codesandbox.io/s/jp890p2x7w)
1619

1720
```jsx
1821
import { Toggle } from 'react-powerplug'
@@ -23,16 +26,37 @@ import Checkbox from './MyDumbCheckbox'
2326
<Checkbox checked={on} onChange={toggle} />
2427
)}
2528
</Toggle>
29+
30+
// you can also use a `render` prop instead
31+
32+
<Toggle
33+
initial={false}
34+
render={({ on, toggle }) => (
35+
<Checkbox checked={on} onChange={toggle}>
36+
)}
37+
/>
2638
```
2739

40+
# Render Props
41+
42+
For most people, this may look pretty weird. **But it's extremely powerful**. Usually you render some element whitin your component, but if you are creating an 'agnostic' component or a kind of abstraction component you can not simply render elements, you don't know what the user wants to render. So you render values, actions, states, data... props. You pick these props passing a function to children (or render prop) and now with this data you have total control of what you want to do. Now render what you want to render and do what you want to do. **Render props components are about abstracting some logic without any UI.**
43+
44+
React PowerPlug brings to you a bunch of components that act as state and logic containers, so you can get this powerful abstraction and use it any way you want.
45+
46+
**Note:** with PowerPlug you can use `children` or `render` prop.
47+
You decide which one is best for you.
48+
2849
# Components
2950

3051
***Note:*** *This is a kind of a cheat sheet for fast search.*
31-
*If you want a more detailed **API Reference** and examples for each component see the [Docs](docs/README.md)*
52+
*If you want a more detailed **API Reference** and examples for each component see the [Docs](/docs)*
3253

33-
## [State](docs/components/State.md)
34-
**Props:** `{ initial }`
35-
**Args:** `{ state, setState }`
54+
## State Containers
55+
56+
### State
57+
**Component Props:** `{ initial }`
58+
**Render Props:** `{ state, setState }`
59+
[see docs](docs/components/State.md)
3660

3761
```jsx
3862
<State initial={{ isLoading: false, data: null }}>
@@ -46,9 +70,10 @@ import Checkbox from './MyDumbCheckbox'
4670
</State>
4771
```
4872

49-
## [Toggle](docs/components/Toggle.md)
50-
**Props:** `{ initial }`
51-
**Args:** `{ on, off, toggle, setOn }`
73+
### Toggle
74+
**Component Props:** `{ initial }`
75+
**Render Props:** `{ on, off, toggle, setOn }`
76+
[see docs](docs/components/Toggle.md)
5277

5378
```jsx
5479
<Toggle initial={true}>
@@ -58,27 +83,59 @@ import Checkbox from './MyDumbCheckbox'
5883
</Toggle>
5984
```
6085

61-
## [Counter](docs/components/Counter.md)
62-
**Props:** `{ initial }`
63-
**Args:** `{ count, inc, dec }`
86+
### Loading
87+
**Component Props:** `{ initial }`
88+
**Render Props:** `{ isLoading, toggle, setLoading }`
89+
[see docs](docs/components/Loading.md)
6490

6591
```jsx
66-
<Counter initial={0}>
67-
{({ count, inc, dec }) => (
68-
<CartItem
69-
productName="Lorem ipsum"
70-
unitPrice={19.90}
71-
count={count}
72-
onAdd={inc}
73-
onRemove={dec}
92+
<Loading initial={false}>
93+
{({ isLoading, toggleLoading }) => (
94+
<Button onClick={toggleLoading}>
95+
{isLoading ? 'Loading...' : 'Click me'}
96+
</Button>
97+
)}
98+
</Loading>
99+
```
100+
101+
### Value
102+
**Component Props:** `{ initial }`
103+
**Render Props:** `{ value, setValue }`
104+
[see docs](docs/components/Value.md)
105+
106+
```jsx
107+
<Value initial="React">
108+
{({ value, setValue }) => (
109+
<Select
110+
label="Choose one"
111+
options={['React', 'Preact', 'Vue']}
112+
value={value}
113+
onChange={setValue}
74114
/>
75115
)}
76-
</Counter>
116+
</Value>
117+
```
118+
119+
### Index
120+
**Component Props:** `{ initial }`
121+
**Render Props:** `{ index, setIndex }`
122+
[see docs](docs/components/Index.md)
123+
124+
```jsx
125+
<Index initial={0}>
126+
{({ index, setIndex }) => (
127+
<Tabs selected={index} onChange={setIndex}>
128+
<Tab title="First tab">Content from the first tab</Tab>
129+
<Tab title="Second tab">Content from the second tab</Tab>
130+
</Tabs>
131+
)}
132+
</Index>
77133
```
78134

79-
## [Set](docs/components/Set.md)
80-
**Props:** `{ initial }`
81-
**Args:** `{ set, get, values }`
135+
### Set
136+
**Component Props:** `{ initial }`
137+
**Render Props:** `{ set, get, values }`
138+
[see docs](docs/components/Set.md)
82139

83140
```jsx
84141
<Set initial={{ sounds: true, graphics: 'medium' }}>
@@ -98,9 +155,10 @@ import Checkbox from './MyDumbCheckbox'
98155
</Set>
99156
```
100157

101-
## [List](docs/components/List.md)
102-
**Props:** `{ initial }`
103-
**Args:** `{ list, push, pull, sort, setList }`
158+
### List
159+
**Component Props:** `{ initial }`
160+
**Render Props:** `{ list, push, pull, sort, setList }`
161+
[see docs](docs/components/List.md)
104162

105163
```jsx
106164
<List initial={['react', 'babel']}>
@@ -117,9 +175,64 @@ import Checkbox from './MyDumbCheckbox'
117175
</List>
118176
```
119177
120-
## [Bind](docs/components/Bind.md)
121-
**Props:** `{ initial, getter }`
122-
**Args:** `{ value, setValue, bind }`
178+
## Feedback Containers
179+
180+
It's like css pseudo-selectors, but in js :)
181+
182+
### Hover
183+
**Component Props:** `{ }`
184+
**Render Props:** `{ isHover, bindHover }`
185+
[see docs](docs/components/Hover.md)
186+
187+
```jsx
188+
<Hover>
189+
{({ isHover, bindHover }) => (
190+
<div {...bindHover}>
191+
You are {isHover ? 'hovering' : 'not hovering'} this div.
192+
</div>
193+
)}
194+
</Hover>
195+
```
196+
197+
### Active
198+
**Component Props:** `{ }`
199+
**Render Props:** `{ isActive, bindActive }`
200+
[see docs](docs/components/Active.md)
201+
202+
```jsx
203+
<Active>
204+
{({ isActive, bindActive }) => (
205+
<div {...bindActive}>
206+
You are {isActive ? 'clicking' : 'not clicking'} this div.
207+
</div>
208+
)}
209+
</Active>
210+
```
211+
212+
### Focus
213+
**Component Props:** `{ }`
214+
**Render Props:** `{ isFocus, bindFocus }`
215+
[see docs](docs/components/Focus.md)
216+
217+
```jsx
218+
<Focus>
219+
{({ isFocus, bindFocus }) => (
220+
<div>
221+
<input {...bindFocus} placeholder="Focus me" />
222+
<div>You are {isFocus ? 'focusing' : 'not focusing'} the input.</div>
223+
</div>
224+
)}
225+
</Focus>
226+
```
227+
228+
## Form Containers
229+
230+
**Note:** *v1.0 will have more powerful form-related components, stay tuned!*
231+
232+
### Bind
233+
**Component Props:** `{ initial }`
234+
**Render Props:** `{ value, setValue, bind }`
235+
[see docs](docs/components/Bind.md)
123236
124237
```jsx
125238
<Bind initial="hello world">
@@ -132,22 +245,47 @@ import Checkbox from './MyDumbCheckbox'
132245
</Bind>
133246
```
134247
135-
## [Compose](docs/components/Compose.md)
136-
**Props:** `{ states }`
137-
**Args:** *depends on passed states*
138-
139-
For an example, see below.
248+
### Form
249+
**Component Props:** `{ initial }`
250+
**Render Props:** `{ input }`
251+
[see docs](docs/components/Form.md)
140252
253+
```jsx
254+
<Form initial={{ subject: '', message: '' }}>
255+
{({ input }) => {
256+
const subject = input('subject')
257+
const message = input('message')
258+
259+
return (
260+
<div>
261+
<ControlledInput
262+
placeholder="Subject"
263+
{...subject.bind}
264+
/>
265+
<ControlledTextArea
266+
placeholder="Message"
267+
{...message.bind}
268+
/>
269+
<Submit>Send</Submit>
270+
271+
{/*
272+
input(id) => { bind, setValue, value }
273+
*/}
274+
</div>
275+
)
276+
}
277+
</Form>
278+
```
141279
142280
# Composing Components
143281
144-
If you want to merge two of more components functionalities, you can compose they.
282+
If you want to merge two of more components functionalities, you can compose they in a single one.
145283
For complete guide [see Compose docs](docs/components/Compose.md)
146284
147285
```jsx
148286
import { compose } from 'react-powerplug'
149287

150-
const ToggleCounter = compose(<Toggle initial={true} />, <Counter initial={2} />)
288+
const ToggleCounter = compose(Toggle, Counter)
151289

152290
<ToggleCounter>
153291
{({ count, inc, dec, on, toggle }) => (
@@ -161,27 +299,36 @@ const ToggleCounter = compose(<Toggle initial={true} />, <Counter initial={2} />
161299
/>
162300
)}
163301
</ToggleCounter>
164-
```
302+
```
303+
304+
If you need to pass props, especially for `initial`, just pass a created element. Internals this will be cloned.
305+
306+
```jsx
307+
const ToggleCounter = compose(<Toggle initial={false} />, <Counter initial={2} />)
308+
309+
// or just mix it
310+
const ToggleCounter = compose(Toggle, <Counter initial={3} />)
311+
```
165312
166313
Also, you can use a built-in Compose component and pass components on `states` prop
167314
168315
```jsx
169316
import { Compose } from 'react-powerplug'
170317

171-
<Compose states={[<Toggle initial={true} />, <Counter initial={2} />]}>
318+
<Compose states={[Toggle, Counter]}>
172319
{({ on, toggle, count, inc, dec }) => (
173320
<ProductCard {...} />
174321
)}
175322
</Compose>
176323
```
177324
178-
It is the same to do this:
325+
Behind the scenes, that's what happens:
179326
180327
```jsx
181-
<Counter initial={2}>
328+
<Counter /* passed props */>
182329
{({ count, inc, dec }) => (
183-
<Toggle initial={true}>
184-
{({ on, toggle }) => (
330+
<Toggle /* passed props */>
331+
{({ on, toggle }) => (s
185332
<ProductCard
186333
{...productInfo}
187334
isFavorited={on}
@@ -196,7 +343,12 @@ It is the same to do this:
196343
</Counter>
197344
```
198345
199-
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.
346+
Because of that, 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.
347+
348+
# CodeSandbox examples
349+
350+
[Using Toggle in a Checkbox](https://codesandbox.io/s/jp890p2x7w)
351+
[Using State in a Pagination](https://codesandbox.io/s/8x9m4893l2)
200352
201353
# Install
202354
@@ -217,4 +369,4 @@ exposed as `ReactPowerPlug`
217369
# Contribute
218370
219371
You can help improving this project sending PRs and helping with issues.
220-
Also you ping me at [Twitter](http://twitter.com/renatorib_)
372+
Also you can ping me at [Twitter](http://twitter.com/renatorib_)

docs/README.md

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)