diff --git a/src/common/form/README.md b/src/common/form/README.md new file mode 100644 index 000000000..375dbd672 --- /dev/null +++ b/src/common/form/README.md @@ -0,0 +1,150 @@ +# Forms and validation + +## Form definition + +```tsx +import React from 'react' +import * as yup from 'yup' +import { useTranslation } from 'react-i18next' +import { Grid, TextField, Button } from '@material-ui/core' + +import { AlertStore } from 'stores/AlertStore' +import useForm, { translateError, customValidators } from 'common/form/useForm' + +export type FormData = { + email: string +} + +const validationSchema: yup.SchemaOf = yup.object().defined().shape({ + email: yup.string().email().required(), +}) + +const defaults: FormData = { + email: '', +} + +export type MyFormProps = { initialValues?: FormData } + +export default function MyForm({ initialValues = defaults }: MyFormProps) { + const { t } = useTranslation() + + const { formik } = useForm({ + initialValues, + validationSchema, + onSubmit: (values) => { + console.log(values) + }, + }) + + return ( +
+ + + + + + + + +
+ ) +} +``` + +## Form usage + +```tsx + + + +``` + +## Validation + +### Default translations + +Simple strings are mapped directly to their respective translation + +```json +{ + "invalid": "Field is invalid", + "required": "Required field" +} +``` + +```tsx +setLocale({ + mixed: { + default: 'validation:invalid', + required: 'validation:required', + }, + string: { + email: 'validation:email', + }, +}) +``` + +### Default translations with interpolation + +Complex translation keys are being evaluated upon translation + +```json +{ + "field-too-short": "Field should be at least {{min}} symbols", + "field-too-long": "Field should be maximum {{max}} symbols" +} +``` + +```tsx +setLocale({ + string: { + min: ({ min }: { min: number }) => ({ + key: 'validation:field-too-short', + values: { min }, + }), + max: ({ max }: { max: number }) => ({ + key: 'validation:field-too-long', + values: { max }, + }), + }, +}) +``` + +#### Custom translations in validation schema + +Commonly used translations with the same translation key + +```tsx +yup.string().min(6 customValidators.passwordMin) +``` + +#### Inline translations in validation schema + +Custom translations with keys defined right next to the form + +```tsx +const validationSchema: yup.SchemaOf = yup + .object() + .defined() + .shape({ + password: yup.string().min(6, ({ min }) => ({ + key: 'validation:password-min', + values: { min }, + })), + }) +```