Implement use cases page
This commit is contained in:
@@ -5,7 +5,7 @@ import { logger } from "../../../../lib/logger";
|
||||
import QuoteBlockView from "./QuoteBlock.view";
|
||||
import type { QuoteBlockProps, VariantConfig } from "./QuoteBlock.types";
|
||||
|
||||
/** Figma: portrait variants standard | compact | extended; statement = Section/Quote (22137:890679, copy scale 22135:889716 from md). */
|
||||
/** Figma: portrait variants standard | compact | extended; **`statement`** = Section/Quote (22137‑890679; **`lg`** single paragraph **21967‑24638** — About + use cases). */
|
||||
const QuoteBlockContainer = memo<QuoteBlockProps>(
|
||||
({
|
||||
variant: variantProp = "standard",
|
||||
@@ -19,7 +19,6 @@ const QuoteBlockContainer = memo<QuoteBlockProps>(
|
||||
fallbackAvatarSrc = "/assets/Quote_Avatar.svg",
|
||||
onError,
|
||||
}) => {
|
||||
const variant = variantProp;
|
||||
const [imageError, setImageError] = useState(false);
|
||||
const [imageLoading, setImageLoading] = useState(true);
|
||||
|
||||
@@ -86,12 +85,12 @@ const QuoteBlockContainer = memo<QuoteBlockProps>(
|
||||
},
|
||||
};
|
||||
|
||||
const config = variants[variant] || variants.standard;
|
||||
const config = variants[variantProp] || variants.standard;
|
||||
|
||||
// Use provided ID or generate a stable one based on content
|
||||
const baseId =
|
||||
id ||
|
||||
(variant === "statement"
|
||||
(variantProp === "statement"
|
||||
? "statement-quote"
|
||||
: `quote-${author.toLowerCase().replace(/\s+/g, "-")}`);
|
||||
const quoteId = `${baseId}-content`;
|
||||
@@ -124,7 +123,7 @@ const QuoteBlockContainer = memo<QuoteBlockProps>(
|
||||
};
|
||||
|
||||
// Validate required props
|
||||
if (variant === "statement") {
|
||||
if (variantProp === "statement") {
|
||||
if (!quote?.trim() || !quoteSecondary?.trim()) {
|
||||
logger.error(
|
||||
"QuoteBlock: statement variant requires non-empty quote and quoteSecondary",
|
||||
@@ -134,7 +133,7 @@ const QuoteBlockContainer = memo<QuoteBlockProps>(
|
||||
type: "missing_props",
|
||||
message:
|
||||
"QuoteBlock statement variant requires quote and quoteSecondary",
|
||||
quote: !!quote?.trim() && !!quoteSecondary?.trim(),
|
||||
quote: !!(quote?.trim() && quoteSecondary?.trim()),
|
||||
});
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -5,13 +5,11 @@ export type QuoteBlockVariantValue =
|
||||
| "statement";
|
||||
|
||||
export interface QuoteBlockProps {
|
||||
/** Default `standard` (home portrait quote). `statement` is About-only dual-paragraph layout; isolated branch in QuoteBlock.view. */
|
||||
/** Default `standard` (home portrait quote). **`statement`** = yellow Section / Quote (**About** + **`/use-cases`** — two paragraphs below **`lg`**, one paragraph from **`lg`**; [21967-24638](https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=21967-24638&m=dev)). */
|
||||
variant?: QuoteBlockVariantValue;
|
||||
className?: string;
|
||||
quote?: string;
|
||||
/**
|
||||
* Second paragraph for **`statement`** variant (Figma Section/Quote 22137:890679).
|
||||
*/
|
||||
/** Second paragraph for **`statement`** (Section/Quote); merged into one `<p>` from **`lg`**. */
|
||||
quoteSecondary?: string;
|
||||
author?: string;
|
||||
source?: string;
|
||||
@@ -39,7 +37,7 @@ export interface VariantConfig {
|
||||
source: string;
|
||||
showDecor: boolean;
|
||||
/**
|
||||
* When true, render Figma **Section/Quote** layout (yellow surface, dual paragraphs, no attribution).
|
||||
* When true, render Figma **Section/Quote** layout (yellow surface; stacked copy below **`lg`**, single paragraph from **`lg`**; no attribution).
|
||||
*/
|
||||
statementLayout?: boolean;
|
||||
}
|
||||
|
||||
@@ -26,15 +26,12 @@ function QuoteBlockView({
|
||||
const avatarAlt = t("avatarAlt").replace("{author}", author);
|
||||
|
||||
if (config.statementLayout) {
|
||||
if (!quoteSecondary?.trim()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const statementTextClass =
|
||||
"font-bricolage-grotesque text-[28px] font-bold leading-9 tracking-[var(--text-xx-large-heading--letter-spacing)] text-[var(--color-surface-default-tertiary)] md:text-[length:var(--text-xx-large-heading)] md:leading-[length:var(--text-xx-large-heading--line-height)]";
|
||||
|
||||
return (
|
||||
<section
|
||||
data-figma-node="21967-24638"
|
||||
className={`${config.container} ${className}`.trim()}
|
||||
aria-labelledby={quoteId}
|
||||
role="region"
|
||||
@@ -43,12 +40,18 @@ function QuoteBlockView({
|
||||
className="relative box-border flex w-full max-w-[1440px] shrink-0 flex-col items-center justify-center gap-[var(--space-800)] overflow-hidden rounded-[var(--spacing-scale-020)] bg-[var(--color-surface-invert-brand-primary,#fefcc9)] px-[var(--spacing-scale-032)] py-[var(--spacing-scale-048)] md:px-[var(--space-1800)] md:py-[var(--space-2400)]"
|
||||
>
|
||||
<QuoteStatementDecor />
|
||||
<div className="relative z-10 flex w-full min-w-0 shrink-0 flex-col items-center gap-9 text-center md:gap-[length:var(--text-xx-large-heading--line-height)]">
|
||||
<p id={quoteId} className={`${statementTextClass} mb-0 w-full min-w-0`}>
|
||||
{quote}
|
||||
</p>
|
||||
<p className={`${statementTextClass} mb-0 w-full min-w-0`}>
|
||||
{quoteSecondary}
|
||||
<div className="relative z-10 flex w-full min-w-0 shrink-0 flex-col items-center text-center">
|
||||
<p
|
||||
id={quoteId}
|
||||
className={`${statementTextClass} mb-0 flex w-full min-w-0 flex-col gap-9 text-center md:gap-[length:var(--text-xx-large-heading--line-height)] lg:block lg:gap-0`}
|
||||
>
|
||||
<span className="block lg:inline">{quote}</span>
|
||||
{quoteSecondary ? (
|
||||
<>
|
||||
<span className="hidden lg:inline">{" "}</span>
|
||||
<span className="block lg:inline">{quoteSecondary}</span>
|
||||
</>
|
||||
) : null}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { memo } from "react";
|
||||
import { getAssetPath, quoteStatementShapePath } from "../../../../lib/assetUtils";
|
||||
|
||||
/** Figma: Section / Quote — Shapes (22137:890679). Radial asset + horizontal gradient mask (side lobes only); grain matches QuoteBlock/HeroDecor. Background `cover` so wide banners still fill lateral mask stripes (square sized by panel height misses them when centered). */
|
||||
/** Figma: Section / Quote — **`shape-qoute.svg`** (22137:890679). */
|
||||
const EDGE_MASK =
|
||||
"linear-gradient(to right, #fff 0%, #fff 14%, rgba(255,255,255,0) 30%, rgba(255,255,255,0) 70%, #fff 86%, #fff 100%)";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user