Skip to content

Commit 857771e

Browse files
authored
Added types and docs for new multi-update api (#9)
* Added types and docs for new multi-update api * Switched API back to the way it was originally written
1 parent 6c79245 commit 857771e

File tree

9 files changed

+4764
-1196
lines changed

9 files changed

+4764
-1196
lines changed

.flowconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ dist/.*
77

88
[options]
99
esproposal.decorators=ignore
10-
unsafe.enable_getters_and_setters=true

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ A calculation to perform
119119

120120
A pattern to match a field with.
121121

122-
### `Updates: { [FieldName]: (value: any, allValues: Object) => any }`
122+
### `Updates: UpdatesByName | UpdatesForAll`
123123

124-
Updates to make on other fields.
124+
Either an object of updater functions or a function that generates updates for multiple fields.
125+
126+
### `UpdatesByName: { [FieldName]: (value: any, allValues: Object) => any }`
127+
128+
Updater functions for each calculated field.
129+
130+
### `UpdatesForAll: (value: any, field: string, allValues: Object) => { [FieldName]: any }`
131+
132+
Takes the value and name of the field that just changed, as well as all the values, and returns an object of fields and new values.

package-lock.json

Lines changed: 4627 additions & 1159 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-scripts.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ module.exports = {
5555
description: 'Generates table of contents in README',
5656
script: 'doctoc README.md'
5757
},
58-
copyTypes: npsUtils.copy('src/*.js.flow dist'),
58+
copyTypes: series(
59+
npsUtils.copy('src/*.js.flow dist'),
60+
npsUtils.copy(
61+
'dist/index.js.flow dist --rename="final-form-calculate.cjs.js.flow"'
62+
),
63+
npsUtils.copy(
64+
'dist/index.js.flow dist --rename="final-form-calculate.es.js.flow"'
65+
)
66+
),
5967
lint: {
6068
description: 'lint the entire project',
6169
script: 'eslint .'

package.json

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,39 @@
2424
},
2525
"homepage": "https://github.com/final-form/final-form-calculate#readme",
2626
"devDependencies": {
27-
"babel-eslint": "^8.0.3",
28-
"babel-jest": "^22.0.4",
27+
"babel-eslint": "^8.2.2",
28+
"babel-jest": "^22.4.1",
2929
"babel-plugin-external-helpers": "^6.22.0",
3030
"babel-plugin-transform-flow-strip-types": "^6.22.0",
3131
"babel-preset-env": "^1.6.1",
3232
"babel-preset-stage-2": "^6.24.1",
33-
"bundlesize": "^0.15.3",
34-
"doctoc": "^1.3.0",
35-
"eslint": "^4.11.0",
36-
"eslint-config-react-app": "^2.0.1",
33+
"bundlesize": "^0.16.0",
34+
"doctoc": "^1.3.1",
35+
"eslint": "^4.19.0",
36+
"eslint-config-react-app": "^2.1.0",
3737
"eslint-plugin-babel": "^4.1.2",
38-
"eslint-plugin-flowtype": "^2.37.0",
39-
"eslint-plugin-import": "^2.8.0",
40-
"eslint-plugin-jsx-a11y": "^6.0.2",
41-
"eslint-plugin-react": "^7.5.1",
42-
"final-form": "^1.3.0",
38+
"eslint-plugin-flowtype": "^2.46.1",
39+
"eslint-plugin-import": "^2.9.0",
40+
"eslint-plugin-jsx-a11y": "^6.0.3",
41+
"eslint-plugin-react": "^7.7.0",
42+
"final-form": "^4.3.1",
4343
"flow": "^0.2.3",
44-
"flow-bin": "^0.60.1",
44+
"flow-bin": "^0.68.0",
45+
"glow": "^1.2.2",
4546
"husky": "^0.14.3",
46-
"jest": "^22.0.5",
47-
"lint-staged": "^6.0.0",
48-
"nps": "^5.7.1",
47+
"jest": "^22.4.2",
48+
"lint-staged": "^7.0.0",
49+
"nps": "^5.8.2",
4950
"nps-utils": "^1.5.0",
50-
"prettier": "^1.8.2",
51-
"prettier-eslint-cli": "^4.4.2",
52-
"rollup": "^0.53.4",
53-
"rollup-plugin-babel": "^3.0.2",
54-
"rollup-plugin-commonjs": "^8.2.6",
51+
"prettier": "^1.11.1",
52+
"prettier-eslint-cli": "^4.7.1",
53+
"rollup": "^0.57.1",
54+
"rollup-plugin-babel": "^3.0.3",
55+
"rollup-plugin-commonjs": "^9.1.0",
5556
"rollup-plugin-flow": "^1.1.1",
56-
"rollup-plugin-node-resolve": "^3.0.0",
57+
"rollup-plugin-node-resolve": "^3.3.0",
5758
"rollup-plugin-replace": "^2.0.0",
58-
"rollup-plugin-uglify": "^2.0.1"
59+
"rollup-plugin-uglify": "^3.0.0"
5960
},
6061
"peerDependencies": {
6162
"final-form": ">=1.3.0"

rollup.config.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ if (es) {
3232
throw new Error('no format specified. --environment FORMAT:xxx')
3333
}
3434

35-
// eslint-disable-next-line no-nested-ternary
36-
const exports = !es ? 'default' : 'named'
37-
3835
export default {
39-
name: 'final-form-calculate',
4036
input: 'src/index.js',
41-
output,
42-
exports,
37+
output: Object.assign(
38+
{
39+
name: 'final-form-calculate',
40+
exports: 'named'
41+
},
42+
output
43+
),
4344
external: [],
4445
plugins: [
4546
resolve({ jsnext: true, main: true }),

src/decorator.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ const createDecorator = (...calculations: Calculation[]): Decorator => (
1111
({ values }) => {
1212
form.batch(() => {
1313
const runUpdates = (field: string, updates: Updates) => {
14-
const next = getIn(values, field)
15-
const previous = getIn(previousValues, field)
14+
const next = values && getIn(values, field)
15+
const previous = previousValues && getIn(previousValues, field)
1616
if (next !== previous) {
1717
if (typeof updates === 'function') {
1818
const results = updates(next, field, values)

src/decorator.test.js

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ describe('decorator', () => {
205205
expect(spy.mock.calls[6][0].values).toEqual({ items: [3, 4, 5], total: 12 })
206206
})
207207

208-
it('should allow seperate array summing', () => {
208+
it('should allow separate array summing', () => {
209209
const form = createForm({ onSubmit: onSubmitMock })
210210
const spy = jest.fn()
211211
const total = jest.fn()
@@ -278,4 +278,81 @@ describe('decorator', () => {
278278
list: [{ items: [3, 4, 5], total: 12 }]
279279
})
280280
})
281+
282+
it('should notify form subscribers of updated values', () => {
283+
const form = createForm({ onSubmit: onSubmitMock })
284+
const spy = jest.fn()
285+
const minimum = jest.fn()
286+
const maximum = jest.fn()
287+
const calcMax = jest.fn((minimumValue, allValues) =>
288+
Math.max(minimumValue || 0, allValues.maximum || 0)
289+
)
290+
const calcMin = jest.fn((maximumValue, allValues) =>
291+
Math.min(maximumValue || 0, allValues.minimum || 0)
292+
)
293+
form.subscribe(spy, { values: true })
294+
form.registerField('minimum', minimum, { value: true })
295+
form.registerField('maximum', maximum, { value: true })
296+
const decorator = createDecorator(
297+
{
298+
field: 'minimum', // when minimum changes...
299+
updates: {
300+
// ...update maximum to the result of this function
301+
maximum: calcMax
302+
}
303+
},
304+
{
305+
field: 'maximum', // when maximum changes...
306+
updates: {
307+
// update minimum to the result of this function
308+
minimum: calcMin
309+
}
310+
}
311+
)
312+
decorator(form)
313+
314+
expect(spy).toHaveBeenCalled()
315+
expect(spy).toHaveBeenCalledTimes(1)
316+
expect(spy.mock.calls[0][0].values).toEqual({})
317+
318+
expect(minimum).toHaveBeenCalled()
319+
expect(minimum).toHaveBeenCalledTimes(1)
320+
expect(minimum.mock.calls[0][0].value).toBeUndefined()
321+
322+
expect(maximum).toHaveBeenCalled()
323+
expect(maximum).toHaveBeenCalledTimes(1)
324+
expect(maximum.mock.calls[0][0].value).toBeUndefined()
325+
326+
expect(calcMax).not.toHaveBeenCalled()
327+
expect(calcMin).not.toHaveBeenCalled()
328+
329+
// change minimum
330+
form.change('minimum', 3)
331+
332+
expect(calcMax).toHaveBeenCalled()
333+
expect(calcMax).toHaveBeenCalledTimes(1)
334+
expect(calcMin).toHaveBeenCalled()
335+
expect(calcMin).toHaveBeenCalledTimes(1)
336+
337+
expect(spy).toHaveBeenCalledTimes(3)
338+
expect(spy.mock.calls[1][0].values).toEqual({ minimum: 3 })
339+
expect(spy.mock.calls[2][0].values).toEqual({ minimum: 3, maximum: 3 })
340+
341+
// raise maximum higher
342+
form.change('maximum', 5)
343+
344+
expect(calcMin).toHaveBeenCalledTimes(2)
345+
346+
expect(spy).toHaveBeenCalledTimes(4)
347+
expect(spy.mock.calls[3][0].values).toEqual({ minimum: 3, maximum: 5 })
348+
349+
form.change('maximum', 2)
350+
351+
expect(calcMin).toHaveBeenCalledTimes(3)
352+
expect(calcMax).toHaveBeenCalledTimes(2)
353+
354+
expect(spy).toHaveBeenCalledTimes(6)
355+
expect(spy.mock.calls[4][0].values).toEqual({ minimum: 3, maximum: 2 })
356+
expect(spy.mock.calls[5][0].values).toEqual({ minimum: 2, maximum: 2 })
357+
})
281358
})

src/types.js.flow

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
// @flow
22
type FieldName = string
33
export type FieldPattern = FieldName | RegExp
4-
export type Updates = {
5-
[FieldName]: (value: any, allValues: Object) => any
4+
export type UpdatesByName = {
5+
[FieldName]: (value: any, allValues: ?Object) => any
66
}
7+
export type UpdatesForAll = (
8+
value: any,
9+
field: string,
10+
allValues: ?Object
11+
) => { [FieldName]: any }
12+
export type Updates = UpdatesByName | UpdatesForAll
713

814
export type Calculation = {
915
field: FieldPattern,

0 commit comments

Comments
 (0)