Blocks

Layout 407

standard
1 ColumnText Align CenterImage/Video CenterImage/Video BottomImageButtons
Layout 407

Code

relume-layout407.tsx
"use client";

import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

type ImageProps = {
  src: string;
  alt?: string;
};

type TabTrigger = {
  heading: string;
  description: string;
};

type Tab = {
  value: string;
  trigger: TabTrigger;
  content: ImageProps[];
};

type Props = {
  tagline: string;
  heading: string;
  description: string;
  defaultTabValue: string;
  tabs: Tab[];
};

export type Layout407Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;

export const Layout407 = (props: Layout407Props) => {
  const { tagline, heading, description, defaultTabValue, tabs } = {
    ...Layout407Defaults,
    ...props,
  };

  return (
    <section className="px-[5%] py-16 md:py-24 lg:py-28">
      <div className="container">
        <div className="mb-12 md:mb-18 lg:mb-20">
          <div className="mx-auto max-w-lg text-center">
            <p className="mb-3 font-semibold md:mb-4">{tagline}</p>
            <h2 className="mb-5 text-h2 font-bold md:mb-6">{heading}</h2>
            <p className="text-medium">{description}</p>
          </div>
        </div>
        <Tabs defaultValue={defaultTabValue}>
          {tabs.map((tab, index) => (
            <TabsContent key={index} value={tab.value} className="data-[state=active]:animate-tabs">
              {tab.content.map((feature, featureIndex) => (
                <div key={featureIndex} className="w-full">
                  <img
                    src={feature.src}
                    className="size-full rounded-image object-cover"
                    alt={feature.alt}
                  />
                </div>
              ))}
            </TabsContent>
          ))}
          <TabsList className="mt-12 flex-col md:mt-16 md:flex-row">
            {tabs.map((tab, index) => (
              <TabsTrigger
                key={index}
                value={tab.value}
                className="w-full flex-col items-center justify-center rounded-none border-0 border-t-[1.5px] px-6 py-4 text-center whitespace-normal data-[state=active]:bg-transparent"
              >
                <h3 className="text-h6 font-bold">{tab.trigger.heading}</h3>
                <p>{tab.trigger.description}</p>
              </TabsTrigger>
            ))}
          </TabsList>
        </Tabs>
      </div>
    </section>
  );
};

export const Layout407Defaults: Props = {
  tagline: "Tagline",
  heading: "Medium length section heading goes here",
  description:
    "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.",
  defaultTabValue: "tab-one",
  tabs: [
    {
      value: "tab-one",
      trigger: {
        heading: "Short heading goes here",
        description:
          "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.",
      },
      content: [
        {
          src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
          alt: "Relume placeholder image 1",
        },
      ],
    },
    {
      value: "tab-two",
      trigger: {
        heading: "Short heading goes here",
        description:
          "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.",
      },
      content: [
        {
          src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
          alt: "Relume placeholder image 2",
        },
      ],
    },
    {
      value: "tab-three",
      trigger: {
        heading: "Short heading goes here",
        description:
          "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.",
      },
      content: [
        {
          src: "https://d22po4pjz3o32e.cloudfront.net/placeholder-image-landscape.svg",
          alt: "Relume placeholder image 3",
        },
      ],
    },
  ],
};

npm i @radix-ui/react-dialog @radix-ui/react-slot @radix-ui/react-tabs class-variance-authority@0.7.1 clsx@^2.1.1 motion@^12.15.0 relume-icons@1.3.0 tailwind-merge@^2.2.2