c7e3048c09
CI Pipeline / test (20) (pull_request) Successful in 3m13s
CI Pipeline / test (18) (pull_request) Successful in 3m57s
CI Pipeline / e2e (firefox) (pull_request) Successful in 5m6s
CI Pipeline / e2e (webkit) (pull_request) Successful in 5m16s
CI Pipeline / e2e (chromium) (pull_request) Successful in 14m47s
CI Pipeline / performance (pull_request) Successful in 4m32s
CI Pipeline / storybook (pull_request) Successful in 1m35s
CI Pipeline / visual-regression (pull_request) Failing after 9m55s
CI Pipeline / lint (pull_request) Failing after 49s
CI Pipeline / build (pull_request) Successful in 1m48s
211 lines
9.2 KiB
TypeScript
211 lines
9.2 KiB
TypeScript
"use client";
|
|
|
|
import React, { memo } from "react";
|
|
import Button from "./Button";
|
|
import { getAssetPath } from "../../lib/assetUtils";
|
|
|
|
interface ContentLockupProps {
|
|
title?: string;
|
|
subtitle?: string;
|
|
description?: string;
|
|
ctaText?: string;
|
|
ctaHref?: string;
|
|
buttonClassName?: string;
|
|
variant?: "hero" | "feature" | "learn" | "ask" | "ask-inverse";
|
|
linkText?: string;
|
|
linkHref?: string;
|
|
alignment?: "center" | "left";
|
|
}
|
|
|
|
interface VariantStyle {
|
|
container: string;
|
|
textContainer: string;
|
|
titleGroup: string;
|
|
titleContainer: string;
|
|
title: string;
|
|
subtitle: string;
|
|
description?: string;
|
|
shape: string;
|
|
}
|
|
|
|
const ContentLockup = memo<ContentLockupProps>(
|
|
({
|
|
title,
|
|
subtitle,
|
|
description,
|
|
ctaText,
|
|
buttonClassName = "",
|
|
variant = "hero",
|
|
linkText,
|
|
linkHref,
|
|
alignment = "center",
|
|
}) => {
|
|
// Variant-specific styling
|
|
const variantStyles: Record<string, VariantStyle> = {
|
|
hero: {
|
|
container:
|
|
"flex flex-col gap-[var(--spacing-scale-006)] sm:gap-[var(--spacing-scale-012)] md:gap-[var(--spacing-scale-020)] lg:gap-[var(--spacing-scale-020)] relative z-10",
|
|
textContainer:
|
|
"flex flex-col md:gap-[var(--spacing-scale-004)] lg:gap-[var(--spacing-scale-008)] xl:gap-[var(--spacing-scale-020)]",
|
|
titleGroup: "flex flex-col xl:gap-0",
|
|
titleContainer:
|
|
"flex gap-[var(--spacing-scale-008)] xl:gap-[var(--spacing-scale-010)] items-center",
|
|
title:
|
|
"font-bricolage-grotesque font-medium text-[32px] leading-[32px] sm:text-[52px] sm:leading-[52px] md:text-[44px] md:leading-[44px] lg:text-[64px] lg:leading-[64px] xl:text-[96px] xl:leading-[110%] text-[var(--color-content-inverse-primary)]",
|
|
subtitle:
|
|
"font-bricolage-grotesque font-medium text-[32px] leading-[32px] sm:text-[52px] sm:leading-[52px] md:text-[44px] md:leading-[44px] lg:text-[64px] lg:leading-[64px] xl:text-[96px] xl:leading-[110%] text-[var(--color-content-inverse-primary)]",
|
|
description:
|
|
"font-inter font-normal text-[18px] leading-[130%] lg:text-[24px] lg:leading-[32px] xl:text-[32px] xl:leading-[40px] text-[var(--color-content-inverse-primary)]",
|
|
shape:
|
|
"w-[27.2px] h-[27.2px] md:w-[34px] md:h-[34px] lg:w-[50px] lg:h-[50px]",
|
|
},
|
|
feature: {
|
|
container: "flex flex-col gap-[var(--spacing-scale-012)] relative z-10",
|
|
textContainer: "flex flex-col gap-[var(--spacing-scale-012)]",
|
|
titleGroup: "flex flex-col gap-[var(--spacing-scale-012)]",
|
|
titleContainer: "flex gap-[var(--spacing-scale-008)] items-center",
|
|
title:
|
|
"font-bricolage-grotesque font-medium text-[32px] leading-[130%] tracking-[0] text-[var(--color-content-default-primary)]",
|
|
subtitle:
|
|
"font-space-grotesk font-normal text-[20px] leading-[130%] tracking-[0] text-[var(--color-content-default-primary)]",
|
|
description:
|
|
"font-inter font-normal text-[16px] leading-[140%] lg:text-[18px] lg:leading-[150%] xl:text-[20px] xl:leading-[160%] text-[var(--color-content-secondary)]",
|
|
shape:
|
|
"w-[20px] h-[20px] md:w-[24px] md:h-[24px] lg:w-[28px] lg:h-[28px]",
|
|
},
|
|
learn: {
|
|
container:
|
|
"flex flex-col gap-[var(--spacing-scale-012)] relative z-10 pt-[var(--spacing-scale-016)] pb-[var(--spacing-scale-016)] px-[var(--spacing-scale-020)] sm:pt-[var(--spacing-scale-040)] sm:pb-0 md:pt-[var(--spacing-scale-056)] md:px-[var(--spacing-scale-032)] lg:pt-[var(--spacing-scale-056)] lg:px-[var(--spacing-scale-064)]",
|
|
textContainer:
|
|
"flex flex-col gap-[var(--spacing-scale-012)] md:gap-[var(--spacing-scale-016)]",
|
|
titleGroup:
|
|
"flex flex-col gap-[var(--spacing-scale-012)] md:gap-[var(--spacing-scale-016)] lg:gap-[var(--spacing-scale-008)]",
|
|
titleContainer: "flex gap-[var(--spacing-scale-008)] items-center",
|
|
title:
|
|
"font-bricolage-grotesque font-medium text-[28px] leading-[36px] tracking-[0] md:text-[44px] md:leading-[110%] lg:text-[52px] text-[var(--color-content-default-primary)]",
|
|
subtitle:
|
|
"font-space-grotesk font-normal text-[16px] leading-[24px] tracking-[0] lg:text-[24px] lg:leading-[28px] text-[var(--color-content-default-primary)]",
|
|
description:
|
|
"font-inter font-normal text-[16px] leading-[140%] lg:text-[18px] lg:leading-[150%] xl:text-[20px] xl:leading-[160%] text-[var(--color-content-secondary)]",
|
|
shape:
|
|
"w-[20px] h-[20px] md:w-[24px] md:h-[24px] lg:w-[28px] lg:h-[28px]",
|
|
},
|
|
ask: {
|
|
container: "flex flex-col gap-[var(--spacing-scale-008)] relative z-10",
|
|
textContainer: "flex flex-col gap-[var(--spacing-scale-008)]",
|
|
titleGroup: "flex flex-col gap-[var(--spacing-scale-008)]",
|
|
titleContainer: "flex gap-[var(--spacing-scale-008)] items-center",
|
|
title:
|
|
"font-bricolage-grotesque font-medium text-[36px] leading-[110%] tracking-[0] md:text-[44px] md:leading-[110%] xl:text-[52px] xl:leading-[110%] text-[var(--color-content-default-brand-primary)]",
|
|
subtitle:
|
|
"font-inter font-normal text-[18px] leading-[130%] tracking-[0] md:text-[24px] md:leading-[32px] text-[var(--color-content-default-primary)]",
|
|
shape:
|
|
"w-[16px] h-[16px] md:w-[20px] md:h-[20px] lg:w-[24px] lg:h-[24px]",
|
|
},
|
|
"ask-inverse": {
|
|
container: "flex flex-col gap-[var(--spacing-scale-008)] relative z-10",
|
|
textContainer: "flex flex-col gap-[var(--spacing-scale-008)]",
|
|
titleGroup: "flex flex-col gap-[var(--spacing-scale-008)]",
|
|
titleContainer: "flex gap-[var(--spacing-scale-008)] items-center",
|
|
title:
|
|
"font-bricolage-grotesque font-medium text-[36px] leading-[110%] tracking-[0] md:text-[44px] md:leading-[110%] xl:text-[52px] xl:leading-[110%] text-[var(--color-content-inverse-primary)]",
|
|
subtitle:
|
|
"font-inter font-normal text-[18px] leading-[130%] tracking-[0] md:text-[24px] md:leading-[32px] text-[var(--color-content-inverse-primary)]",
|
|
shape:
|
|
"w-[16px] h-[16px] md:w-[20px] md:h-[20px] lg:w-[24px] lg:h-[24px]",
|
|
},
|
|
};
|
|
|
|
const styles = variantStyles[variant] || variantStyles.hero;
|
|
|
|
return (
|
|
<div className={styles.container}>
|
|
{variant === "ask" || variant === "ask-inverse" ? (
|
|
/* Simplified structure for ask variant */
|
|
<div
|
|
className={`${styles.titleGroup} ${
|
|
alignment === "left" ? "text-left" : "text-center"
|
|
}`}
|
|
>
|
|
<div
|
|
className={`${styles.titleContainer} ${
|
|
alignment === "left" ? "justify-start" : "justify-center"
|
|
}`}
|
|
>
|
|
<h1 className={styles.title}>{title}</h1>
|
|
</div>
|
|
<h2 className={styles.subtitle}>{subtitle}</h2>
|
|
</div>
|
|
) : (
|
|
/* Full structure for other variants */
|
|
<div className={styles.textContainer}>
|
|
{/* Title and subtitle group */}
|
|
<div className={styles.titleGroup}>
|
|
{/* Title container */}
|
|
<div className={styles.titleContainer}>
|
|
<h1 className={styles.title}>{title}</h1>
|
|
{variant === "hero" && (
|
|
<img
|
|
src={getAssetPath("assets/Shapes_1.svg")}
|
|
alt=""
|
|
className={styles.shape}
|
|
role="presentation"
|
|
/>
|
|
)}
|
|
</div>
|
|
|
|
{/* Subtitle */}
|
|
<h2 className={styles.subtitle}>{subtitle}</h2>
|
|
</div>
|
|
|
|
{/* Description */}
|
|
{description && <p className={styles.description}>{description}</p>}
|
|
</div>
|
|
)}
|
|
|
|
{/* Link for feature variant */}
|
|
{variant === "feature" && linkText && (
|
|
<a
|
|
href={linkHref || "#"}
|
|
className="font-inter font-medium text-[16px] leading-[20px] underline text-[var(--color-content-default-primary)] hover:text-gray-300 transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--color-surface-default-brand-royal)] focus:ring-offset-2 focus:ring-offset-[#171717] rounded-sm px-1 py-0.5"
|
|
>
|
|
{linkText}
|
|
</a>
|
|
)}
|
|
|
|
{/* CTA Button */}
|
|
{ctaText && (
|
|
<div className="flex justify-start">
|
|
{/* Small button for xsm and sm breakpoints */}
|
|
<div className="block md:hidden">
|
|
<Button variant="primary" size="small">
|
|
{ctaText}
|
|
</Button>
|
|
</div>
|
|
{/* Large button for md and lg breakpoints */}
|
|
<div className="hidden md:block xl:hidden">
|
|
<Button
|
|
variant="primary"
|
|
size="large"
|
|
className={buttonClassName}
|
|
>
|
|
{ctaText}
|
|
</Button>
|
|
</div>
|
|
{/* XLarge button for xl breakpoint */}
|
|
<div className="hidden xl:block">
|
|
<Button variant="primary" size="xlarge">
|
|
{ctaText}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
},
|
|
);
|
|
|
|
ContentLockup.displayName = "ContentLockup";
|
|
|
|
export default ContentLockup;
|