From 58353ab6a0fff21c08b051961d2d6cb781c2198c Mon Sep 17 00:00:00 2001 From: Martin Oppitz Date: Thu, 19 Oct 2023 05:45:41 +0200 Subject: [PATCH 1/2] add validation --- package.json | 3 +- pnpm-lock.yaml | 29 +++++++++++++++ src/App.tsx | 95 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 113 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index f509ad8..9de2e7a 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "@public-ui/theme-default": "2.0.0-rc.0", "formik": "2.4.5", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "yup": "1.3.2" }, "devDependencies": { "@types/react": "^18.2.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93b1f54..e4d6d9b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + yup: + specifier: 1.3.2 + version: 1.3.2 devDependencies: '@types/react': @@ -2063,6 +2066,10 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + dev: false + /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} @@ -2229,6 +2236,10 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /tiny-case@1.0.3: + resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + dev: false + /tiny-warning@1.0.3: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} dev: false @@ -2245,6 +2256,10 @@ packages: is-number: 7.0.0 dev: true + /toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + dev: false + /totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -2275,6 +2290,11 @@ packages: engines: {node: '>=10'} dev: true + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: false + /typescript@5.2.2: resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} engines: {node: '>=14.17'} @@ -2409,3 +2429,12 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /yup@1.3.2: + resolution: {integrity: sha512-6KCM971iQtJ+/KUaHdrhVr2LDkfhBtFPRnsG1P8F4q3uUVQ2RfEM9xekpha9aA4GXWJevjM10eDcPQ1FfWlmaQ==} + dependencies: + property-expr: 2.0.6 + tiny-case: 1.0.3 + toposort: 2.0.2 + type-fest: 2.19.0 + dev: false diff --git a/src/App.tsx b/src/App.tsx index be31f3f..62542bc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,4 @@ +import { InputTypeOnDefault, Iso8601 } from "@public-ui/components"; import { KolButton, KolHeading, @@ -5,10 +6,11 @@ import { KolInputNumber, KolInputText, } from "@public-ui/react"; +import { Formik, useFormikContext } from "formik"; +import { useEffect, useMemo, useState } from "react"; +import * as Yup from "yup"; import "./App.css"; import { ErrorList } from "./ErrorList"; -import { InputTypeOnDefault, Iso8601 } from "@public-ui/components"; -import { Formik, useFormikContext } from "formik"; type FormValues = { date: Iso8601 | null; @@ -26,8 +28,38 @@ const initialValues: FormValues = { phone: "", }; +const terminSchema = { + date: Yup.string().required("Bitte Datum wählen."), + time: Yup.string().required("Bitte Zeit wählen."), + numberOfPersons: Yup.number() + .required("Bitte Personenanzahl wählen.") + .max(8, "Maximal 8 Personen."), +}; + +const contactSchema = { + name: Yup.string().required("Bitte Nachname eingeben."), + phone: Yup.string().required("Bitte Telefon eingeben."), +}; + function Form() { const form = useFormikContext(); + const [errorList, setErrorList] = useState({ + ...form.errors, + }); + + const showErrorList = useMemo( + () => Object.keys(errorList).length > 0, + [errorList] + ); + + useEffect(() => { + if (errorList) { + const errorList = document.getElementById("error-list"); + if (errorList) { + errorList.focus(); + } + } + }, [errorList]); const createOnChange = (name: keyof FormValues): InputTypeOnDefault => { return { @@ -39,52 +71,82 @@ function Form() { }; }; + // Hack to trigger validation on mount + useEffect(() => { + form.handleSubmit(); + }, []); + + const onSubmit = () => { + console.log(form.errors); + form.handleSubmit(); + setErrorList({ + ...form.errors, + }); + }; + return (
{ - form.handleSubmit(); - }} + onSubmit={onSubmit} onReset={() => { + setErrorList({}); form.handleReset(); + form.handleSubmit(); // Hack to trigger validation on reset }} > -
- -
+ {showErrorList && ( +
+ +
+ )}

@@ -95,20 +157,27 @@ function Form() { />
-
{JSON.stringify(form.values, null, 2)}
); } +const validationSchema = Yup.object().shape({ + ...terminSchema, + ...contactSchema, +}); + function App() { + const onSubmit = (values: FormValues) => { + console.log("Valid form to sumbit", values); + }; + return (
initialValues={initialValues} - onSubmit={(values) => { - console.log(values); - }} + onSubmit={onSubmit} + validationSchema={validationSchema} >
From 83716e99066baefa1d10a5f7c0b290b5a3d280df Mon Sep 17 00:00:00 2001 From: Martin Oppitz Date: Thu, 19 Oct 2023 05:48:24 +0200 Subject: [PATCH 2/2] update --- src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 62542bc..d6fa6d1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -112,8 +112,8 @@ function Form() {