@graphcommerce/react-hook-form 9.0.4-canary.8 → 9.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -16
- package/package.json +4 -4
- package/src/ComposedForm/types.ts +4 -9
- package/src/ComposedForm/useFormCompose.ts +5 -5
- package/src/useFormAutoSubmit.tsx +2 -3
- package/src/useFormGqlMutation.tsx +8 -5
- package/src/useFormMuiRegister.tsx +3 -1
- package/src/useFormPersist.tsx +8 -8
- package/src/useFormValidFields.tsx +4 -6
- package/src/useGqlDocumentHandler.tsx +1 -1
- package/src/utils/useDebounce.ts +10 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## 9.0.4
|
|
3
|
+
## 9.0.4
|
|
4
4
|
|
|
5
|
-
## 9.0.
|
|
5
|
+
## 9.0.3
|
|
6
6
|
|
|
7
|
-
## 9.0.
|
|
7
|
+
## 9.0.3-canary.0
|
|
8
8
|
|
|
9
|
-
## 9.0.
|
|
10
|
-
|
|
11
|
-
## 9.0.4-canary.4
|
|
12
|
-
|
|
13
|
-
## 9.0.4-canary.3
|
|
9
|
+
## 9.0.2
|
|
14
10
|
|
|
15
11
|
### Patch Changes
|
|
16
12
|
|
|
17
|
-
- [
|
|
18
|
-
|
|
19
|
-
## 9.0.4-canary.2
|
|
20
|
-
|
|
21
|
-
## 9.0.4-canary.1
|
|
22
|
-
|
|
23
|
-
## 9.0.4-canary.0
|
|
13
|
+
- [`c40c559`](https://github.com/graphcommerce-org/graphcommerce/commit/c40c5596bcc8f3c2e1e15c9e6ad85bfa1f9154b0) - Solve an issue where the payment submission would remain in a spinning state when placing an order failed: `useFormGql` will now set `root` error on the form when there is an error response on the GraphQL operation, an error is thrown in onBeforeSubmit and in onSuccess. ([@paales](https://github.com/paales))
|
|
24
14
|
|
|
25
|
-
## 9.0.2
|
|
15
|
+
## 9.0.2-canary.0
|
|
26
16
|
|
|
27
17
|
### Patch Changes
|
|
28
18
|
|
|
29
19
|
- [`c40c559`](https://github.com/graphcommerce-org/graphcommerce/commit/c40c5596bcc8f3c2e1e15c9e6ad85bfa1f9154b0) - Solve an issue where the payment submission would remain in a spinning state when placing an order failed: `useFormGql` will now set `root` error on the form when there is an error response on the GraphQL operation, an error is thrown in onBeforeSubmit and in onSuccess. ([@paales](https://github.com/paales))
|
|
30
20
|
|
|
21
|
+
## 9.0.1
|
|
22
|
+
|
|
23
|
+
## 9.0.1-canary.1
|
|
24
|
+
|
|
31
25
|
## 9.0.0
|
|
32
26
|
|
|
33
27
|
### Major Changes
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/react-hook-form",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "9.0.4
|
|
5
|
+
"version": "9.0.4",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"@apollo/client": "*",
|
|
16
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.4
|
|
17
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.4
|
|
18
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.4
|
|
16
|
+
"@graphcommerce/eslint-config-pwa": "^9.0.4",
|
|
17
|
+
"@graphcommerce/prettier-config-pwa": "^9.0.4",
|
|
18
|
+
"@graphcommerce/typescript-config-pwa": "^9.0.4",
|
|
19
19
|
"@mui/utils": "^5",
|
|
20
20
|
"graphql": "^16.6.0",
|
|
21
21
|
"react": "^18.2.0",
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import type { ApolloError } from '@apollo/client'
|
|
2
|
-
import type { FieldValues, FormState,
|
|
2
|
+
import type { FieldValues, FormState, UseFormReturn } from 'react-hook-form'
|
|
3
3
|
import type { SetOptional } from 'type-fest'
|
|
4
4
|
|
|
5
|
-
export type
|
|
6
|
-
formState: FormState<TFieldValues>
|
|
7
|
-
trigger: UseFormTrigger<TFieldValues>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type UseFormComposeOptions<TFieldValues extends FieldValues = FieldValues> = {
|
|
5
|
+
export type UseFormComposeOptions<V extends FieldValues = FieldValues> = {
|
|
11
6
|
/** The form that is used to submit */
|
|
12
|
-
form:
|
|
7
|
+
form: UseFormReturn<V>
|
|
13
8
|
/** Method to submit the form */
|
|
14
|
-
submit: ReturnType<
|
|
9
|
+
submit: ReturnType<UseFormReturn<V>['handleSubmit']>
|
|
15
10
|
|
|
16
11
|
/** Identifier of the specific */
|
|
17
12
|
key: string
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useContext, useEffect } from 'react'
|
|
2
|
-
import type { FieldValues } from 'react-hook-form'
|
|
2
|
+
import type { FieldValues, UseFormReturn } from 'react-hook-form'
|
|
3
3
|
import { isFormGqlOperation } from '../useFormGqlMutation'
|
|
4
4
|
import { composedFormContext } from './context'
|
|
5
|
-
import type {
|
|
5
|
+
import type { UseFormComposeOptions } from './types'
|
|
6
6
|
|
|
7
|
-
export function useFormCompose<
|
|
8
|
-
fields: UseFormComposeOptions<
|
|
7
|
+
export function useFormCompose<V extends Record<string, unknown>>(
|
|
8
|
+
fields: UseFormComposeOptions<V>,
|
|
9
9
|
) {
|
|
10
10
|
const [state, dispatch] = useContext(composedFormContext)
|
|
11
11
|
const { form, key, step, submit } = fields
|
|
@@ -18,7 +18,7 @@ export function useFormCompose<TFieldValues extends FieldValues = FieldValues>(
|
|
|
18
18
|
}, [dispatch, key, step])
|
|
19
19
|
|
|
20
20
|
useEffect(() => {
|
|
21
|
-
dispatch({ type: 'ASSIGN', key, form: form as
|
|
21
|
+
dispatch({ type: 'ASSIGN', key, form: form as UseFormReturn<FieldValues>, submit })
|
|
22
22
|
}, [dispatch, fields, form, key, submit])
|
|
23
23
|
|
|
24
24
|
const error = isFormGqlOperation(form) ? form.error : undefined
|
|
@@ -4,12 +4,11 @@ import { useMemoObject } from '@graphcommerce/next-ui/hooks/useMemoObject'
|
|
|
4
4
|
import { cloneDeep } from '@apollo/client/utilities'
|
|
5
5
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
6
6
|
import { debounce } from '@mui/material'
|
|
7
|
-
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
|
7
|
+
import React, { startTransition, useCallback, useEffect, useRef, useState } from 'react'
|
|
8
8
|
import type {
|
|
9
9
|
DeepPartialSkipArrayKey,
|
|
10
10
|
FieldPath,
|
|
11
11
|
FieldValues,
|
|
12
|
-
UseFormHandleSubmit,
|
|
13
12
|
UseFormReturn,
|
|
14
13
|
UseWatchProps,
|
|
15
14
|
} from 'react-hook-form'
|
|
@@ -106,7 +105,7 @@ export type FormAutoSubmitProps<TFieldValues extends FieldValues = FieldValues>
|
|
|
106
105
|
|
|
107
106
|
/** SubmitHandler */
|
|
108
107
|
// eslint-disable-next-line react/no-unused-prop-types
|
|
109
|
-
submit: ReturnType<
|
|
108
|
+
submit: ReturnType<UseFormReturn<TFieldValues>['handleSubmit']>
|
|
110
109
|
|
|
111
110
|
/**
|
|
112
111
|
* When a current submission is already in flight, should we wait for it to finish before
|
|
@@ -15,18 +15,21 @@ export type UseFormGqlMutationReturn<
|
|
|
15
15
|
V extends FieldValues = FieldValues,
|
|
16
16
|
> = UseFormGqlMethods<Q, V> &
|
|
17
17
|
UseFormReturn<V> & {
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated Please use TextFieldElement
|
|
20
|
+
*/
|
|
19
21
|
muiRegister: UseMuiFormRegister<V>
|
|
20
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated Please use TextFieldElement showValid
|
|
24
|
+
*/
|
|
21
25
|
valid: UseFormValidReturn<V>
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
export function isFormGqlOperation<
|
|
25
29
|
V extends FieldValues,
|
|
26
30
|
Q extends Record<string, unknown> = Record<string, unknown>,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return typeof (form as UseFormGqlMutationReturn<Q, V>).submittedVariables !== 'undefined'
|
|
31
|
+
>(form: UseFormReturn<V>): form is UseFormGqlMutationReturn<Q, V> {
|
|
32
|
+
return typeof (form as UseFormGqlMutationReturn<Q, V>).muiRegister === 'function'
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
export function assertFormGqlOperation<
|
|
@@ -13,7 +13,9 @@ export type UseMuiFormRegister<TFieldValues extends FieldValues> = <
|
|
|
13
13
|
options?: RegisterOptions<TFieldValues, TFieldName>,
|
|
14
14
|
) => Omit<UseFormRegisterReturn, 'ref'> & { inputRef: UseFormRegisterReturn['ref'] }
|
|
15
15
|
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Please use use TextFieldElement, etc.
|
|
18
|
+
*/
|
|
17
19
|
export function useFormMuiRegister<V extends FieldValues>({
|
|
18
20
|
register,
|
|
19
21
|
}: Pick<UseFormReturn<V>, 'register'>) {
|
package/src/useFormPersist.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable react/no-unused-prop-types */
|
|
2
2
|
import { useEffect } from 'react'
|
|
3
|
-
import type {
|
|
3
|
+
import type { FieldPath, FieldValues, Path, PathValue, UseFormReturn } from 'react-hook-form'
|
|
4
4
|
import { useFormState, useWatch } from 'react-hook-form'
|
|
5
5
|
|
|
6
6
|
export type UseFormPersistOptions<
|
|
@@ -9,10 +9,7 @@ export type UseFormPersistOptions<
|
|
|
9
9
|
TContext = any,
|
|
10
10
|
> = {
|
|
11
11
|
/** Instance of current form, used to watch value */
|
|
12
|
-
form:
|
|
13
|
-
control: Control<TFieldValues, TContext>
|
|
14
|
-
setValue: UseFormSetValue<TFieldValues>
|
|
15
|
-
}
|
|
12
|
+
form: UseFormReturn<TFieldValues, TContext>
|
|
16
13
|
|
|
17
14
|
/** Name of the key how it will be stored in the storage. */
|
|
18
15
|
name: string
|
|
@@ -45,7 +42,7 @@ export function useFormPersist<V extends FieldValues>(options: UseFormPersistOpt
|
|
|
45
42
|
const formState = useFormState({ control })
|
|
46
43
|
const allFields = useWatch({ control })
|
|
47
44
|
|
|
48
|
-
const dirtyFieldKeys = Object.keys(formState.dirtyFields) as
|
|
45
|
+
const dirtyFieldKeys = Object.keys(formState.dirtyFields) as Path<V>[]
|
|
49
46
|
|
|
50
47
|
// // Get all dirty field values and exclude sensitive data
|
|
51
48
|
const newValues = Object.fromEntries(
|
|
@@ -70,9 +67,12 @@ export function useFormPersist<V extends FieldValues>(options: UseFormPersistOpt
|
|
|
70
67
|
|
|
71
68
|
const storedValues = JSON.parse(storedFormStr) as FieldValues
|
|
72
69
|
if (storedValues) {
|
|
73
|
-
const entries = Object.entries(storedValues) as [
|
|
70
|
+
const entries = Object.entries(storedValues) as [Path<V>, PathValue<V, Path<V>>][]
|
|
74
71
|
entries.forEach(([entryName, value]) =>
|
|
75
|
-
setValue(entryName, value, {
|
|
72
|
+
setValue(entryName, value, {
|
|
73
|
+
shouldDirty: true,
|
|
74
|
+
shouldValidate: true,
|
|
75
|
+
}),
|
|
76
76
|
)
|
|
77
77
|
}
|
|
78
78
|
} catch {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FieldValues, Path, UseFormReturn } from 'react-hook-form'
|
|
2
2
|
import type { IsRequired } from './useGqlDocumentHandler'
|
|
3
3
|
|
|
4
|
-
export type UseFormValidReturn<TFieldValues
|
|
5
|
-
Record<FieldPath<TFieldValues>, boolean>
|
|
6
|
-
>
|
|
4
|
+
export type UseFormValidReturn<TFieldValues> = Partial<Record<Path<TFieldValues>, boolean>>
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* ### useFormValidFields
|
|
@@ -18,10 +16,10 @@ export function useFormValidFields<TFieldValues extends FieldValues>(
|
|
|
18
16
|
required: IsRequired<TFieldValues>,
|
|
19
17
|
): UseFormValidReturn<TFieldValues> {
|
|
20
18
|
const { watch, formState } = form
|
|
21
|
-
const fields: Partial<Record<
|
|
19
|
+
const fields: Partial<Record<Path<TFieldValues>, boolean>> = {}
|
|
22
20
|
|
|
23
21
|
Object.keys(required).forEach((key) => {
|
|
24
|
-
fields[key] = !formState.errors[key] && watch(key as
|
|
22
|
+
fields[key] = !formState.errors[key] && watch(key as Path<TFieldValues>)
|
|
25
23
|
})
|
|
26
24
|
|
|
27
25
|
return fields
|
package/src/utils/useDebounce.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import { useMemoObject } from '@graphcommerce/next-ui/hooks/useMemoObject'
|
|
3
3
|
import useEventCallback from '@mui/utils/useEventCallback'
|
|
4
4
|
import type {
|
|
5
|
-
DebouncedFunc,
|
|
6
|
-
DebouncedFuncLeading,
|
|
7
5
|
DebounceSettings,
|
|
8
6
|
DebounceSettingsLeading,
|
|
7
|
+
DebouncedFunc,
|
|
8
|
+
DebouncedFuncLeading,
|
|
9
9
|
} from 'lodash'
|
|
10
10
|
import debounce from 'lodash/debounce'
|
|
11
11
|
import { useMemo } from 'react'
|
|
@@ -13,15 +13,14 @@ import { useMemo } from 'react'
|
|
|
13
13
|
export type { DebounceSettings, DebounceSettingsLeading, DebouncedFunc, DebouncedFuncLeading }
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Creates a debounced function that delays invoking func until after wait milliseconds have elapsed
|
|
17
|
-
*
|
|
18
|
-
* cancel
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* last func invocation.
|
|
16
|
+
* Creates a debounced function that delays invoking func until after wait milliseconds have elapsed since
|
|
17
|
+
* the last time the debounced function was invoked. The debounced function comes with a cancel method to
|
|
18
|
+
* cancel delayed invocations and a flush method to immediately invoke them. Provide an options object to
|
|
19
|
+
* indicate that func should be invoked on the leading and/or trailing edge of the wait timeout. Subsequent
|
|
20
|
+
* calls to the debounced function return the result of the last func invocation.
|
|
22
21
|
*
|
|
23
|
-
* Note: If leading and trailing options are true, func is invoked on the trailing edge of the
|
|
24
|
-
*
|
|
22
|
+
* Note: If leading and trailing options are true, func is invoked on the trailing edge of the timeout only
|
|
23
|
+
* if the the debounced function is invoked more than once during the wait timeout.
|
|
25
24
|
*
|
|
26
25
|
* See David Corbacho’s article for details over the differences between _.debounce and _.throttle.
|
|
27
26
|
*
|
|
@@ -31,7 +30,7 @@ export type { DebounceSettings, DebounceSettingsLeading, DebouncedFunc, Debounce
|
|
|
31
30
|
* @param options.leading Specify invoking on the leading edge of the timeout.
|
|
32
31
|
* @param options.maxWait The maximum time func is allowed to be delayed before it’s invoked.
|
|
33
32
|
* @param options.trailing Specify invoking on the trailing edge of the timeout.
|
|
34
|
-
* @
|
|
33
|
+
* @return Returns the new debounced function.
|
|
35
34
|
*/
|
|
36
35
|
export function useDebounce<T extends (...args: never[]) => unknown>(
|
|
37
36
|
func: T,
|