From 3343ea68d51186ab4e234ab2cccc96e255f1feaf Mon Sep 17 00:00:00 2001 From: Alisa Cantillo-Olsson Date: Tue, 24 Mar 2026 18:00:11 +0100 Subject: [PATCH] split components into folders, add all home page sections --- relume-test/package-lock.json | 1 + relume-test/package.json | 1 + relume-test/src/App.tsx | 12 +- relume-test/src/components/Cta30.tsx | 79 ++ relume-test/src/components/Event17.tsx | 146 +++ relume-test/src/components/Event20.tsx | 151 +++ relume-test/src/components/Faq10.tsx | 100 ++ relume-test/src/{ => components}/Footer.tsx | 0 relume-test/src/components/Gallery19.tsx | 99 ++ relume-test/src/{ => components}/Header.tsx | 0 relume-test/src/{ => components}/Navbar.tsx | 0 relume-test/src/components/Pricing18.tsx | 104 ++ relume-test/src/pages/Home.tsx | 27 + relume-test/src/reactcomponents_home.jsx | 1242 +++++++++++++++++++ 14 files changed, 1952 insertions(+), 10 deletions(-) create mode 100644 relume-test/src/components/Cta30.tsx create mode 100644 relume-test/src/components/Event17.tsx create mode 100644 relume-test/src/components/Event20.tsx create mode 100644 relume-test/src/components/Faq10.tsx rename relume-test/src/{ => components}/Footer.tsx (100%) create mode 100644 relume-test/src/components/Gallery19.tsx rename relume-test/src/{ => components}/Header.tsx (100%) rename relume-test/src/{ => components}/Navbar.tsx (100%) create mode 100644 relume-test/src/components/Pricing18.tsx create mode 100644 relume-test/src/pages/Home.tsx create mode 100644 relume-test/src/reactcomponents_home.jsx diff --git a/relume-test/package-lock.json b/relume-test/package-lock.json index 6c1a95a..7b19dfd 100644 --- a/relume-test/package-lock.json +++ b/relume-test/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@relume_io/relume-tailwind": "^1.3.0", "@relume_io/relume-ui": "^1.3.1", + "clsx": "^2.1.1", "framer-motion": "^12.38.0", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/relume-test/package.json b/relume-test/package.json index 2cec436..7750f5a 100644 --- a/relume-test/package.json +++ b/relume-test/package.json @@ -12,6 +12,7 @@ "dependencies": { "@relume_io/relume-tailwind": "^1.3.0", "@relume_io/relume-ui": "^1.3.1", + "clsx": "^2.1.1", "framer-motion": "^12.38.0", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/relume-test/src/App.tsx b/relume-test/src/App.tsx index 5ab54e3..75666f8 100644 --- a/relume-test/src/App.tsx +++ b/relume-test/src/App.tsx @@ -1,15 +1,7 @@ -import { Navbar3 } from "./Navbar"; -import { Header1 } from "./Header"; -import { Footer3 } from "./Footer"; +import Home from "./pages/Home"; function App() { - return ( -
- - - -
- ); + return ; } export default App; \ No newline at end of file diff --git a/relume-test/src/components/Cta30.tsx b/relume-test/src/components/Cta30.tsx new file mode 100644 index 0000000..5fdfe5e --- /dev/null +++ b/relume-test/src/components/Cta30.tsx @@ -0,0 +1,79 @@ +import * as React from "react"; +import { useState } from "react"; +import { Button, Input } from "@relume_io/relume-ui"; +import type { ButtonProps } from "@relume_io/relume-ui"; + +type Props = { + heading: string; + description: string; + inputPlaceholder?: string; + button: ButtonProps; + termsAndConditions: string; + video: string; + videoType: string; +}; + +export type Cta30Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Cta30 = (props: Cta30Props) => { + const { heading, description, inputPlaceholder, button, termsAndConditions, video, videoType } = { + ...Cta30Defaults, + ...props, + }; + + const [emailInput, setEmailInput] = useState(""); + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + console.log({ emailInput }); + }; + + return ( +
+
+

+ {heading} +

+

{description}

+
+
+ setEmailInput(e.target.value)} + /> + +
+
+
+
+
+ +
+
+
+ ); +}; + +export const Cta30Defaults: Props = { + heading: "Medium length heading goes here", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.", + inputPlaceholder: "Enter your email", + button: { title: "Sign up", variant: "primary", size: "sm" }, + termsAndConditions: ` +

+ By clicking Sign Up you're confirming that you agree with our + Terms and Conditions. +

+ `, + video: "https://d22po4pjz3o32e.cloudfront.net/placeholder-video.mp4", + videoType: "video/mp4", +}; \ No newline at end of file diff --git a/relume-test/src/components/Event17.tsx b/relume-test/src/components/Event17.tsx new file mode 100644 index 0000000..cf41079 --- /dev/null +++ b/relume-test/src/components/Event17.tsx @@ -0,0 +1,146 @@ +import * as React from "react"; +import type { ButtonProps } from "@relume_io/relume-ui"; +import { Button } from "@relume_io/relume-ui"; +import { RxChevronRight } from "react-icons/rx"; +import { BiMap, BiCalendarAlt } from "react-icons/bi"; + +type ImageProps = { + src: string; + alt?: string; +}; + +type Date = { + weekday: string; + day: string; + month: string; + year: string; +}; + +type FeaturedEvent = { + url: string; + image: ImageProps; + date: Date; + category: string; + title: string; + location: string; + description: string; + button: ButtonProps; +}; + +type Props = { + tagline: string; + heading: string; + description: string; + button: ButtonProps; + featuredEvents: FeaturedEvent[]; +}; + +export type Event17Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Event17 = (props: Event17Props) => { + const { tagline, heading, description, button, featuredEvents } = { + ...Event17Defaults, + ...props, + }; + return ( +
+
+
+

{tagline}

+

{heading}

+

{description}

+
+
+ {featuredEvents.map((event, index) => ( + + ))} +
+
+ +
+
+
+ ); +}; + +const FeaturedEvent: React.FC = ({ + url, image, date, category, title, location, description, button, +}) => { + return ( +
+ + {image.alt} + + {category} + + +
+
+
+ + {date.weekday} {date.day} {date.month} {date.year} +
+
+ + {location} +
+
+ +

{title}

+
+

{description}

+ +
+
+ ); +}; + +export const Event17Defaults: Props = { + tagline: "Tagline", + heading: "Events", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + button: { variant: "secondary", size: "primary", title: "View all" }, + featuredEvents: [ + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 1", + }, + date: { weekday: "Fri", day: "09", month: "Feb", year: "2024" }, + category: "Category", + title: "Event title heading", + location: "Location", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 2", + }, + date: { weekday: "Sat", day: "10", month: "Feb", year: "2024" }, + category: "Category", + title: "Event title heading", + location: "Location", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 3", + }, + date: { weekday: "Sun", day: "11", month: "Feb", year: "2024" }, + category: "Category", + title: "Event title heading", + location: "Location", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + ], +}; \ No newline at end of file diff --git a/relume-test/src/components/Event20.tsx b/relume-test/src/components/Event20.tsx new file mode 100644 index 0000000..cd69fb0 --- /dev/null +++ b/relume-test/src/components/Event20.tsx @@ -0,0 +1,151 @@ +import * as React from "react"; +import type { ButtonProps } from "@relume_io/relume-ui"; +import { Button } from "@relume_io/relume-ui"; +import { RxChevronRight } from "react-icons/rx"; +import { BiMap, BiCalendarAlt } from "react-icons/bi"; + +type ImageProps = { + src: string; + alt?: string; +}; + +type Date = { + weekday: string; + day: string; + month: string; + year: string; +}; + +type FeaturedEvent = { + url: string; + image: ImageProps; + date: Date; + category: string; + title: string; + location: string; + description: string; + button: ButtonProps; +}; + +type Props = { + tagline: string; + heading: string; + description: string; + button: ButtonProps; + featuredEvents: FeaturedEvent[]; +}; + +export type Event20Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Event20 = (props: Event20Props) => { + const { tagline, heading, description, button, featuredEvents } = { + ...Event20Defaults, + ...props, + }; + return ( +
+
+
+
+

{tagline}

+

{heading}

+

{description}

+
+ +
+
+ {featuredEvents.map((event, index) => ( + + ))} +
+
+ +
+
+
+ ); +}; + +const FeaturedEvent: React.FC = ({ + url, image, date, category, title, location, description, button, +}) => { + return ( +
+ + {image.alt} + + {category} + + +
+
+
+ + {date.weekday} {date.day} {date.month} {date.year} +
+
+ + {location} +
+
+ +

{title}

+
+

{description}

+ +
+
+ ); +}; + +export const Event20Defaults: Props = { + tagline: "Tagline", + heading: "Events", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + button: { variant: "secondary", size: "primary", title: "View all" }, + featuredEvents: [ + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 1", + }, + date: { weekday: "Fri", day: "09", month: "Feb", year: "2024" }, + category: "Category", + title: "Event title heading", + location: "Location", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 2", + }, + date: { weekday: "Sat", day: "10", month: "Feb", year: "2024" }, + category: "Category", + title: "Event title heading", + location: "Location", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 3", + }, + date: { weekday: "Sun", day: "11", month: "Feb", year: "2024" }, + category: "Category", + title: "Event title heading", + location: "Location", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + ], +}; \ No newline at end of file diff --git a/relume-test/src/components/Faq10.tsx b/relume-test/src/components/Faq10.tsx new file mode 100644 index 0000000..51ae1f3 --- /dev/null +++ b/relume-test/src/components/Faq10.tsx @@ -0,0 +1,100 @@ +import * as React from "react"; +import { + Button, + Accordion, + AccordionTrigger, + AccordionContent, + AccordionItem, +} from "@relume_io/relume-ui"; +import type { ButtonProps } from "@relume_io/relume-ui"; + +type QuestionsProps = { + title: string; + answer: string; +}; + +type Props = { + heading: string; + description: string; + footerHeading: string; + footerDescription: string; + button: ButtonProps; + questions: QuestionsProps[]; +}; + +export type Faq10Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Faq10 = (props: Faq10Props) => { + const { heading, description, questions, footerHeading, footerDescription, button } = { + ...Faq10Defaults, + ...props, + }; + + const halfLength = Math.ceil(questions.length / 2); + const firstColumnQuestions = questions.slice(0, halfLength); + const secondColumnQuestions = questions.slice(halfLength); + + return ( +
+
+
+

+ {heading} +

+

{description}

+
+
+ + {firstColumnQuestions.map((question, index) => ( + + {question.title} + {question.answer} + + ))} + + + {secondColumnQuestions.map((question, index) => ( + + {question.title} + {question.answer} + + ))} + +
+
+

+ {footerHeading} +

+

{footerDescription}

+
+ +
+
+
+
+ ); +}; + +export const Faq10Defaults: Props = { + heading: "FAQs", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.", + questions: [ + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + { title: "Question text goes here", answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere." }, + ], + footerHeading: "Still have questions?", + footerDescription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + button: { title: "Contact", variant: "secondary" }, +}; \ No newline at end of file diff --git a/relume-test/src/Footer.tsx b/relume-test/src/components/Footer.tsx similarity index 100% rename from relume-test/src/Footer.tsx rename to relume-test/src/components/Footer.tsx diff --git a/relume-test/src/components/Gallery19.tsx b/relume-test/src/components/Gallery19.tsx new file mode 100644 index 0000000..14b7247 --- /dev/null +++ b/relume-test/src/components/Gallery19.tsx @@ -0,0 +1,99 @@ +import * as React from "react"; +import { useState, useEffect } from "react"; +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@relume_io/relume-ui"; +import type { CarouselApi } from "@relume_io/relume-ui"; +import clsx from "clsx"; + +type ImageProps = { + src: string; + alt?: string; +}; + +type Props = { + heading: string; + description: string; + images: ImageProps[]; +}; + +export type Gallery19Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Gallery19 = (props: Gallery19Props) => { + const { heading, description, images } = { + ...Gallery19Defaults, + ...props, + }; + + const [api, setApi] = useState(); + const [current, setCurrent] = useState(0); + + useEffect(() => { + if (!api) return; + setCurrent(api.selectedScrollSnap() + 1); + api.on("select", () => { + setCurrent(api.selectedScrollSnap() + 1); + }); + }, [api]); + + return ( +
+
+
+
+

+ {heading} +

+

{description}

+
+ +
+ + {images.map((image, index) => ( + +
+ {image.alt} +
+
+ ))} +
+ + +
+
+ {images.map((_, index) => ( +
+
+
+
+
+ ); +}; + +export const Gallery19Defaults: Props = { + heading: "Image Gallery", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + images: [ + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 1" }, + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 2" }, + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 3" }, + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 4" }, + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 5" }, + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 6" }, + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 7" }, + { src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", alt: "Relume placeholder image 8" }, + ], +}; \ No newline at end of file diff --git a/relume-test/src/Header.tsx b/relume-test/src/components/Header.tsx similarity index 100% rename from relume-test/src/Header.tsx rename to relume-test/src/components/Header.tsx diff --git a/relume-test/src/Navbar.tsx b/relume-test/src/components/Navbar.tsx similarity index 100% rename from relume-test/src/Navbar.tsx rename to relume-test/src/components/Navbar.tsx diff --git a/relume-test/src/components/Pricing18.tsx b/relume-test/src/components/Pricing18.tsx new file mode 100644 index 0000000..c02c354 --- /dev/null +++ b/relume-test/src/components/Pricing18.tsx @@ -0,0 +1,104 @@ +import * as React from "react"; +import { Button } from "@relume_io/relume-ui"; +import type { ButtonProps } from "@relume_io/relume-ui"; +import { BiCheck } from "react-icons/bi"; + +type PricingPlan = { + planName: string; + monthlyPrice: string; + yearlyPrice: string; + features: string[]; + button: ButtonProps; +}; + +type Props = { + tagline: string; + heading: string; + description: string; + pricingPlans: PricingPlan[]; +}; + +export type Pricing18Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Pricing18 = (props: Pricing18Props) => { + const { tagline, heading, description, pricingPlans } = { + ...Pricing18Defaults, + ...props, + }; + return ( +
+
+
+

{tagline}

+

+ {heading} +

+

{description}

+
+
+ {pricingPlans.map((plan, index) => ( +
+
+
+
{plan.planName}
+

+ {plan.monthlyPrice} + /mo +

+

or {plan.yearlyPrice} yearly

+
+
+ {plan.features.map((feature, index) => ( +
+
+ +
+

{feature}

+
+ ))} +
+
+
+ +
+
+ ))} +
+
+
+ ); +}; + +export const Pricing18Defaults: Props = { + tagline: "Tagline", + heading: "Pricing plan", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + pricingPlans: [ + { + planName: "Basic plan", + monthlyPrice: "$19", + yearlyPrice: "$199", + features: ["Feature text goes here", "Feature text goes here", "Feature text goes here"], + button: { title: "Get started" }, + }, + { + planName: "Business plan", + monthlyPrice: "$29", + yearlyPrice: "$299", + features: ["Feature text goes here", "Feature text goes here", "Feature text goes here", "Feature text goes here"], + button: { title: "Get started" }, + }, + { + planName: "Enterprise plan", + monthlyPrice: "$49", + yearlyPrice: "$499", + features: ["Feature text goes here", "Feature text goes here", "Feature text goes here", "Feature text goes here", "Feature text goes here"], + button: { title: "Get started" }, + }, + ], +}; \ No newline at end of file diff --git a/relume-test/src/pages/Home.tsx b/relume-test/src/pages/Home.tsx new file mode 100644 index 0000000..4ef4373 --- /dev/null +++ b/relume-test/src/pages/Home.tsx @@ -0,0 +1,27 @@ +import { Navbar3 } from "../components/Navbar"; +import { Header1 } from "../components/Header"; +import { Event17 } from "../components/Event17"; +import { Gallery19 } from "../components/Gallery19"; +import { Cta30 } from "../components/Cta30"; +import { Event20 } from "../components/Event20"; +import { Pricing18 } from "../components/Pricing18"; +import { Faq10 } from "../components/Faq10"; +import { Footer3 } from "../components/Footer"; + +export const Home = () => { + return ( +
+ + + + + + + + + +
+ ); +}; + +export default Home; \ No newline at end of file diff --git a/relume-test/src/reactcomponents_home.jsx b/relume-test/src/reactcomponents_home.jsx new file mode 100644 index 0000000..718a571 --- /dev/null +++ b/relume-test/src/reactcomponents_home.jsx @@ -0,0 +1,1242 @@ +"use client"; + +import { useState } from "react"; +import { Button, useMediaQuery } from "@relume_io/relume-ui"; +import type { ButtonProps } from "@relume_io/relume-ui"; +import { AnimatePresence, motion } from "framer-motion"; +import { RxChevronDown } from "react-icons/rx"; + +type ImageProps = { + url?: string; + src: string; + alt?: string; +}; + +type NavLink = { + url: string; + title: string; + subMenuLinks?: NavLink[]; +}; + +type Props = { + logo: ImageProps; + navLinks: NavLink[]; + buttons: ButtonProps[]; +}; + +export type Navbar3Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Navbar3 = (props: Navbar3Props) => { + const { logo, navLinks, buttons } = { + ...Navbar3Defaults, + ...props, + }; + const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); + const isMobile = useMediaQuery("(max-width: 991px)"); + + return ( +
+ + + + + {logo.alt} + + {navLinks.map((navLink, index) => ( +
+ {navLink.subMenuLinks && navLink.subMenuLinks.length > 0 ? ( + + ) : ( + + {navLink.title} + + )} +
+ ))} +
+ {buttons.map((button, index) => ( + + ))} +
+
+ {isMobileMenuOpen && ( + setIsMobileMenuOpen(false)} + /> + )} +
+ + {logo.alt} + +
+
+ {buttons.map((button, index) => ( + + ))} +
+
+
+ ); +}; + +const SubMenu = ({ navLink, isMobile }: { navLink: NavLink; isMobile: boolean }) => { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + + return ( +
!isMobile && setIsDropdownOpen(true)} + onMouseLeave={() => !isMobile && setIsDropdownOpen(false)} + > + + {isDropdownOpen && ( + + + {navLink.subMenuLinks?.map((subMenuLink, index) => ( + + {subMenuLink.title} + + ))} + + + )} +
+ ); +}; + +export const Navbar3Defaults: Props = { + logo: { + url: "#", + src: "https://d22po4pjz3o32e.cloudfront.net/logo-image.svg", + alt: "Logo image", + }, + navLinks: [ + { title: "Link One", url: "#" }, + { title: "Link Two", url: "#" }, + { + title: "Link Three", + url: "#", + subMenuLinks: [ + { title: "Link Four", url: "#" }, + { title: "Link Five", url: "#" }, + { title: "Link Six", url: "#" }, + ], + }, + ], + buttons: [ + { + title: "Button", + size: "sm", + }, + ], +}; + + + + +import * as React from "react"; +import type { ButtonProps } from "@relume_io/relume-ui"; +import { Button } from "@relume_io/relume-ui"; +import { RxChevronRight } from "react-icons/rx"; +import { BiMap, BiCalendarAlt } from "react-icons/bi"; + +type ImageProps = { + src: string; + alt?: string; +}; + +type Date = { + weekday: string; + day: string; + month: string; + year: string; +}; + +type FeaturedEvent = { + url: string; + image: ImageProps; + date: Date; + category: string; + title: string; + location: string; + description: string; + button: ButtonProps; +}; + +type Props = { + tagline: string; + heading: string; + description: string; + button: ButtonProps; + featuredEvents: FeaturedEvent[]; +}; + +export type Event17Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Event17 = (props: Event17Props) => { + const { tagline, heading, description, button, featuredEvents } = { + ...Event17Defaults, + ...props, + }; + return ( +
+
+
+

{tagline}

+

{heading}

+

{description}

+
+
+ {featuredEvents.map((event, index) => ( + + ))} +
+
+ +
+
+
+ ); +}; + +const FeaturedEvent: React.FC = ({ + url, + image, + date, + category, + title, + location, + description, + button, +}) => { + return ( +
+ + {image.alt} + + {category} + + +
+
+
+ + {date.weekday} {date.day} {date.month} {date.year} +
+
+ + {location} +
+
+ +

{title}

+
+

{description}

+ +
+
+ ); +}; + +export const Event17Defaults: Props = { + tagline: "Tagline", + heading: "Events", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + button: { + variant: "secondary", + size: "primary", + title: "View all", + }, + featuredEvents: [ + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 1", + }, + date: { + weekday: "Fri", + day: "09", + month: "Feb", + year: "2024", + }, + category: "Category", + title: "Event title heading", + location: "Location", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 2", + }, + date: { + weekday: "Sat", + day: "10", + month: "Feb", + year: "2024", + }, + category: "Category", + title: "Event title heading", + location: "Location", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 3", + }, + date: { + weekday: "Sun", + day: "11", + month: "Feb", + year: "2024", + }, + category: "Category", + title: "Event title heading", + location: "Location", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + ], +}; + + + + +"use client"; + +import { useState, useEffect } from "react"; +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@relume_io/relume-ui"; +import type { CarouselApi } from "@relume_io/relume-ui"; +import clsx from "clsx"; + +type ImageProps = { + src: string; + alt?: string; +}; + +type Props = { + heading: string; + description: string; + images: ImageProps[]; +}; + +export type Gallery19Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Gallery19 = (props: Gallery19Props) => { + const { heading, description, images } = { + ...Gallery19Defaults, + ...props, + }; + + const [api, setApi] = useState(); + const [current, setCurrent] = useState(0); + + useEffect(() => { + if (!api) { + return; + } + setCurrent(api.selectedScrollSnap() + 1); + api.on("select", () => { + setCurrent(api.selectedScrollSnap() + 1); + }); + }, [api]); + + return ( +
+
+
+
+

+ {heading} +

+

{description}

+
+ {/* for all available options: https://www.embla-carousel.com/api/options/ */} + +
+ + {images.map((image, index) => ( + +
+ {image.alt} +
+
+ ))} +
+ + +
+
+ {images.map((_, index) => ( +
+
+
+
+
+ ); +}; + +export const Gallery19Defaults: Props = { + heading: "Image Gallery", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + images: [ + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 1", + }, + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 2", + }, + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 3", + }, + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 4", + }, + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 5", + }, + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 6", + }, + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 7", + }, + { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image.svg", + alt: "Relume placeholder image 8", + }, + ], +}; + + + + +"use client"; + +import { useState } from "react"; +import { Button, Input } from "@relume_io/relume-ui"; +import type { ButtonProps } from "@relume_io/relume-ui"; + +type Props = { + heading: string; + description: string; + inputPlaceholder?: string; + button: ButtonProps; + termsAndConditions: string; + video: string; + videoType: string; +}; + +export type Cta30Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Cta30 = (props: Cta30Props) => { + const { heading, description, inputPlaceholder, button, termsAndConditions, video, videoType } = { + ...Cta30Defaults, + ...props, + }; + + const [emailInput, setEmailInput] = useState(""); + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + console.log({ + emailInput, + }); + }; + + return ( +
+
+

+ {heading} +

+

{description}

+
+
+ setEmailInput(e.target.value)} + /> + +
+
+
+
+
+ +
+
+
+ ); +}; + +export const Cta30Defaults: Props = { + heading: "Medium length heading goes here", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.", + inputPlaceholder: "Enter your email", + button: { + title: "Sign up", + variant: "primary", + size: "sm", + }, + termsAndConditions: ` +

+ By clicking Sign Up you're confirming that you agree with our + Terms and Conditions. +

+ `, + video: "https://d22po4pjz3o32e.cloudfront.net/placeholder-video.mp4", + videoType: "video/mp4", +}; + + + + +import * as React from "react"; +import type { ButtonProps } from "@relume_io/relume-ui"; +import { Button } from "@relume_io/relume-ui"; +import { RxChevronRight } from "react-icons/rx"; +import { BiMap, BiCalendarAlt } from "react-icons/bi"; + +type ImageProps = { + src: string; + alt?: string; +}; + +type Date = { + weekday: string; + day: string; + month: string; + year: string; +}; + +type FeaturedEvent = { + url: string; + image: ImageProps; + date: Date; + category: string; + title: string; + location: string; + description: string; + button: ButtonProps; +}; + +type Props = { + tagline: string; + heading: string; + description: string; + button: ButtonProps; + featuredEvents: FeaturedEvent[]; +}; + +export type Event20Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Event20 = (props: Event20Props) => { + const { tagline, heading, description, button, featuredEvents } = { + ...Event20Defaults, + ...props, + }; + return ( +
+
+
+
+

{tagline}

+

{heading}

+

{description}

+
+ +
+
+ {featuredEvents.map((event, index) => ( + + ))} +
+
+ +
+
+
+ ); +}; + +const FeaturedEvent: React.FC = ({ + url, + image, + date, + category, + title, + location, + description, + button, +}) => { + return ( +
+ + {image.alt} + + {category} + + +
+
+
+ + {date.weekday} {date.day} {date.month} {date.year} +
+
+ + {location} +
+
+ +

{title}

+
+

{description}

+ +
+
+ ); +}; + +export const Event20Defaults: Props = { + tagline: "Tagline", + heading: "Events", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + button: { + variant: "secondary", + size: "primary", + title: "View all", + }, + featuredEvents: [ + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 1", + }, + date: { + weekday: "Fri", + day: "09", + month: "Feb", + year: "2024", + }, + category: "Category", + title: "Event title heading", + location: "Location", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 2", + }, + date: { + weekday: "Sat", + day: "10", + month: "Feb", + year: "2024", + }, + category: "Category", + title: "Event title heading", + location: "Location", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + { + url: "#", + image: { + src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg", + alt: "Relume placeholder image 3", + }, + date: { + weekday: "Sun", + day: "11", + month: "Feb", + year: "2024", + }, + category: "Category", + title: "Event title heading", + location: "Location", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.", + button: { title: "View event", variant: "link", size: "link", iconRight: }, + }, + ], +}; + + + + +import { Button } from "@relume_io/relume-ui"; +import type { ButtonProps } from "@relume_io/relume-ui"; +import { BiCheck } from "react-icons/bi"; + +type PricingPlan = { + planName: string; + monthlyPrice: string; + yearlyPrice: string; + features: string[]; + button: ButtonProps; +}; + +type Props = { + tagline: string; + heading: string; + description: string; + pricingPlans: PricingPlan[]; +}; + +export type Pricing18Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Pricing18 = (props: Pricing18Props) => { + const { tagline, heading, description, pricingPlans } = { + ...Pricing18Defaults, + ...props, + }; + return ( +
+
+
+

{tagline}

+

+ {heading} +

+

{description}

+
+
+ {pricingPlans.map((plan, index) => ( +
+
+
+
{plan.planName}
+

+ {plan.monthlyPrice} + /mo +

+

or {plan.yearlyPrice} yearly

+
+
+ {plan.features.map((feature, index) => ( +
+
+ +
+

{feature}

+
+ ))} +
+
+
+ +
+
+ ))} +
+
+
+ ); +}; + +export const Pricing18Defaults: Props = { + tagline: "Tagline", + heading: "Pricing plan", + description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + pricingPlans: [ + { + planName: "Basic plan", + monthlyPrice: "$19", + yearlyPrice: "$199", + features: ["Feature text goes here", "Feature text goes here", "Feature text goes here"], + button: { title: "Get started" }, + }, + { + planName: "Business plan", + monthlyPrice: "$29", + yearlyPrice: "$299", + features: [ + "Feature text goes here", + "Feature text goes here", + "Feature text goes here", + "Feature text goes here", + ], + button: { title: "Get started" }, + }, + { + planName: "Enterprise plan", + monthlyPrice: "$49", + yearlyPrice: "$499", + features: [ + "Feature text goes here", + "Feature text goes here", + "Feature text goes here", + "Feature text goes here", + "Feature text goes here", + ], + button: { title: "Get started" }, + }, + ], +}; + + + + +import { + Button, + Accordion, + AccordionTrigger, + AccordionContent, + AccordionItem, +} from "@relume_io/relume-ui"; +import type { ButtonProps } from "@relume_io/relume-ui"; + +type QuestionsProps = { + title: string; + answer: string; +}; + +type Props = { + heading: string; + description: string; + footerHeading: string; + footerDescription: string; + button: ButtonProps; + questions: QuestionsProps[]; +}; + +export type Faq10Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Faq10 = (props: Faq10Props) => { + const { heading, description, questions, footerHeading, footerDescription, button } = { + ...Faq10Defaults, + ...props, + }; + + const halfLength = Math.ceil(questions.length / 2); + const firstColumnQuestions = questions.slice(0, halfLength); + const secondColumnQuestions = questions.slice(halfLength); + + return ( +
+
+
+

+ {heading} +

+

{description}

+
+
+ + {firstColumnQuestions.map((question, index) => ( + + {question.title} + {question.answer} + + ))} + + + {secondColumnQuestions.map((question, index) => ( + + {question.title} + {question.answer} + + ))} + +
+
+

+ {footerHeading} +

+

{footerDescription}

+
+ +
+
+
+
+ ); +}; + +export const Faq10Defaults: Props = { + heading: "FAQs", + description: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.", + questions: [ + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + { + title: "Question text goes here", + answer: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.", + }, + ], + footerHeading: "Still have questions?", + footerDescription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + button: { + title: "Contact", + variant: "secondary", + }, +}; + + + + +import { FaXTwitter } from "react-icons/fa6"; +import { + BiLogoFacebookCircle, + BiLogoInstagram, + BiLogoLinkedinSquare, + BiLogoYoutube, +} from "react-icons/bi"; + +type ImageProps = { + url?: string; + src: string; + alt?: string; +}; + +type Links = { + title: string; + url: string; +}; + +type SocialMediaLinks = { + url: string; + icon: React.ReactNode; +}; + +type ColumnLinks = { + links: Links[]; +}; + +type Address = { + label: string; + value: string; +}; + +type Contact = { + label: string; + phone: string; + email: string; +}; + +type Props = { + logo: ImageProps; + address: Address; + contact: Contact; + columnLinks: ColumnLinks[]; + socialMediaLinks: SocialMediaLinks[]; + footerText?: string; + footerLinks: Links[]; +}; + +export type Footer3Props = React.ComponentPropsWithoutRef<"section"> & Partial; + +export const Footer3 = (props: Footer3Props) => { + const { logo, address, contact, columnLinks, socialMediaLinks, footerText, footerLinks } = { + ...Footer3Defaults, + ...props, + }; + return ( +
+
+
+
+
+ + {logo.alt} + +
+
+
+

{address.label}

+

{address.value}

+
+
+

{contact.label}

+

+ {contact.phone} + {contact.email} +

+
+
+
+ {socialMediaLinks.map((link, index) => ( + + {link.icon} + + ))} +
+
+
+ {columnLinks.map((column, index) => ( +
    + {column.links.map((link, linkIndex) => ( +
  • + {link.title} +
  • + ))} +
+ ))} +
+
+
+
+

{footerText}

+
    + {footerLinks.map((link, index) => ( +
  • + {link.title} +
  • + ))} +
+
+
+
+ ); +}; + +export const Footer3Defaults: Props = { + logo: { + url: "#", + src: "https://d22po4pjz3o32e.cloudfront.net/logo-image.svg", + alt: "Logo image", + }, + address: { + label: "Address:", + value: "Level 1, 12 Sample St, Sydney NSW 2000", + }, + contact: { + label: "Contact:", + phone: "1800 123 4567", + email: "info@relume.io", + }, + columnLinks: [ + { + links: [ + { title: "Link One", url: "#" }, + { title: "Link Two", url: "#" }, + { title: "Link Three", url: "#" }, + { title: "Link Four", url: "#" }, + { title: "Link Five", url: "#" }, + ], + }, + { + links: [ + { title: "Link Six", url: "#" }, + { title: "Link Seven", url: "#" }, + { title: "Link Eight", url: "#" }, + { title: "Link Nine", url: "#" }, + { title: "Link Ten", url: "#" }, + ], + }, + ], + socialMediaLinks: [ + { url: "#", icon: }, + { url: "#", icon: }, + { url: "#", icon: }, + { url: "#", icon: }, + { url: "#", icon: }, + ], + footerText: "© 2024 Relume. All rights reserved.", + footerLinks: [ + { title: "Privacy Policy", url: "#" }, + { title: "Terms of Service", url: "#" }, + { title: "Cookies Settings", url: "#" }, + ], +};