From beb1e0ae6895543f4f95ae526d6817cedcc2a406 Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Fri, 6 Jun 2025 22:27:14 +0800 Subject: [PATCH] update react hook form example, --- .../pages/DemoReactHookFormExample/index.tsx | 28 ++-- .../DemoReactHookFormExample/module.d.ts | 9 ++ .../DemoReactHookFormExample/pages/Home.scss | 0 .../DemoReactHookFormExample/pages/Home.tsx | 126 ++++++++++++++++++ .../theme/variables.scss | 79 +++++++++++ 5 files changed, 229 insertions(+), 13 deletions(-) create mode 100644 03_source/mobile/src/pages/DemoReactHookFormExample/module.d.ts create mode 100644 03_source/mobile/src/pages/DemoReactHookFormExample/pages/Home.scss create mode 100644 03_source/mobile/src/pages/DemoReactHookFormExample/pages/Home.tsx create mode 100644 03_source/mobile/src/pages/DemoReactHookFormExample/theme/variables.scss diff --git a/03_source/mobile/src/pages/DemoReactHookFormExample/index.tsx b/03_source/mobile/src/pages/DemoReactHookFormExample/index.tsx index e5b0304..88d41f2 100644 --- a/03_source/mobile/src/pages/DemoReactHookFormExample/index.tsx +++ b/03_source/mobile/src/pages/DemoReactHookFormExample/index.tsx @@ -1,30 +1,31 @@ -import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } from '@ionic/react'; +import { IonRouterOutlet, IonTabs } from '@ionic/react'; -import { cloudOutline, searchOutline } from 'ionicons/icons'; import { Route, Redirect } from 'react-router'; -import Tab1 from './AppPages/Tab1'; -import Tab2 from './AppPages/Tab2'; +// import Tab1 from './AppPages/Tab1'; +// import Tab2 from './AppPages/Tab2'; import './style.scss'; +import Home from './pages/Home'; function DemoReactHookFormExample() { return ( - + - - - - - + + - + - {/* */} + {/* - + Dashboard @@ -33,6 +34,7 @@ function DemoReactHookFormExample() { Search + */} ); } diff --git a/03_source/mobile/src/pages/DemoReactHookFormExample/module.d.ts b/03_source/mobile/src/pages/DemoReactHookFormExample/module.d.ts new file mode 100644 index 0000000..4af7be7 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactHookFormExample/module.d.ts @@ -0,0 +1,9 @@ +declare module '*.module.css' { + const classes: { readonly [key: string]: string }; + export default classes; +} + +declare module '*.module.scss' { + const classes: { readonly [key: string]: string }; + export default classes; +} diff --git a/03_source/mobile/src/pages/DemoReactHookFormExample/pages/Home.scss b/03_source/mobile/src/pages/DemoReactHookFormExample/pages/Home.scss new file mode 100644 index 0000000..e69de29 diff --git a/03_source/mobile/src/pages/DemoReactHookFormExample/pages/Home.tsx b/03_source/mobile/src/pages/DemoReactHookFormExample/pages/Home.tsx new file mode 100644 index 0000000..340bb48 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactHookFormExample/pages/Home.tsx @@ -0,0 +1,126 @@ +import { + IonButton, + IonButtons, + IonCardSubtitle, + IonContent, + IonHeader, + IonIcon, + IonInput, + IonItem, + IonLabel, + IonPage, + IonTitle, + IonToolbar, + useIonRouter, +} from '@ionic/react'; +import './Home.scss'; +import { useForm } from 'react-hook-form'; + +import { alertCircleOutline, chevronBackOutline } from 'ionicons/icons'; +import React from 'react'; + +const Home = (): React.JSX.Element => { + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + mode: 'onTouched', + reValidateMode: 'onChange', + }); + + const fields = [ + { + label: 'Firstname', + required: true, + requiredOptions: { + maxLength: 10, + }, + props: { + name: 'firstname', + type: 'text', + placeholder: 'Enter a username', + }, + }, + + { + label: 'Age', + required: true, + requiredOptions: { + min: 18, + max: 99, + }, + props: { + name: 'age', + type: 'number', + inputmode: 'numeric', + placeholder: 'Enter your age', + }, + }, + ]; + + console.log(errors); + + const onSubmit = (data) => { + console.log(data); + }; + + const router = useIonRouter(); + function handleBackClick() { + router.goBack(); + } + + return ( + + + + React Hook Form + + + handleBackClick()}> + + + + + + + + + React Hook Form + + + + + An example using React Hook Form + + +
+ {fields.map((field, index) => { + const { label, required, requiredOptions, props } = field; + + return ( + + <> + {label} + + + {required && errors[props.name] && ( + + )} + + ); + })} + + + Submit + +
+
+
+ ); +}; + +export default Home; diff --git a/03_source/mobile/src/pages/DemoReactHookFormExample/theme/variables.scss b/03_source/mobile/src/pages/DemoReactHookFormExample/theme/variables.scss new file mode 100644 index 0000000..9173d58 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactHookFormExample/theme/variables.scss @@ -0,0 +1,79 @@ +.demo-react-hook-form-example { + /* Ionic Variables and Theming. For more info, please see: +http://ionicframework.com/docs/theming/ */ + + /** Ionic CSS Variables **/ + :root { + /** primary **/ + --ion-color-primary: #3880ff; + --ion-color-primary-rgb: 56, 128, 255; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255, 255, 255; + --ion-color-primary-shade: #3171e0; + --ion-color-primary-tint: #4c8dff; + + /** secondary **/ + --ion-color-secondary: #3dc2ff; + --ion-color-secondary-rgb: 61, 194, 255; + --ion-color-secondary-contrast: #ffffff; + --ion-color-secondary-contrast-rgb: 255, 255, 255; + --ion-color-secondary-shade: #36abe0; + --ion-color-secondary-tint: #50c8ff; + + /** tertiary **/ + --ion-color-tertiary: #5260ff; + --ion-color-tertiary-rgb: 82, 96, 255; + --ion-color-tertiary-contrast: #ffffff; + --ion-color-tertiary-contrast-rgb: 255, 255, 255; + --ion-color-tertiary-shade: #4854e0; + --ion-color-tertiary-tint: #6370ff; + + /** success **/ + --ion-color-success: #2dd36f; + --ion-color-success-rgb: 45, 211, 111; + --ion-color-success-contrast: #ffffff; + --ion-color-success-contrast-rgb: 255, 255, 255; + --ion-color-success-shade: #28ba62; + --ion-color-success-tint: #42d77d; + + /** warning **/ + --ion-color-warning: #ffc409; + --ion-color-warning-rgb: 255, 196, 9; + --ion-color-warning-contrast: #000000; + --ion-color-warning-contrast-rgb: 0, 0, 0; + --ion-color-warning-shade: #e0ac08; + --ion-color-warning-tint: #ffca22; + + /** danger **/ + --ion-color-danger: #eb445a; + --ion-color-danger-rgb: 235, 68, 90; + --ion-color-danger-contrast: #ffffff; + --ion-color-danger-contrast-rgb: 255, 255, 255; + --ion-color-danger-shade: #cf3c4f; + --ion-color-danger-tint: #ed576b; + + /** dark **/ + --ion-color-dark: #222428; + --ion-color-dark-rgb: 34, 36, 40; + --ion-color-dark-contrast: #ffffff; + --ion-color-dark-contrast-rgb: 255, 255, 255; + --ion-color-dark-shade: #1e2023; + --ion-color-dark-tint: #383a3e; + + /** medium **/ + --ion-color-medium: #92949c; + --ion-color-medium-rgb: 146, 148, 156; + --ion-color-medium-contrast: #ffffff; + --ion-color-medium-contrast-rgb: 255, 255, 255; + --ion-color-medium-shade: #808289; + --ion-color-medium-tint: #9d9fa6; + + /** light **/ + --ion-color-light: #f4f5f8; + --ion-color-light-rgb: 244, 245, 248; + --ion-color-light-contrast: #000000; + --ion-color-light-contrast-rgb: 0, 0, 0; + --ion-color-light-shade: #d7d8da; + --ion-color-light-tint: #f5f6f9; + } +}