-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCounter.js
90 lines (69 loc) · 1.83 KB
/
Counter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React, { PropTypes } from 'react';
import { recordOf } from 'react-immutable-proptypes';
import { Record } from 'immutable';
import { Union, Maybe } from 'results';
import Spindle, { Update } from '../../spindle';
const Model = Record({
value: 0,
min: -Infinity,
max: Infinity,
});
const modelType = recordOf({
value: PropTypes.number.isRequired,
min: PropTypes.number.isRequired,
max: PropTypes.number.isRequired,
});
const cbTypes = {
onChange: PropTypes.number.isRequired,
};
const Action = Union({
Increment: null,
Decrement: null,
});
// this is just a helper, it's not a special funciton
const constrain = model => {
const { value, min, max } = model.toObject();
return model.set('value', Math.max(min, Math.min(max, value)));
}
const init = props =>
propsUpdate(props, Model());
const propsUpdate = ({ min = -Infinity, max = Infinity }, model) => {
const updated = constrain(model.merge({ min, max }));
return Update({
model: updated,
cb: { onChange: model.value },
});
};
const update = (action, model) => Action.match(action, {
Increment: () => {
const newModel = constrain(model.update('value', v => v + 1));
return Update({
model: newModel,
cb: { onChange: newModel.value },
});
},
Decrement: () => {
const newModel = constrain(model.update('value', v => v - 1));
return Update({
model: newModel,
cb: { onChange: newModel.value },
});
},
});
const view = (model, dispatch) => (
<p>
<button
disabled={model.value <= model.min}
onClick={dispatch.Decrement}>
-
</button>
{model.value}
<button
disabled={model.value >= model.max}
onClick={dispatch.Increment}>
+
</button>
</p>
);
export default Spindle('Counter',
{ Action, init, propsUpdate, update, modelType, view, cbTypes });