generated from ocadotechnology/codeforlife-template-backend
-
Notifications
You must be signed in to change notification settings - Fork 24
/
CflForm.tsx
87 lines (82 loc) · 2.38 KB
/
CflForm.tsx
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
import React from 'react';
import {
Grid,
Stack,
StackProps,
Typography,
GridProps,
ButtonProps,
TypographyProps
} from '@mui/material';
import { Formik, FormikValues, FormikConfig, FormikProps, Form } from 'formik';
export interface CflHorizontalFormProps<Values> extends FormikConfig<Values> {
header: string;
subheader?: string;
subheaderBold?: string;
children?: JSX.Element[];
gridProps?: GridProps;
submitButton: React.ReactElement<ButtonProps>;
headerAlignment?: TypographyProps['align'];
}
export const CflHorizontalForm = <Values extends FormikValues = FormikValues>({
children,
gridProps = { container: true, columnSpacing: 3 },
header,
headerAlignment = 'left',
subheader,
subheaderBold,
submitButton,
...formikProps
}: CflHorizontalFormProps<Values>): JSX.Element => {
return (
<Formik {...formikProps}>
{(formik) => (
<React.Fragment>
<Typography align={headerAlignment} variant="h4" sx={{ mb: 2 }}>
{header}
</Typography>
<Typography>{subheader}</Typography>
<Typography fontWeight="bold">{subheaderBold}</Typography>
<Form>
<Grid {...gridProps}>
{React.Children.map(children, (child, index) => {
// Allow last child components such as checkboxes to take up the full width
const isLastChild = children && index === children?.length - 1;
return (
<Grid xs={12} sm={isLastChild ? true : 4} item>
{child}
</Grid>
);
})}
<Grid item xs={12}>
{React.cloneElement(submitButton, {
disabled: !(formik.isValid && formik.dirty)
})}
</Grid>
</Grid>
</Form>
</React.Fragment>
)}
</Formik>
);
};
export interface CflFormProps<Values> extends FormikConfig<Values> {
children: (formik: FormikProps<Values>) => React.ReactNode;
stackProps?: StackProps;
}
const CflForm = <Values extends FormikValues = FormikValues>({
children,
stackProps = { gap: 1 },
...formikProps
}: CflFormProps<Values>): JSX.Element => {
return (
<Formik {...formikProps}>
{(formik) => (
<Form>
<Stack {...stackProps}>{children(formik)}</Stack>
</Form>
)}
</Formik>
);
};
export default CflForm;