Files
community-rule/app/components/content/ContentContainer/ContentContainer.container.tsx
T
adilallo ca928e306b Match the 3 Nov color ramps and size-based strokes, and replace leftover palette hex with tokens.
Drop Cookies Settings from the footer, link the Home features that already have pages, and give leftover routes their own descriptions.
2026-11-05 15:37:55 -07:00

140 lines
5.3 KiB
TypeScript

"use client";
/**
* Figma: "Components" / Container (19614-14838, 19003-23432).
* XS thumbnail copy: title 18/22, description 12/16, metadata 10/14.
*/
import { memo } from "react";
import {
contentBlogTagPath,
contentCatalogSlugForFallback,
CONTENT_CATALOG_SLUG_ORDER,
} from "../../../../lib/assetUtils";
import ContentContainerView from "./ContentContainer.view";
import type { ContentContainerProps } from "./ContentContainer.types";
const ContentContainerContainer = memo<ContentContainerProps>(
({
post,
width: widthProp,
size: sizeProp = "responsive",
tone: toneProp = "inverse",
leadingImageSrc,
leadingImageAlt,
showLeadingImage: showLeadingImageProp = true,
showByline: showBylineProp = true,
}) => {
const size = sizeProp;
const tone = toneProp;
const showLeadingImage = showLeadingImageProp;
const showByline = showBylineProp;
const width =
widthProp ?? (size === "useCase" ? "100%" : "200px");
const onLight = tone === "onLight";
const titleColor = onLight
? "text-[var(--color-content-default-primary)] group-hover:text-[var(--color-content-default-brand-primary)]"
: "text-[var(--color-content-invert-brand-navy)] group-hover:text-[var(--color-content-invert-brand-royal)]";
const bodyColor = onLight
? "text-[var(--color-content-default-secondary)]"
: "text-[var(--color-content-invert-brand-navy)]";
const getIconImage = (slug: string): string => {
const resolvedSlug =
CONTENT_CATALOG_SLUG_ORDER.indexOf(
slug as (typeof CONTENT_CATALOG_SLUG_ORDER)[number],
) >= 0
? slug
: contentCatalogSlugForFallback(slug);
return contentBlogTagPath(resolvedSlug);
};
const iconImage = leadingImageSrc ?? getIconImage(post.slug);
const iconAlt = leadingImageAlt ?? "";
const formattedDate = new Date(post.frontmatter.date).toLocaleDateString(
"en-US",
{
year: "numeric",
month: "long",
},
);
const isUseCase = size === "useCase";
const containerClasses =
size === "xs"
? "relative z-20 flex h-full flex-col gap-[var(--space-300)]"
: isUseCase
? "relative z-20 flex h-full w-full min-w-0 flex-col gap-[var(--space-600)]"
: "relative z-20 h-full flex flex-col gap-[var(--space-300)] sm:gap-[var(--space-400)] md:gap-[18px] lg:gap-[var(--space-600)]";
const contentGapClasses =
size === "xs"
? "flex flex-col gap-[var(--space-200)]"
: isUseCase
? "flex w-full min-w-0 flex-col gap-[var(--space-400)]"
: "flex flex-col gap-[var(--space-200)] sm:gap-[var(--space-300)] md:gap-[var(--space-200)] lg:gap-[var(--space-400)] xl:gap-[var(--space-100)]";
const textGapClasses =
size === "xs"
? "flex flex-col gap-[var(--space-100)]"
: isUseCase
? "flex w-full min-w-0 flex-col gap-[var(--space-100)]"
: "flex flex-col gap-[var(--space-100)] md:gap-[var(--space-050)] lg:gap-[var(--space-100)]";
const titleClasses =
size === "xs"
? `font-bricolage-grotesque font-medium text-[18px] leading-[22px] transition-colors ${titleColor}`
: isUseCase
? `w-full font-bricolage-grotesque font-medium text-[32px] leading-[110%] lg:text-medium-display transition-colors ${titleColor}`
: `font-bricolage-grotesque font-medium text-xx-small-display sm:text-x-small-display md:text-[32px] md:leading-[110%] lg:text-medium-display xl:text-x-large-display transition-colors ${titleColor}`;
const descriptionClasses =
size === "xs"
? `text-x-small-paragraph max-w-md ${bodyColor}`
: isUseCase
? `w-full text-small-paragraph lg:text-large-paragraph ${bodyColor}`
: `text-x-small-paragraph sm:text-small-paragraph md:text-small-paragraph lg:text-large-paragraph xl:text-x-large-paragraph ${bodyColor}`;
const authorClasses =
size === "xs"
? `overflow-hidden text-ellipsis whitespace-nowrap text-xx-small-paragraph ${bodyColor}`
: isUseCase
? `overflow-hidden text-ellipsis whitespace-nowrap text-x-small-paragraph lg:text-small-paragraph ${bodyColor}`
: `text-xx-small-paragraph md:text-x-small-paragraph lg:text-small-paragraph xl:text-large-paragraph ${bodyColor}`;
const dateClasses =
size === "xs"
? `overflow-hidden text-ellipsis whitespace-nowrap text-xx-small-paragraph ${bodyColor}`
: isUseCase
? `overflow-hidden text-ellipsis whitespace-nowrap text-x-small-paragraph lg:text-small-paragraph ${bodyColor}`
: `text-xx-small-paragraph md:text-x-small-paragraph lg:text-small-paragraph xl:text-large-paragraph ${bodyColor}`;
return (
<ContentContainerView
post={post}
width={width}
size={size}
tone={tone}
iconImage={iconImage}
iconAlt={iconAlt}
showLeadingImage={showLeadingImage}
showByline={showByline}
containerClasses={containerClasses}
contentGapClasses={contentGapClasses}
textGapClasses={textGapClasses}
titleClasses={titleClasses}
descriptionClasses={descriptionClasses}
authorClasses={authorClasses}
dateClasses={dateClasses}
formattedDate={formattedDate}
/>
);
},
);
ContentContainerContainer.displayName = "ContentContainer";
export default ContentContainerContainer;