diff --git a/.all-contributorsrc b/.all-contributorsrc index 03c818670..a5dd02a27 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -123,10 +123,10 @@ ] }, { - "login": "probablyup", + "login": "quantizor", "name": "Evan Jacobs", "avatar_url": "https://avatars.githubusercontent.com/u/570070?v=4", - "profile": "https://probablyup.com", + "profile": "https://quantizor.dev", "contributions": [ "question", "code", diff --git a/.changeset/spotty-poets-bathe.md b/.changeset/spotty-poets-bathe.md new file mode 100644 index 000000000..8228beca7 --- /dev/null +++ b/.changeset/spotty-poets-bathe.md @@ -0,0 +1,5 @@ +--- +'formik': patch +--- + +Value of setFieldValue can be a function that takes previous field value diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b948465e4..605db9d96 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,6 @@ # Learn how to add code owners here: # https://help.github.com/en/articles/about-code-owners -* @jaredpalmer @probablyup -/docs/ @jaredpalmer @probablyup -/examples/ @jaredpalmer @probablyup \ No newline at end of file +* @jaredpalmer @quantizor +/docs/ @jaredpalmer @quantizor +/examples/ @jaredpalmer @quantizor \ No newline at end of file diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b58951398..1193bd4d0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -69,8 +69,8 @@ git remote add upstream https://github.com/formik/formik.git 3. Synchronize your local `next` branch with the upstream one: ```sh -git checkout master -git pull upstream master +git checkout main +git pull upstream main ``` 4. Install the dependencies with [yarn](https://yarnpkg.com) (npm isn't supported): @@ -122,7 +122,7 @@ the results. If any of them fail, refer to [Checks and how to fix them](#checks- Make sure the following is true: -- The branch is targeted at `master` for ongoing development. We do our best to keep `master` in good shape, with all tests passing. Code that lands in `master` must be compatible with the latest stable release. It may contain additional features, but no breaking changes. We should be able to release a new minor version from the tip of `master` at any time. +- The branch is targeted at `main` for ongoing development. We do our best to keep `main` in good shape, with all tests passing. Code that lands in `main` must be compatible with the latest stable release. It may contain additional features, but no breaking changes. We should be able to release a new minor version from the tip of `main` at any time. - If a feature is being added: - If the result was already achievable with the library, explain why this feature needs to be added. - If this is a common use case, consider adding an example to the documentation. diff --git a/.vscode/settings.json b/.vscode/settings.json index e56b4cfc8..11a40855a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,6 @@ "typescript.tsdk": "node_modules/typescript/lib", "editor.formatOnSave": false, "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, } diff --git a/docs/api/fastfield.md b/docs/api/fastfield.md index cd9d7b1bf..32fa48ee3 100644 --- a/docs/api/fastfield.md +++ b/docs/api/fastfield.md @@ -57,7 +57,8 @@ const Basic = () => ( alert(JSON.stringify(values, null, 2)); }, 500); }} - render={formikProps => ( + > + {formikProps => (
{/** This only updates for changes made to values.firstName, touched.firstName, errors.firstName */} @@ -66,8 +67,8 @@ const Basic = () => ( {/** Updates for all changes because it's from the top-level formikProps which get all updates */} - {form.touched.firstName && form.errors.firstName && ( -
{form.errors.firstName}
+ {formikProps.touched.firstName && formikProps.errors.firstName && ( +
{formikProps.errors.firstName}
)} @@ -105,7 +106,7 @@ const Basic = () => ( and all changes by all s and s */} - {() => ( + {({ field, form, meta }) => (
{/** Works because this is inside @@ -125,7 +126,7 @@ const Basic = () => ( )} - /> +
); ``` diff --git a/docs/api/field.md b/docs/api/field.md index 422493ec6..a2c1002c6 100644 --- a/docs/api/field.md +++ b/docs/api/field.md @@ -102,7 +102,7 @@ Either a React component or the name of an HTML element to render. That is, one - A valid HTML element name - A custom React component -Custom React components will be passed `onChange`, `onBlur`, `name`, and `value` plus any other props passed to directly to ``. +Custom React components will be passed `onChange`, `onBlur`, `name`, and `value` plus any other props passed directly to ``. Default is `'input'` (so an `` is rendered by default) diff --git a/docs/api/formik.md b/docs/api/formik.md index 09c0c159b..9fa07f3a4 100644 --- a/docs/api/formik.md +++ b/docs/api/formik.md @@ -193,7 +193,7 @@ Trigger a form submission. The promise will be rejected if form is invalid. Number of times user tried to submit the form. Increases when [`handleSubmit`](#handlesubmit-e-reactformeventhtmlformelement--void) is called, resets after calling [`handleReset`](#handlereset---void). `submitCount` is readonly computed property and should not be mutated directly. -#### `setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise` +#### `setFieldValue: (field: string, value: React.SetStateAction, shouldValidate?: boolean) => Promise` Set the value of a field imperatively. `field` should match the key of `values` you wish to update. Useful for creating custom input change handlers. Calling this will trigger validation to run if `validateOnChange` is set to `true` (which it is by default). You can also explicitly prevent/skip validation by passing a third argument as `false`. diff --git a/docs/api/useField.md b/docs/api/useField.md index 279060606..e22245ffe 100644 --- a/docs/api/useField.md +++ b/docs/api/useField.md @@ -3,7 +3,7 @@ id: useField title: useField() --- -`useField` is a custom React hook that will automagically help you hook up inputs to Formik. You can and should use it to build your own custom input primitives. There are 2 ways to use it. +`useField` is a React hook used to thread Formik behaviors into arbitrary field components. It provides the greatest amount of flexibility for scenarios where `Field` is inappropriate. There are two ways to use it. ## Example diff --git a/packages/formik-native/CHANGELOG.md b/packages/formik-native/CHANGELOG.md index e3461da1f..e9afbbc85 100644 --- a/packages/formik-native/CHANGELOG.md +++ b/packages/formik-native/CHANGELOG.md @@ -1,5 +1,12 @@ # formik-native +## 2.1.29 + +### Patch Changes + +- Updated dependencies [[`f57ca9b`](https://github.com/jaredpalmer/formik/commit/f57ca9bc5ee3842d50f74f39b3fb36a744b55ae8)]: + - formik@2.4.6 + ## 2.1.28 ### Patch Changes diff --git a/packages/formik-native/package.json b/packages/formik-native/package.json index 152b5ff8f..7653cce45 100644 --- a/packages/formik-native/package.json +++ b/packages/formik-native/package.json @@ -1,6 +1,6 @@ { "name": "formik-native", - "version": "2.1.28", + "version": "2.1.29", "license": "Apache-2.0", "author": "Jared Palmer ", "repository": "formium/formik", @@ -30,7 +30,7 @@ "react": ">=16.8.0" }, "dependencies": { - "formik": "2.4.5" + "formik": "2.4.6" }, "devDependencies": { "@react-native-community/eslint-config": "^0.0.5", diff --git a/packages/formik/CHANGELOG.md b/packages/formik/CHANGELOG.md index a8cb976cd..a3b24da4d 100644 --- a/packages/formik/CHANGELOG.md +++ b/packages/formik/CHANGELOG.md @@ -1,5 +1,11 @@ # formik +## 2.4.6 + +### Patch Changes + +- [`f57ca9b`](https://github.com/jaredpalmer/formik/commit/f57ca9bc5ee3842d50f74f39b3fb36a744b55ae8) [#3949](https://github.com/jaredpalmer/formik/pull/3949) Thanks [@DeveloperRaj](https://github.com/DeveloperRaj)! - Changing the state inside formik was changing reference of initialValues provided via props, deep cloning the initialvalues will fix it. + ## 2.4.5 ### Patch Changes @@ -28,7 +34,7 @@ ### Patch Changes -- [`96280d3`](https://github.com/jaredpalmer/formik/commit/96280d388eaa0f2e9fb84e7fd2aa45450de3a949) [#3817](https://github.com/jaredpalmer/formik/pull/3817) Thanks [@probablyup](https://github.com/probablyup)! - Updated internal types to support React 18. +- [`96280d3`](https://github.com/jaredpalmer/formik/commit/96280d388eaa0f2e9fb84e7fd2aa45450de3a949) [#3817](https://github.com/jaredpalmer/formik/pull/3817) Thanks [@quantizor](https://github.com/quantizor)! - Updated internal types to support React 18. ## 2.4.1 @@ -36,21 +42,21 @@ - [`2b194c2`](https://github.com/jaredpalmer/formik/commit/2b194c287dc281ec2a8ff691d75c6b798ab5f70c) [#3808](https://github.com/jaredpalmer/formik/pull/3808) Thanks [@NagaiKoki](https://github.com/NagaiKoki)! - fix type of setFieldValue function -* [`708bcb2`](https://github.com/jaredpalmer/formik/commit/708bcb24785f1f8fbb5dfd649de3df4fddf7a113) [#3813](https://github.com/jaredpalmer/formik/pull/3813) Thanks [@probablyup](https://github.com/probablyup)! - Revert `FieldArray` "shouldComponentUpdate" performance optimization. As it turns out, it's a common use case to have JSX controlled via non-Formik state/props inside of `FieldArray`, so it's not safe to cancel re-renders here. +* [`708bcb2`](https://github.com/jaredpalmer/formik/commit/708bcb24785f1f8fbb5dfd649de3df4fddf7a113) [#3813](https://github.com/jaredpalmer/formik/pull/3813) Thanks [@quantizor](https://github.com/quantizor)! - Revert `FieldArray` "shouldComponentUpdate" performance optimization. As it turns out, it's a common use case to have JSX controlled via non-Formik state/props inside of `FieldArray`, so it's not safe to cancel re-renders here. -- [`187e47d`](https://github.com/jaredpalmer/formik/commit/187e47de0c4289cb279e25d69f8172cfa14369d2) [#3815](https://github.com/jaredpalmer/formik/pull/3815) Thanks [@probablyup](https://github.com/probablyup)! - Revert Yup transform support for the time being, this may be re-introduced in a future release under an opt-in prop. +- [`187e47d`](https://github.com/jaredpalmer/formik/commit/187e47de0c4289cb279e25d69f8172cfa14369d2) [#3815](https://github.com/jaredpalmer/formik/pull/3815) Thanks [@quantizor](https://github.com/quantizor)! - Revert Yup transform support for the time being, this may be re-introduced in a future release under an opt-in prop. ## 2.4.0 ### Minor Changes -- [`2f53b70`](https://github.com/jaredpalmer/formik/commit/2f53b70ef9c086a268330fa263390a2edd0164dd) [#3796](https://github.com/jaredpalmer/formik/pull/3796) Thanks [@probablyup](https://github.com/probablyup)! - Add support for Yup ["transforms"](https://github.com/jquense/yup#parsing-transforms). +- [`2f53b70`](https://github.com/jaredpalmer/formik/commit/2f53b70ef9c086a268330fa263390a2edd0164dd) [#3796](https://github.com/jaredpalmer/formik/pull/3796) Thanks [@quantizor](https://github.com/quantizor)! - Add support for Yup ["transforms"](https://github.com/jquense/yup#parsing-transforms). ## 2.3.3 ### Patch Changes -- [`f075a0c`](https://github.com/jaredpalmer/formik/commit/f075a0cf8228c135ff71c58e139246ad24aae529) [#3798](https://github.com/jaredpalmer/formik/pull/3798) Thanks [@probablyup](https://github.com/probablyup)! - Fixed the use of generics for the `ArrayHelpers` type such that `any[]` is the default array type and for each individual method the array item type can be overridden if necessary. +- [`f075a0c`](https://github.com/jaredpalmer/formik/commit/f075a0cf8228c135ff71c58e139246ad24aae529) [#3798](https://github.com/jaredpalmer/formik/pull/3798) Thanks [@quantizor](https://github.com/quantizor)! - Fixed the use of generics for the `ArrayHelpers` type such that `any[]` is the default array type and for each individual method the array item type can be overridden if necessary. ## 2.3.2 @@ -58,21 +64,21 @@ - [`f086b5a`](https://github.com/jaredpalmer/formik/commit/f086b5a3bb6a155b4dc4ac3735c88805f9f5c4e4) [#3237](https://github.com/jaredpalmer/formik/pull/3237) Thanks [@pieplu](https://github.com/pieplu)! - Changed `getIn` to return undefined when it can't find a value AND a parent of that value is "falsy" ( "" / 0 / null / false ) -* [`6d8f018`](https://github.com/jaredpalmer/formik/commit/6d8f018d7f52b863405b2e310be4b4195c2ba39c) [#3792](https://github.com/jaredpalmer/formik/pull/3792) Thanks [@probablyup](https://github.com/probablyup)! - Update the type for `setFieldValue` to reflect the returned `Promise` and potential returned error(s). +* [`6d8f018`](https://github.com/jaredpalmer/formik/commit/6d8f018d7f52b863405b2e310be4b4195c2ba39c) [#3792](https://github.com/jaredpalmer/formik/pull/3792) Thanks [@quantizor](https://github.com/quantizor)! - Update the type for `setFieldValue` to reflect the returned `Promise` and potential returned error(s). ## 2.3.1 ### Patch Changes -- [`290d92b`](https://github.com/jaredpalmer/formik/commit/290d92b34056593f551ad55baf00dc6f8c700bbe) [#3793](https://github.com/jaredpalmer/formik/pull/3793) Thanks [@probablyup](https://github.com/probablyup)! - Fix potential infinite loop scenario when `initialValues` changes but `enableReinitialize` is not truthy. +- [`290d92b`](https://github.com/jaredpalmer/formik/commit/290d92b34056593f551ad55baf00dc6f8c700bbe) [#3793](https://github.com/jaredpalmer/formik/pull/3793) Thanks [@quantizor](https://github.com/quantizor)! - Fix potential infinite loop scenario when `initialValues` changes but `enableReinitialize` is not truthy. ## 2.3.0 ### Minor Changes -- [`73de78d`](https://github.com/jaredpalmer/formik/commit/73de78d169f0bc25bd84dff0beaed3cc7a2cbb11) [#3788](https://github.com/jaredpalmer/formik/pull/3788) Thanks [@probablyup](https://github.com/probablyup)! - Added typescript generics to `ArrayHelpers` interface and its methods so that users who use TypeScript can set the type for their arrays and have type safety on array utils. I have also gone ahead and made supplying a type for the generic optional for the sake of backwards compatibility so any existing TS code that does not give a type for the FieldArray will continue to work as they always have. +- [`73de78d`](https://github.com/jaredpalmer/formik/commit/73de78d169f0bc25bd84dff0beaed3cc7a2cbb11) [#3788](https://github.com/jaredpalmer/formik/pull/3788) Thanks [@quantizor](https://github.com/quantizor)! - Added typescript generics to `ArrayHelpers` interface and its methods so that users who use TypeScript can set the type for their arrays and have type safety on array utils. I have also gone ahead and made supplying a type for the generic optional for the sake of backwards compatibility so any existing TS code that does not give a type for the FieldArray will continue to work as they always have. -* [`39a7bf7`](https://github.com/jaredpalmer/formik/commit/39a7bf7ca31f2ef5b149a8ff02bab64667e19654) [#3786](https://github.com/jaredpalmer/formik/pull/3786) Thanks [@probablyup](https://github.com/probablyup)! - Yup by default only allows for cross-field validation within the +* [`39a7bf7`](https://github.com/jaredpalmer/formik/commit/39a7bf7ca31f2ef5b149a8ff02bab64667e19654) [#3786](https://github.com/jaredpalmer/formik/pull/3786) Thanks [@quantizor](https://github.com/quantizor)! - Yup by default only allows for cross-field validation within the same field object. This is not that useful in most scenarios because a sufficiently-complex form will have several `yup.object()` in the schema. @@ -115,17 +121,17 @@ ### Patch Changes -- [`22e236e`](https://github.com/jaredpalmer/formik/commit/22e236ed8035c7c5824232202c8ce52193338d5a) [#3784](https://github.com/jaredpalmer/formik/pull/3784) Thanks [@probablyup](https://github.com/probablyup)! - Improve performance of the `FieldArray` component by adding a `shouldComponentUpdate` check; this should help avoid unnecessary re-renders which may affect the performance of a form. +- [`22e236e`](https://github.com/jaredpalmer/formik/commit/22e236ed8035c7c5824232202c8ce52193338d5a) [#3784](https://github.com/jaredpalmer/formik/pull/3784) Thanks [@quantizor](https://github.com/quantizor)! - Improve performance of the `FieldArray` component by adding a `shouldComponentUpdate` check; this should help avoid unnecessary re-renders which may affect the performance of a form. -* [`bc9cb28`](https://github.com/jaredpalmer/formik/commit/bc9cb28df7ad07277a499e8301cfd1bb7b230b86) [#3785](https://github.com/jaredpalmer/formik/pull/3785) Thanks [@probablyup](https://github.com/probablyup)! - Fixed field error state for array fields that have an error and become empty through an API like `arrayHelpers.remove`. +* [`bc9cb28`](https://github.com/jaredpalmer/formik/commit/bc9cb28df7ad07277a499e8301cfd1bb7b230b86) [#3785](https://github.com/jaredpalmer/formik/pull/3785) Thanks [@quantizor](https://github.com/quantizor)! - Fixed field error state for array fields that have an error and become empty through an API like `arrayHelpers.remove`. The prior behavior resolved the field error to `[undefined]`, now it is simply `undefined`. -- [`9cbf150`](https://github.com/jaredpalmer/formik/commit/9cbf150e65d7c5498900f19b4fa1897ca8a2c87f) [#3787](https://github.com/jaredpalmer/formik/pull/3787) Thanks [@probablyup](https://github.com/probablyup)! - Fix infinite loop issue in `Field` when field helpers (`setTouched`, etc) are used as an argument in `React.useEffect`. +- [`9cbf150`](https://github.com/jaredpalmer/formik/commit/9cbf150e65d7c5498900f19b4fa1897ca8a2c87f) [#3787](https://github.com/jaredpalmer/formik/pull/3787) Thanks [@quantizor](https://github.com/quantizor)! - Fix infinite loop issue in `Field` when field helpers (`setTouched`, etc) are used as an argument in `React.useEffect`. -* [`9c75a9f`](https://github.com/jaredpalmer/formik/commit/9c75a9f639eb38ad55c351e5e1def8a7e5ebd1f3) [#3780](https://github.com/jaredpalmer/formik/pull/3780) Thanks [@probablyup](https://github.com/probablyup)! - Fixed an issue with array field errors being incorrectly split into an array of individual characters instead of an array of error strings. +* [`9c75a9f`](https://github.com/jaredpalmer/formik/commit/9c75a9f639eb38ad55c351e5e1def8a7e5ebd1f3) [#3780](https://github.com/jaredpalmer/formik/pull/3780) Thanks [@quantizor](https://github.com/quantizor)! - Fixed an issue with array field errors being incorrectly split into an array of individual characters instead of an array of error strings. -- [`35fa4cc`](https://github.com/jaredpalmer/formik/commit/35fa4cc38260d709a5570dd3c9ef82831758a5f5) [#3783](https://github.com/jaredpalmer/formik/pull/3783) Thanks [@probablyup](https://github.com/probablyup)! - Fix validation of deep.dot.path field references when using the `validateField` API. +- [`35fa4cc`](https://github.com/jaredpalmer/formik/commit/35fa4cc38260d709a5570dd3c9ef82831758a5f5) [#3783](https://github.com/jaredpalmer/formik/pull/3783) Thanks [@quantizor](https://github.com/quantizor)! - Fix validation of deep.dot.path field references when using the `validateField` API. ## 2.2.9 diff --git a/packages/formik/package.json b/packages/formik/package.json index 2db8b4ac9..6d001676a 100644 --- a/packages/formik/package.json +++ b/packages/formik/package.json @@ -1,11 +1,11 @@ { "name": "formik", "description": "Build forms in React, without the tears", - "version": "2.4.5", + "version": "2.4.6", "license": "Apache-2.0", "author": "Jared Palmer (https://jaredpalmer.com)", "contributors": [ - "Evan Jacobs (https://probablyup.com)" + "Evan Jacobs (https://quantizor.dev)" ], "repository": "jaredpalmer/formik", "homepage": "https://formik.org", diff --git a/packages/formik/src/FieldArray.tsx b/packages/formik/src/FieldArray.tsx index 951a2a491..1e0a4073e 100644 --- a/packages/formik/src/FieldArray.tsx +++ b/packages/formik/src/FieldArray.tsx @@ -30,9 +30,9 @@ export type FieldArrayConfig = { } & SharedRenderProps; export interface ArrayHelpers { /** Imperatively add a value to the end of an array */ - push(obj: X): void; + push(obj: X): void; /** Curried fn to add a value to the end of an array */ - handlePush(obj: X): () => void; + handlePush(obj: X): () => void; /** Imperatively swap two values in an array */ swap: (indexA: number, indexB: number) => void; /** Curried fn to swap two values in an array */ @@ -42,25 +42,25 @@ export interface ArrayHelpers { /** Imperatively move an element in an array to another index */ handleMove: (from: number, to: number) => () => void; /** Imperatively insert an element at a given index into the array */ - insert(index: number, value: X): void; + insert(index: number, value: X): void; /** Curried fn to insert an element at a given index into the array */ - handleInsert(index: number, value: X): () => void; + handleInsert(index: number, value: X): () => void; /** Imperatively replace a value at an index of an array */ - replace(index: number, value: X): void; + replace(index: number, value: X): void; /** Curried fn to replace an element at a given index into the array */ - handleReplace(index: number, value: X): () => void; + handleReplace(index: number, value: X): () => void; /** Imperatively add an element to the beginning of an array and return its length */ - unshift(value: X): number; + unshift(value: X): number; /** Curried fn to add an element to the beginning of an array */ - handleUnshift(value: X): () => void; + handleUnshift(value: X): () => void; /** Curried fn to remove an element at an index of an array */ handleRemove: (index: number) => () => void; /** Curried fn to remove a value from the end of the array */ handlePop: () => () => void; /** Imperatively remove and element at an index of an array */ - remove(index: number): X | undefined; + remove(index: number): X | undefined; /** Imperatively remove and return value from the end of the array */ - pop(): X | undefined; + pop(): X | undefined; } /** diff --git a/packages/formik/src/Formik.tsx b/packages/formik/src/Formik.tsx index cd17adcd4..ea36e80d3 100755 --- a/packages/formik/src/Formik.tsx +++ b/packages/formik/src/Formik.tsx @@ -1,5 +1,6 @@ import deepmerge from 'deepmerge'; import isPlainObject from 'lodash/isPlainObject'; +import cloneDeep from 'lodash/cloneDeep'; import * as React from 'react'; import isEqual from 'react-fast-compare'; import invariant from 'tiny-warning'; @@ -173,10 +174,10 @@ export function useFormik({ const [, setIteration] = React.useState(0); const stateRef = React.useRef>({ - values: props.initialValues, - errors: props.initialErrors || emptyErrors, - touched: props.initialTouched || emptyTouched, - status: props.initialStatus, + values: cloneDeep(props.initialValues), + errors: cloneDeep(props.initialErrors) || emptyErrors, + touched: cloneDeep(props.initialTouched) || emptyTouched, + status: cloneDeep(props.initialStatus), isSubmitting: false, isValidating: false, submitCount: 0, @@ -581,18 +582,20 @@ export function useFormik({ ); const setFieldValue = useEventCallback( - (field: string, value: any, shouldValidate?: boolean) => { + (field: string, value: React.SetStateAction, shouldValidate?: boolean) => { + const resolvedValue = isFunction(value) ? value(getIn(state.values, field)) : value; + dispatch({ type: 'SET_FIELD_VALUE', payload: { field, - value, + value: resolvedValue, }, }); const willValidate = shouldValidate === undefined ? validateOnChange : shouldValidate; return willValidate - ? validateFormWithHighPriority(setIn(state.values, field, value)) + ? validateFormWithHighPriority(setIn(state.values, field, resolvedValue)) : Promise.resolve(); } ); diff --git a/packages/formik/test/Formik.test.tsx b/packages/formik/test/Formik.test.tsx index 2acf332dd..864589643 100644 --- a/packages/formik/test/Formik.test.tsx +++ b/packages/formik/test/Formik.test.tsx @@ -61,6 +61,20 @@ const InitialValues = { age: 30, }; +const InitialValuesWithNestedObject = { + content: { + items: [ + { + cards: [ + { + desc: 'Initial Desc', + }, + ], + }, + ], + }, +}; + function renderFormik( props?: Partial> ) { @@ -726,6 +740,55 @@ describe('', () => { }); }); + it('setFieldValue sets value by key when takes a setter function', async () => { + const { getProps, rerender } = renderFormik(); + + act(() => { + getProps().setFieldValue('name', (prev: string) => { + return prev + ' chronicus'; + }); + }); + rerender(); + await waitFor(() => { + expect(getProps().values.name).toEqual('jared chronicus'); + }); + }); + + it( + 'setFieldValue should run validations with resolved value when takes a setter function and validateOnChange is true (default)', + async () => { + const validate = jest.fn(() =>({})); + const { getProps, rerender } = renderFormik({ validate }); + + act(() => { + getProps().setFieldValue('name', (prev: string) => prev + ' chronicus'); + }); + rerender(); + await waitFor(() => { + // the validate function is called with the second arg as undefined always in this case + expect(validate).toHaveBeenCalledWith(expect.objectContaining({ + name: 'jared chronicus', + }), undefined); + }); + } + ); + + it('setFieldValue should NOT run validations when takes a setter function and validateOnChange is false', async () => { + const validate = jest.fn(); + const { getProps, rerender } = renderFormik({ + validate, + validateOnChange: false, + }); + + act(() => { + getProps().setFieldValue('name', (prev: string) => prev + ' chronicus'); + }); + rerender(); + await waitFor(() => { + expect(validate).not.toHaveBeenCalled(); + }); + }); + it('setTouched sets touched', () => { const { getProps } = renderFormik(); @@ -1454,4 +1517,34 @@ describe('', () => { expect(innerRef.current).toEqual(getProps()); }); + + it('should not modify original initialValues object', () => { + render( + + {formikProps => ( + { + const copy = { ...formikProps.values.content }; + copy.items[0].cards[0].desc = e.target.value; + formikProps.setValues({ + ...formikProps.values, + content: copy, + }); + }} + /> + )} + + ); + const input = screen.getByTestId('desc-input'); + + fireEvent.change(input, { + target: { + value: 'New Value', + }, + }); + + expect(InitialValuesWithNestedObject.content.items[0].cards[0].desc).toEqual('Initial Desc'); + }); }); diff --git a/website/public/images/logos/techjobsbe.svg b/website/public/images/logos/techjobsbe.svg new file mode 100644 index 000000000..1b97c07ec --- /dev/null +++ b/website/public/images/logos/techjobsbe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/users.ts b/website/src/users.ts index 010cadab6..d5836be37 100644 --- a/website/src/users.ts +++ b/website/src/users.ts @@ -239,4 +239,9 @@ export const users = [ image: '/images/logos/authdog.svg', infoLink: 'https://www.authdog.com', }, + { + caption: 'Techjobs.be IT jobs', + image: '/images/logos/techjobsbe.svg', + infoLink: 'https://techjobs.be', + }, ];