-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathForm.tsx
More file actions
108 lines (92 loc) · 2.86 KB
/
Form.tsx
File metadata and controls
108 lines (92 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { ReactNode } from "react";
import { DeepPartial, FieldPath, FieldValues, Mode, Resolver, SubmitHandler, useForm, UseFormReturn } from "react-hook-form";
import { jsonIsoDateReviver } from "./helpers/dateUtils";
import { FormContext, FormContextProps } from "./context/FormContext";
import { AutoSubmitConfig, useAutoSubmit } from "./hooks/useAutoSubmit";
export interface FormMethods<T extends FieldValues> extends UseFormReturn<T, unknown>, FormContextProps<T> {}
interface FormProps<T extends FieldValues> {
/**
* will be executed when an submit action was triggered
*/
onSubmit: SubmitHandler<T>;
/**
* The default validation mode of the form
*/
mode?: Mode;
/**
* the resolver for the validation
*/
resolver?: Resolver<T>;
/**
* the default values of the form
*/
defaultValues?: DeepPartial<T>;
/**
* passed fieldnames will be marked with "*"
*/
requiredFields?: FieldPath<T>[];
/**
* disable all fields inside the form making it readonly
*/
disabled?: boolean;
/**
* enables the form to do an autosubmit on values changed
*/
autoSubmitConfig?: AutoSubmitConfig;
/**
* the children that will be drawn inside the form
*/
children: ((formMethods: FormMethods<T>) => ReactNode) | ReactNode;
/**
* the form ref
*/
formRef?: React.MutableRefObject<HTMLFormElement | null>;
/**
* hide the validation messages for all form inputs.
*/
hideValidationMessages?: boolean;
/**
* controls browser autocomplete behavior for the form.
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
*/
autoComplete?: string;
}
const Form = <T extends FieldValues>({
children,
onSubmit,
resolver,
defaultValues,
requiredFields = [],
disabled = false,
autoSubmitConfig,
formRef,
hideValidationMessages = false,
autoComplete,
mode,
}: FormProps<T>) => {
const revivedDefaultValues = defaultValues
? (JSON.parse(JSON.stringify(defaultValues), jsonIsoDateReviver) as DeepPartial<T>)
: defaultValues;
const disableAriaAutocomplete = autoComplete === "off";
const formMethods = useForm<T>({ resolver, defaultValues: revivedDefaultValues, mode: mode });
const autoSubmitHandler = useAutoSubmit({ onSubmit, formMethods, autoSubmitConfig });
return (
<FormContext.Provider value={{ requiredFields, disabled, hideValidationMessages, disableAriaAutocomplete, ...formMethods }}>
<form
ref={(elem) => {
if (formRef) {
formRef.current = elem;
}
}}
onSubmit={autoSubmitHandler}
method="POST"
autoComplete={autoComplete}
>
{children instanceof Function
? children({ ...formMethods, disabled, requiredFields, hideValidationMessages, disableAriaAutocomplete })
: children}
</form>
</FormContext.Provider>
);
};
export { Form, FormProps };