Skip to content

Commit 132b5ea

Browse files
authored
Change base component to Value (#149)
`<State />` component has too much own logic which makes `State` based components more complex with additional `set` and `onChangeProp` helpers. In this diff I reimplemented `<Value />` as class and `<State />` and another components as `Value` based. This reduced bundle size with ~0.8kb (parsed) and significantly simplified components implementation.
1 parent 81f8592 commit 132b5ea

21 files changed

+169
-211
lines changed

.size-snapshot.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
{
22
"dist/react-powerplug.umd.js": {
3-
"bundled": 22187,
4-
"minified": 8780,
5-
"gzipped": 2415
3+
"bundled": 20373,
4+
"minified": 8144,
5+
"gzipped": 2218
66
},
77
"dist/react-powerplug.cjs.js": {
8-
"bundled": 20000,
9-
"minified": 10012,
10-
"gzipped": 2407
8+
"bundled": 18338,
9+
"minified": 9263,
10+
"gzipped": 2228
1111
},
1212
"dist/react-powerplug.esm.js": {
13-
"bundled": 19370,
14-
"minified": 9474,
15-
"gzipped": 2267,
13+
"bundled": 17708,
14+
"minified": 8725,
15+
"gzipped": 2092,
1616
"treeshaked": {
1717
"rollup": {
18-
"code": 204,
19-
"import_statements": 204
18+
"code": 197,
19+
"import_statements": 197
2020
},
2121
"webpack": {
22-
"code": 1506
22+
"code": 1495
2323
}
2424
}
2525
}

src/components/Active.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import onChangeProp from '../utils/onChangeProp'
54

65
const Active = ({ onChange, ...props }) => (
7-
<State
8-
initial={{ active: false }}
9-
onChange={onChangeProp(onChange, 'active')}
10-
>
11-
{({ state, setState }) =>
6+
<Value initial={false} onChange={onChange}>
7+
{({ value, set }) =>
128
renderProps(props, {
13-
active: state.active,
9+
active: value,
1410
bind: {
15-
onMouseDown: () => setState({ active: true }),
16-
onMouseUp: () => setState({ active: false }),
11+
onMouseDown: () => set(true),
12+
onMouseUp: () => set(false),
1713
},
1814
})
1915
}
20-
</State>
16+
</Value>
2117
)
2218

2319
export default Active

src/components/Counter.js

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import set from '../utils/set'
5-
import onChangeProp from '../utils/onChangeProp'
64

7-
const add = value => state => ({
8-
count: state.count + value,
9-
})
5+
const add = diff => value => value + diff
106

117
const Counter = ({ initial = 0, onChange, ...props }) => (
12-
<State
13-
initial={{ count: initial }}
14-
onChange={onChangeProp(onChange, 'count')}
15-
>
16-
{({ state, setState }) =>
8+
<Value initial={initial} onChange={onChange}>
9+
{({ value, set }) =>
1710
renderProps(props, {
18-
count: state.count,
19-
inc: () => setState(add(1)),
20-
dec: () => setState(add(-1)),
21-
incBy: value => setState(add(value)),
22-
decBy: value => setState(add(-value)),
23-
set: value => setState(s => ({ count: set(value, s.count) })),
11+
count: value,
12+
inc: () => set(add(1)),
13+
dec: () => set(add(-1)),
14+
incBy: value => set(add(value)),
15+
decBy: value => set(add(-value)),
16+
set: value => set(value),
2417
})
2518
}
26-
</State>
19+
</Value>
2720
)
2821

2922
export default Counter

src/components/Focus.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import onChangeProp from '../utils/onChangeProp'
54

65
const Focus = ({ onChange, ...props }) => (
7-
<State
8-
initial={{ focused: false }}
9-
onChange={onChangeProp(onChange, 'focused')}
10-
>
11-
{({ state, setState }) =>
6+
<Value initial={false} onChange={onChange}>
7+
{({ value, set }) =>
128
renderProps(props, {
13-
focused: state.focused,
9+
focused: value,
1410
bind: {
15-
onFocus: () => setState({ focused: true }),
16-
onBlur: () => setState({ focused: false }),
11+
onFocus: () => set(true),
12+
onBlur: () => set(false),
1713
},
1814
})
1915
}
20-
</State>
16+
</Value>
2117
)
2218

2319
export default Focus

src/components/FocusManager.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import onChangeProp from '../utils/onChangeProp'
54

65
const FocusManager = ({ onChange, ...props }) => {
76
let canBlur = true
87
return (
9-
<State
10-
initial={{ focused: false }}
11-
onChange={onChangeProp(onChange, 'focused')}
12-
>
13-
{({ state, setState }) =>
8+
<Value initial={false} onChange={onChange}>
9+
{({ value, set }) =>
1410
renderProps(props, {
15-
focused: state.focused,
11+
focused: value,
1612
blur: () => {
17-
if (state.focused) {
13+
if (value) {
1814
document.activeElement.blur()
1915
}
2016
},
2117
bind: {
2218
tabIndex: -1,
2319
onBlur: () => {
2420
if (canBlur) {
25-
setState({ focused: false })
21+
set(false)
2622
}
2723
},
2824
onFocus: () => {
29-
setState({ focused: true })
25+
set(true)
3026
},
3127
onMouseDown: () => {
3228
canBlur = false
@@ -37,7 +33,7 @@ const FocusManager = ({ onChange, ...props }) => {
3733
},
3834
})
3935
}
40-
</State>
36+
</Value>
4137
)
4238
}
4339

src/components/Form.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import set from '../utils/set'
54

65
const Form = ({ initial = {}, onChange, ...props }) => (
7-
<State initial={{ ...initial }} onChange={onChange}>
8-
{({ state, setState }) =>
6+
<Value initial={{ ...initial }} onChange={onChange}>
7+
{({ value: values, set }) =>
98
renderProps(props, {
10-
values: { ...state },
9+
values,
1110
input: id => {
12-
const value = state[id] || ''
13-
const setValue = value => setState({ [id]: value })
11+
const value = values[id] || ''
12+
const setValue = updater =>
13+
typeof updater === 'function'
14+
? set(prev => ({ ...prev, [id]: updater(prev[id]) }))
15+
: set({ ...values, [id]: updater })
1416

1517
return {
18+
value,
19+
set: setValue,
1620
bind: {
17-
onChange: event => setValue(event.target.value),
1821
value,
22+
onChange: event => setValue(event.target.value),
1923
},
20-
set: value => setState(s => ({ [id]: set(value, s.value) })),
21-
value,
2224
}
2325
},
2426
})
2527
}
26-
</State>
28+
</Value>
2729
)
2830

2931
export default Form

src/components/Hover.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import onChangeProp from '../utils/onChangeProp'
54

65
const Hover = ({ onChange, ...props }) => (
7-
<State
8-
initial={{ hovered: false }}
9-
onChange={onChangeProp(onChange, 'hovered')}
10-
>
11-
{({ state, setState }) =>
6+
<Value initial={false} onChange={onChange}>
7+
{({ value, set }) =>
128
renderProps(props, {
13-
hovered: state.hovered,
9+
hovered: value,
1410
bind: {
15-
onMouseEnter: () => setState({ hovered: true }),
16-
onMouseLeave: () => setState({ hovered: false }),
11+
onMouseEnter: () => set(true),
12+
onMouseLeave: () => set(false),
1713
},
1814
})
1915
}
20-
</State>
16+
</Value>
2117
)
2218

2319
export default Hover

src/components/Input.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import set from '../utils/set'
5-
import onChangeProp from '../utils/onChangeProp'
64

75
const Input = ({ initial = '', onChange, ...props }) => (
8-
<State
9-
initial={{ value: initial }}
10-
onChange={onChangeProp(onChange, 'value')}
11-
>
12-
{({ state, setState }) =>
6+
<Value initial={initial} onChange={onChange}>
7+
{({ value, set }) =>
138
renderProps(props, {
9+
value,
10+
set: value => set(value),
1411
bind: {
15-
onChange: event => setState({ value: event.target.value }),
16-
value: state.value,
12+
value,
13+
onChange: event => set(event.target.value),
1714
},
18-
set: value => setState(s => ({ value: set(value, s.value) })),
19-
value: state.value,
2015
})
2116
}
22-
</State>
17+
</Value>
2318
)
2419

2520
export default Input

src/components/List.js

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
4-
import set from '../utils/set'
5-
import onChangeProp from '../utils/onChangeProp'
64

75
const complement = fn => (...args) => !fn(...args)
86

97
const List = ({ initial = [], onChange, ...props }) => (
10-
<State initial={{ list: initial }} onChange={onChangeProp(onChange, 'list')}>
11-
{({ state, setState }) =>
8+
<Value initial={initial} onChange={onChange}>
9+
{({ value, set }) =>
1210
renderProps(props, {
13-
list: state.list,
14-
first: () => state.list[0],
15-
last: () => state.list[Math.max(0, state.list.length - 1)],
16-
set: list => setState(s => ({ list: set(list, s.list) })),
17-
push: (...values) => setState(s => ({ list: [...s.list, ...values] })),
18-
pull: predicate =>
19-
setState(s => ({ list: s.list.filter(complement(predicate)) })),
20-
sort: compareFn =>
21-
setState(s => ({ list: [...s.list].sort(compareFn) })),
11+
list: value,
12+
first: () => value[0],
13+
last: () => value[Math.max(0, value.length - 1)],
14+
set: list => set(list),
15+
push: (...values) => set(list => [...list, ...values]),
16+
pull: predicate => set(list => list.filter(complement(predicate))),
17+
sort: compareFn => set(list => [...list].sort(compareFn)),
2218
})
2319
}
24-
</State>
20+
</Value>
2521
)
2622

2723
export default List

src/components/Map.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import * as React from 'react'
2-
import State from './State'
2+
import Value from './Value'
33
import renderProps from '../utils/renderProps'
44

55
const Map = ({ initial = {}, onChange, ...props }) => (
6-
<State initial={{ ...initial }} onChange={onChange}>
7-
{({ state, setState }) =>
6+
<Value initial={{ ...initial }} onChange={onChange}>
7+
{({ value, set }) =>
88
renderProps(props, {
9-
values: state,
10-
set: (key, value) => setState({ [key]: value }),
11-
over: (key, fn) => setState(s => ({ [key]: fn(s[key]) })),
12-
get: key => state[key],
9+
values: value,
10+
set: (key, value) => set(prev => ({ ...prev, [key]: value })),
11+
over: (key, fn) => set(prev => ({ ...prev, [key]: fn(prev[key]) })),
12+
get: key => value[key],
1313
})
1414
}
15-
</State>
15+
</Value>
1616
)
1717

1818
export default Map

0 commit comments

Comments
 (0)