diff --git a/README.md b/README.md index 9221ae7..62fda39 100644 --- a/README.md +++ b/README.md @@ -50,21 +50,26 @@ const customer = form.mutators.pop('customers') -* [Mutators](#mutators) - * [`form.mutators.insert(name: string, index:number, value: any) => undefined`](#formmutatorsinsertname-string-indexnumber-value-any--undefined) - * [`form.mutators.move(name: string, from: number, to: number) => undefined`](#formmutatorsmovename-string-from-number-to-number--undefined) - * [`form.mutators.pop(name: string) => any`](#formmutatorspopname-string--any) - * [`form.mutators.push(name: string, value: any) => void`](#formmutatorspushname-string-value-any--void) - * [`form.mutators.remove(name: string, index: number) => any`](#formmutatorsremovename-string-index-number--any) - * [`form.mutators.shift(name: string) => any`](#formmutatorsshiftname-string--any) - * [`form.mutators.swap(name: string, indexA: number, indexB: number) => void`](#formmutatorsswapname-string-indexa-number-indexb-number--void) - * [`form.mutators.unshift(name: string, value: any) => void`](#formmutatorsunshiftname-string-value-any--void) +- [🏁 Final Form Arrays](#%F0%9F%8F%81-final-form-arrays) + - [Installation](#installation) + - [Usage](#usage) + - [Table of Contents](#table-of-contents) + - [Mutators](#mutators) + - [`form.mutators.insert(name: string, index: number, value: any) => undefined`](#formmutatorsinsertname-string-index-number-value-any--undefined) + - [`form.mutators.move(name: string, from: number, to: number) => undefined`](#formmutatorsmovename-string-from-number-to-number--undefined) + - [`form.mutators.pop(name: string) => any`](#formmutatorspopname-string--any) + - [`form.mutators.push(name: string, value: any) => void`](#formmutatorspushname-string-value-any--void) + - [`form.mutators.remove(name: string, index: number) => any`](#formmutatorsremovename-string-index-number--any) + - [`form.mutators.shift(name: string) => any`](#formmutatorsshiftname-string--any) + - [`form.mutators.swap(name: string, indexA: number, indexB: number) => void`](#formmutatorsswapname-string-indexa-number-indexb-number--void) + - [`form.mutators.update(name: string, index: number, value: any) => void`](#formmutatorsupdatename-string-index-number-value-any--void) + - [`form.mutators.unshift(name: string, value: any) => void`](#formmutatorsunshiftname-string-value-any--void) ## Mutators -### `form.mutators.insert(name: string, index:number, value: any) => undefined` +### `form.mutators.insert(name: string, index: number, value: any) => undefined` Inserts a value into the specified index of the array field. @@ -93,6 +98,10 @@ Removes a value from the beginning of the array field. Returns the value. Swaps the position of two values in the array field. +### `form.mutators.update(name: string, index: number, value: any) => void` + +Updates a value of the specified index of the array field. + ### `form.mutators.unshift(name: string, value: any) => void` Inserts a value onto the beginning of the array field. diff --git a/src/index.d.test.ts b/src/index.d.test.ts index cf0610d..1b7d4a2 100644 --- a/src/index.d.test.ts +++ b/src/index.d.test.ts @@ -21,4 +21,5 @@ mutators.push('customers', { firstName: '', lastName: '' }) const removed = mutators.remove('customers', 0) const shifted = mutators.shift('customers') mutators.swap('customers', 0, 1) +mutators.update('customers', 0, { firstName: '', lastName: '' }) mutators.unshift('customers', { firstName: '', lastName: '' }) diff --git a/src/index.d.ts b/src/index.d.ts index b80b48b..b3e9f3d 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -7,6 +7,7 @@ export const push: Mutator export const remove: Mutator export const shift: Mutator export const swap: Mutator +export const update: Mutator export const unshift: Mutator export interface DefaultType { @@ -17,6 +18,7 @@ export interface DefaultType { remove: Mutator shift: Mutator swap: Mutator + update: Mutator unshift: Mutator } @@ -32,5 +34,6 @@ export interface Mutators { remove: (name: string, index: number) => any shift: (name: string) => any swap: (name: string, indexA: number, indexB: number) => void + update: (name: string, index: number, value: any) => void unshift: (name: string, value: any) => void } diff --git a/src/index.js b/src/index.js index d170667..26fadaf 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,7 @@ import remove from './remove' import shift from './shift' import swap from './swap' import unshift from './unshift' +import update from './update' const mutators: { [string]: Mutator } = { insert, @@ -17,6 +18,7 @@ const mutators: { [string]: Mutator } = { remove, shift, swap, - unshift + unshift, + update } export default mutators diff --git a/src/index.js.flow b/src/index.js.flow index 23cc240..08cec50 100644 --- a/src/index.js.flow +++ b/src/index.js.flow @@ -14,5 +14,6 @@ export type Mutators = { remove: (name: string, index: number) => any, shift: (name: string) => any, swap: (name: string, indexA: number, indexB: number) => void, + update: (name: string, index: number, value: any) => void, unshift: (name: string, value: any) => void } diff --git a/src/update.js b/src/update.js new file mode 100644 index 0000000..cc2168f --- /dev/null +++ b/src/update.js @@ -0,0 +1,22 @@ +// @flow +import type { MutableState, Mutator, Tools } from 'final-form' + +type Args = [string, number, any] + +const update: Mutator = ( + [name, index, value]: Args, + state: MutableState, + { changeValue }: Tools +) => { + changeValue( + state, + name, + (array: ?(any[])): any[] => { + const copy = [...(array || [])] + copy.splice(index, 1, value) + return copy + } + ) +} + +export default update diff --git a/src/update.test.js b/src/update.test.js new file mode 100644 index 0000000..0084e1b --- /dev/null +++ b/src/update.test.js @@ -0,0 +1,38 @@ +import update from './update' + +describe('update', () => { + const getOp = (index, value) => { + const changeValue = jest.fn() + update(['foo', index, value], {}, { changeValue }) + return changeValue.mock.calls[0][2] + } + + it('should call changeValue once', () => { + const changeValue = jest.fn() + const state = {} + const result = update(['foo', 0, 'bar'], state, { changeValue }) + expect(result).toBeUndefined() + expect(changeValue).toHaveBeenCalled() + expect(changeValue).toHaveBeenCalledTimes(1) + expect(changeValue.mock.calls[0][0]).toBe(state) + expect(changeValue.mock.calls[0][1]).toBe('foo') + expect(typeof changeValue.mock.calls[0][2]).toBe('function') + }) + + it('should treat undefined like an empty array', () => { + const op = getOp(0, 'bar') + const result = op(undefined) + expect(Array.isArray(result)).toBe(true) + expect(result.length).toBe(1) + expect(result[0]).toBe('bar') + }) + + it('should update value of the specified index', () => { + const op = getOp(1, 'd') + const array = ['a', 'b', 'c'] + const result = op(array) + expect(result).not.toBe(array) // copied + expect(Array.isArray(result)).toBe(true) + expect(result).toEqual(['a', 'd', 'c']) + }) +})