-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathform-container.tsx
More file actions
76 lines (66 loc) · 2.4 KB
/
form-container.tsx
File metadata and controls
76 lines (66 loc) · 2.4 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
import * as React from "react";
import {
Form,
FormValues,
ValidationSnapshot,
ValidationStatus,
} from "@batch/ui-common/lib/form";
import { getBrowserEnvironment } from "../../environment";
import { FormLayoutType } from "./form-layout";
export interface FormButton {
label: string;
onClick?: () => void;
}
export interface FormContainerProps<V extends FormValues> {
form: Form<V>;
buttons?: FormButton[];
layout?: FormLayoutType;
onFormChange?: (newValues: V, oldValues: V) => void;
onValidationStatusChange?: (
oldStatus: ValidationStatus | undefined,
newStatus: ValidationStatus | undefined
) => void;
}
export const FormContainer = <V extends FormValues>(
props: FormContainerProps<V>
): JSX.Element => {
const { form, layout, onFormChange, buttons } = props;
// KLUDGE: These exist simply to trigger a rerender. The data is not
// actually used, as the components read the form directly
const [, setFormValues] = React.useState(form.values);
const [, setValidationStatus] = React.useState(form.validationStatus);
const formChangeHandler = React.useCallback(
(newValues: V, oldValues: V) => {
setFormValues(newValues);
if (onFormChange) {
onFormChange(newValues, oldValues);
}
form.validate();
},
[form, onFormChange]
);
React.useEffect(() => {
form._emitter.on("change", formChangeHandler);
return () => {
form._emitter.off("change", formChangeHandler);
};
}, [form, formChangeHandler]);
const formValidateHandler = React.useCallback(
async (snapshot?: ValidationSnapshot<V>) => {
// Note this will set the validation status to undefined
// when a validation event is seen without a snapshot, indicating a
// new validation round has begun, and any previous displayed
// validation data should be cleared.
setValidationStatus(snapshot?.overallStatus);
},
[]
);
React.useEffect(() => {
form._emitter.on("validate", formValidateHandler);
return () => {
form._emitter.off("validate", formValidateHandler);
};
}, [form, formValidateHandler]);
const LayoutComp = getBrowserEnvironment().getFormLayout<V>(layout);
return <LayoutComp form={form} button={buttons} />;
};