From 0f674badd93ca28116d45c090d881f8814c4b852 Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Sun, 8 Jun 2025 19:07:48 +0800 Subject: [PATCH] update demo-react-onboarding-ui, --- .../components/OnboardingSlide.tsx | 59 ++++++++++++ .../DemoReactOnboardingUi/pages/Home.css | 52 +++++++++++ .../DemoReactOnboardingUi/pages/Home.tsx | 89 +++++++++++++++++++ .../DemoReactOnboardingUi/theme/variables.css | 82 +++++++++++++++++ 4 files changed, 282 insertions(+) create mode 100644 03_source/mobile/src/pages/DemoReactOnboardingUi/components/OnboardingSlide.tsx create mode 100644 03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.css create mode 100644 03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.tsx create mode 100644 03_source/mobile/src/pages/DemoReactOnboardingUi/theme/variables.css diff --git a/03_source/mobile/src/pages/DemoReactOnboardingUi/components/OnboardingSlide.tsx b/03_source/mobile/src/pages/DemoReactOnboardingUi/components/OnboardingSlide.tsx new file mode 100644 index 0000000..b411ba7 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactOnboardingUi/components/OnboardingSlide.tsx @@ -0,0 +1,59 @@ +import { IonSlide, IonButton, IonGrid, IonRow, IonCol } from '@ionic/react'; +import '../pages/Home.css'; + +interface OnboardingSlideProps { + image: string; + mainSlide?: boolean; + finalSlide?: boolean; + title: string; + text: string; + lastSlide?: boolean; + sliderRef: React.RefObject; +} + +const OnboardingSlide = ({ + image, + mainSlide = false, + finalSlide = false, + title, + text, + lastSlide, + sliderRef, +}: OnboardingSlideProps): React.JSX.Element => { + return ( + + + + + +

{title}

+

{text}

+ + {mainSlide && ( + sliderRef.current.slideNext()} + > + Get started → + + )} + + {finalSlide && ( + <> + + Register + + + Login + + + )} +
+
+
+
+ ); +}; + +export default OnboardingSlide; diff --git a/03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.css b/03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.css new file mode 100644 index 0000000..3b02677 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.css @@ -0,0 +1,52 @@ +ion-slides { + + height: 100%; +} + +.slide-grid { + + height: 100%; +} + +.slide-main-image { + + height: 5rem !important; +} + +.slide-buttons { + + position: absolute; + bottom: 2rem; + z-index: 10; + + display: flex; + flex-direction: row; + justify-content: center; + width: 100%; + align-items: center; + align-content: center; +} + +.slide-content-container { + + margin-top: -4rem; +} + +.slide-content { + + margin: 0 auto; + /* margin-top: 5rem; */ + color: var(--ion-color-primary); + /* background-color: var(--ion-color-primary); */ + /* color: white; */ + border: 2px solid rgb(228, 228, 228); + border-radius: 15px; + padding: 3rem; + /* padding-left: 3rem; */ + /* padding-right: 3rem; */ +} + +.slide-content p { + + color: rgb(161, 161, 161); +} \ No newline at end of file diff --git a/03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.tsx b/03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.tsx new file mode 100644 index 0000000..238981f --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactOnboardingUi/pages/Home.tsx @@ -0,0 +1,89 @@ +import { IonButton, IonContent, IonIcon, IonPage, IonRow, IonSlides } from '@ionic/react'; +import { arrowBack, arrowForward } from 'ionicons/icons'; +import { useRef, useState } from 'react'; +import OnboardingSlide from '../components/OnboardingSlide'; +import './Home.css'; + +interface SlideContent { + image: string; + mainSlide?: boolean; + finalSlide?: boolean; + title: string; + text: string; +} + +const Home = (): React.JSX.Element => { + const sliderRef = useRef(null); + const [lastSlide, setLastSlide] = useState(false); + const [firstSlide, setFirstSlide] = useState(true); + + const slideContent: SlideContent[] = [ + { + image: '/assets/applogo1.png', + mainSlide: true, + title: 'Ionic Onboarding UI', + text: 'Share moments with your followers and experience memorable captures', + }, + { + image: '/assets/1sub.png', + title: 'Capture', + text: 'Capture that perfect moment in your life', + }, + { + image: '/assets/2sub.png', + title: 'Organize', + text: 'Organize photos exactly how you want them', + }, + { + image: '/assets/3sub.png', + title: 'Share', + finalSlide: true, + text: 'Are you ready to share your special moments online with the world?', + }, + ]; + + const checkSlides = async () => { + if (!sliderRef.current) return; + + const isLastSlide = await sliderRef.current.isEnd(); + const isFirstSlide = await sliderRef.current.isBeginning(); + setLastSlide(isLastSlide); + setFirstSlide(isFirstSlide); + }; + + return ( + + + + {slideContent.map((slide, index) => { + return ( + + ); + })} + + + + {!firstSlide && ( + sliderRef.current?.slidePrev()}> + + + )} + + {!lastSlide && ( + sliderRef.current?.slideNext()}> + + + )} + + + + ); +}; + +export default Home; diff --git a/03_source/mobile/src/pages/DemoReactOnboardingUi/theme/variables.css b/03_source/mobile/src/pages/DemoReactOnboardingUi/theme/variables.css new file mode 100644 index 0000000..5e720f4 --- /dev/null +++ b/03_source/mobile/src/pages/DemoReactOnboardingUi/theme/variables.css @@ -0,0 +1,82 @@ +/* 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; +} + +.swiper-pagination { + + margin-bottom: 1rem; +} \ No newline at end of file