add basic react-hook-form implementation with basic autosave

This commit is contained in:
Sidney Alcantara
2020-07-17 17:47:42 +10:00
parent af6a347827
commit 32c625ea4a
4 changed files with 238 additions and 17 deletions

View File

@@ -51,6 +51,7 @@
"react-div-100vh": "^0.3.8",
"react-dom": "^16.9.0",
"react-dropzone": "^10.1.8",
"react-hook-form": "^6.0.6",
"react-json-view": "^1.19.1",
"react-router-dom": "^5.0.1",
"react-scripts": "^3.3.0",

View File

@@ -1,7 +1,11 @@
import React from "react";
import { makeStyles, createStyles } from "@material-ui/core";
import { TextField, TextFieldProps } from "formik-material-ui";
import {
makeStyles,
createStyles,
TextField,
FilledTextFieldProps,
} from "@material-ui/core";
const useStyles = makeStyles(theme =>
createStyles({
@@ -9,7 +13,7 @@ const useStyles = makeStyles(theme =>
})
);
export interface ITextProps extends TextFieldProps {
export interface ITextProps extends Omit<FilledTextFieldProps, "variant"> {
fieldVariant?: "short" | "long" | "email" | "phone" | "number" | "url";
}
@@ -27,7 +31,10 @@ export default function Text({ fieldVariant = "short", ...props }: ITextProps) {
break;
case "email":
variantProps = { type: "email", inputProps: { autoComplete: "email" } };
variantProps = {
// type: "email",
inputProps: { autoComplete: "email" },
};
break;
case "phone":
@@ -45,14 +52,14 @@ export default function Text({ fieldVariant = "short", ...props }: ITextProps) {
}
return (
<TextField
key={`${props.form.initialValues.id}-${props.field.name}`}
variant="filled"
//key={`${props.form.initialValues.id}-${props.field.name}`}
// variant="filled"
fullWidth
margin="none"
placeholder={props.label as string}
{...variantProps}
{...props}
id={`sidedrawer-field-${props.field.name}`}
id={`sidedrawer-field-${props.name}`}
label=""
hiddenLabel
//InputProps={{ disableUnderline: true }}

View File

@@ -1,5 +1,6 @@
import React, { lazy, useEffect } from "react";
import { Formik, Form as FormikForm, Field } from "formik";
import { useForm, useWatch } from "react-hook-form";
import { MuiPickersUtilsProvider } from "@material-ui/pickers";
import DateFnsUtils from "@date-io/date-fns";
import _isFunction from "lodash/isFunction";
@@ -144,8 +145,21 @@ export interface IFormProps {
export default function Form({ fields, values }: IFormProps) {
const initialValues = getInitialValues(fields);
const defaultValues = { ...initialValues, ...values };
const { sideDrawerRef } = useFiretableContext();
const { register, handleSubmit, watch, errors, control } = useForm({
mode: "onBlur",
defaultValues,
});
const onSubmit = data => {
console.log("SUBMIT", data);
};
// const watchAllFields = watch();
// useEffect(() => {console.log(watchAllFields)}, [watchAllFields]);
// const { sideDrawerRef } = useFiretableContext();
// useEffect(() => {
// const column = sideDrawerRef?.current?.cell?.column;
// if (!column) return;
@@ -159,15 +173,203 @@ export default function Form({ fields, values }: IFormProps) {
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Formik
enableReinitialize
initialValues={{ ...initialValues, ...values }}
onSubmit={(values, actions) => {
// Mark as submitted. We use Autosave instead.
actions.setSubmitting(false);
}}
<form
// enableReinitialize
onSubmit={handleSubmit(onSubmit)}
// onSubmit={(values, actions) => {
// // Mark as submitted. We use Autosave instead.
// actions.setSubmitting(false);
// }}
>
{({ values, errors }) => (
<AutosaveTwo control={control} defaultValues={defaultValues} />
<Grid container spacing={4} direction="column" wrap="nowrap">
<button type="submit">Submit</button>
{fields.map((_field, i) => {
// Call the field function with values if necessary
// Otherwise, just use the field object
const field: Field = _isFunction(_field) ? _field(values) : _field;
const { type, ...fieldProps } = field;
let _type = type;
if (field.config && field.config.renderFieldType) {
_type = field.config.renderFieldType;
}
// TODO: handle get initial field value for when a field is later
// shown to prevent uncontrolled components becoming controlled
let renderedField: React.ReactNode = null;
switch (_type) {
case FieldType.shortText:
case FieldType.longText:
case FieldType.email:
case FieldType.phone:
case FieldType.number:
renderedField = (
<Text {...fieldProps} hiddenLabel inputRef={register} />
);
break;
// case FieldType.url:
// renderedField = (
// <Field {...fieldProps} component={Url} hiddenLabel />
// );
// break;
// case FieldType.percentage:
// renderedField = (
// <Field
// {...fieldProps}
// component={Percentage}
// hiddenLabel
// />
// );
// break;
// case FieldType.singleSelect:
// renderedField = (
// <Field
// {...fieldProps}
// component={SingleSelect}
// hiddenLabel
// />
// );
// break;
// case FieldType.multiSelect:
// renderedField = (
// <Field
// {...fieldProps}
// component={MultiSelect}
// hiddenLabel
// />
// );
// break;
// case FieldType.date:
// renderedField = (
// <Field
// {...fieldProps}
// component={DatePicker}
// hiddenLabel
// />
// );
// break;
// case FieldType.dateTime:
// renderedField = (
// <Field
// {...fieldProps}
// component={DateTimePicker}
// hiddenLabel
// />
// );
// break;
// case FieldType.checkbox:
// renderedField = (
// <Checkbox {...fieldProps} name={fieldProps.name!} />
// );
// break;
// case FieldType.color:
// renderedField = <Field {...fieldProps} component={Color} />;
// break;
// case FieldType.slider:
// renderedField = (
// <Field {...fieldProps} component={Slider} />
// );
// break;
// case FieldType.richText:
// renderedField = (
// <Field {...fieldProps} component={RichText} />
// );
// break;
// case FieldType.image:
// renderedField = (
// <Field
// {...fieldProps}
// component={ImageUploader}
// docRef={values.ref}
// />
// );
// break;
// case FieldType.file:
// renderedField = (
// <Field
// {...fieldProps}
// component={FileUploader}
// docRef={values.ref}
// />
// );
// break;
// case FieldType.rating:
// renderedField = (
// <Field {...fieldProps} component={Rating} />
// );
// break;
// case FieldType.connectTable:
// renderedField = (
// <Field {...fieldProps} component={ConnectTable} />
// );
// break;
// case FieldType.subTable:
// renderedField = (
// <Field {...fieldProps} component={SubTable} />
// );
// break;
// case FieldType.action:
// renderedField = (
// <Field {...fieldProps} component={Action} />
// );
// break;
// case FieldType.json:
// renderedField = (
// <Field {...fieldProps} component={JsonEditor} />
// );
// break;
// case FieldType.code:
// renderedField = <Field {...fieldProps} component={Code} />;
// break;
case undefined:
default:
return null;
// default:
// break;
}
return (
<FieldWrapper
key={fieldProps.name ?? i}
type={_type}
name={field.name}
label={field.label}
>
{renderedField}
</FieldWrapper>
);
})}
<FieldWrapper
type="debug"
name="_ft_debug_path"
label="Document Path"
debugText={values.ref?.path ?? values.id ?? "No ref"}
/>
</Grid>
</form>
{/* {({ values, errors }) => (
<FormikForm>
<Autosave values={values} errors={errors} />
@@ -357,7 +559,13 @@ export default function Form({ fields, values }: IFormProps) {
</Grid>
</FormikForm>
)}
</Formik>
</Formik> */}
</MuiPickersUtilsProvider>
);
}
function AutosaveTwo({ control }: any) {
const watchAll = useWatch({ control });
console.log(watchAll);
return <>autosave2</>;
}

View File

@@ -11946,6 +11946,11 @@ react-fast-compare@^2.0.1:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
react-hook-form@^6.0.6:
version "6.0.6"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.0.6.tgz#72ac1668aeaddfd642bcfb324cebe1ba237fb13e"
integrity sha512-qxWhV++1V7SKKlr2hHFsessGwATCdexgVsByxOHltDyO9F0VWB1WN4ZvxnKuHTVGwjj6CLZo0mL+Hgy0QH1sAw==
react-input-autosize@^2.1.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.2.tgz#fcaa7020568ec206bc04be36f4eb68e647c4d8c2"