|
| 1 | +/** |
| 2 | + * External dependencies |
| 3 | + */ |
| 4 | +import { createContext, useContext } from '@wordpress/element'; |
| 5 | + |
| 6 | +/** |
| 7 | + * @typedef {import('react').React} React |
| 8 | + */ |
| 9 | + |
| 10 | +/** |
| 11 | + * @typedef {Object} InputProps |
| 12 | + * @property {*} value Form value. |
| 13 | + * @property {boolean} checked Form value converted to boolean. |
| 14 | + * @property {*} selected Form value. |
| 15 | + * @property {(value: Event<HTMLInputElement> | *) => void} onChange Function to handle onChange event. |
| 16 | + * @property {() => void} onBlur Function to handle onBlur event. |
| 17 | + * @property {'has-error' | undefined} className 'has-error' if the form value is invalid and marked as touched. `undefined` otherwise. |
| 18 | + * @property {string | undefined | null} help The corresponding value in form `errors` if the form value is marked as touched. `null` otherwise. |
| 19 | + */ |
| 20 | + |
| 21 | +/** |
| 22 | + * @typedef {Object} AdaptiveFormContextAdapter |
| 23 | + * @property {boolean} isSubmitting `true` if the form is currently being submitted. |
| 24 | + * @property {boolean} isSubmitted Set to `true` after the form is submitted. Initial value and during submission are set to `false`. |
| 25 | + * @property { HTMLElement | null} submitter Set to the element triggering the `handleSubmit` callback until the processing of `onSubmit` is completed. `null` otherwise. |
| 26 | + * @property {number} validationRequestCount The current validation request count. |
| 27 | + * @property {boolean} requestedShowValidation Whether have requested verification. It will be reset to false after calling hideValidation. |
| 28 | + * @property {() => void} showValidation Increase the validation request count by 1. |
| 29 | + * @property {() => void} hideValidation Reset the validation request count to 0. |
| 30 | + */ |
| 31 | + |
| 32 | +/** |
| 33 | + * @typedef {Object} AdaptiveFormContext |
| 34 | + * @property {Object} values Form values, e.g. `{ nickname: '' age: 0 }`. |
| 35 | + * @property {Object} errors Object with key-value pairs representing errors for form values. Empty object if no errors. For example, `{ nickname: 'Nickname is required.' }`. |
| 36 | + * @property {Object} touched Object with key-value pairs representing the corresponding input fields of the form values have received focus, e.g. `{ nickname: true }`. |
| 37 | + * @property {boolean} isValidForm `true` if form values pass the validation. |
| 38 | + * @property {boolean} isDirty `true` after any of the form values is modified. |
| 39 | + * @property {(name: string, value: *) => void} setValue Function to set a form value. |
| 40 | + * @property {(name: string) => InputProps} getInputProps Function to get the corresponding input props by a name of the form `values`. The returned props is usually used to assign to input field. |
| 41 | + * @property {() => Promise<Object>} handleSubmit Function to trigger form submission. |
| 42 | + * @property {(initialValues: Object) => void} resetForm Function to reset form with given initial values. |
| 43 | + * @property {React.Dispatch<React.SetStateAction<Object>>} setTouched Function to update the `touched` state, e.g. `setTouched( { nickname: false } )`. |
| 44 | + * @property {AdaptiveFormContextAdapter} adapter Additional enhancements to AdaptiveForm. |
| 45 | + */ |
| 46 | + |
| 47 | +export const AdaptiveFormContext = createContext( null ); |
| 48 | + |
| 49 | +/** |
| 50 | + * AdaptiveForm's context hook. |
| 51 | + * |
| 52 | + * @return {AdaptiveFormContext} AdaptiveForm's context. |
| 53 | + * @throws Will throw an error if its context provider is not existing in its parents. |
| 54 | + */ |
| 55 | +export function useAdaptiveFormContext() { |
| 56 | + const adaptiveFormContext = useContext( AdaptiveFormContext ); |
| 57 | + |
| 58 | + if ( adaptiveFormContext === null ) { |
| 59 | + throw new Error( |
| 60 | + 'useAdaptiveFormContext was used outside of its context provider AdaptiveForm.' |
| 61 | + ); |
| 62 | + } |
| 63 | + |
| 64 | + return adaptiveFormContext; |
| 65 | +} |
| 66 | + |
| 67 | +/** |
| 68 | + * AdaptiveForm's input props hook. |
| 69 | + * |
| 70 | + * @param {string} key Key of the form value. |
| 71 | + * @param {string} [validationKey=key] Key of the form value to be used for validation. |
| 72 | + * |
| 73 | + * @return {Object} Props for an adaptive form input. |
| 74 | + */ |
| 75 | +export function useAdaptiveFormInputProps( key, validationKey = key ) { |
| 76 | + const { getInputProps, adapter } = useAdaptiveFormContext(); |
| 77 | + |
| 78 | + return { |
| 79 | + ...getInputProps( key ), |
| 80 | + helper: adapter.renderRequestedValidation( validationKey ), |
| 81 | + }; |
| 82 | +} |
0 commit comments