105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
/* ============================================================================
|
|
Card.Horizontal - Figma 25:781 (720 x 200)
|
|
----------------------------------------------------------------------------
|
|
The listing row: a 240px image beside the text, image at the inline start so
|
|
it moves to the right in Arabic on its own. Stacks to a single column below
|
|
the sm breakpoint. Like Card.Content, the whole row is one link.
|
|
|
|
USAGE
|
|
-----
|
|
<ul className="flex flex-col gap-lg">
|
|
<Card.Horizontal
|
|
as="li"
|
|
href="/en/resources/governance-systems"
|
|
eyebrow="Dialogue report"
|
|
title="Strengthening Governance Systems"
|
|
excerpt="Our annual deep-dive reports focus on structural coordination,
|
|
bringing diverse multi-stakeholder views into policy discussions."
|
|
actionLabel="Read full report"
|
|
image={{ src: "/media/roundtable.jpg", alt: "" }}
|
|
/>
|
|
</ul>
|
|
|
|
// External resource - rendered as a plain anchor, not a client-side route.
|
|
<Card.Horizontal
|
|
href="https://example.org/report.pdf"
|
|
title="Annual review 2026"
|
|
actionLabel="Download"
|
|
/>
|
|
========================================================================= */
|
|
|
|
import {
|
|
CardActionHint,
|
|
CardEyebrow,
|
|
CardLink,
|
|
CardMedia,
|
|
CardShell,
|
|
cx,
|
|
} from "./CardShell";
|
|
import type { CardElement, CardImage, CardTitleElement } from "./types";
|
|
|
|
export interface CardHorizontalProps {
|
|
href: string;
|
|
title: string;
|
|
/** Label of the "Read full report" affordance - required, so Arabic cannot inherit English. */
|
|
actionLabel: string;
|
|
eyebrow?: string;
|
|
excerpt?: string;
|
|
image?: CardImage;
|
|
as?: CardElement;
|
|
titleAs?: CardTitleElement;
|
|
className?: string;
|
|
}
|
|
|
|
export function CardHorizontal({
|
|
href,
|
|
title,
|
|
actionLabel,
|
|
eyebrow,
|
|
excerpt,
|
|
image,
|
|
as = "article",
|
|
titleAs = "h3",
|
|
className,
|
|
}: CardHorizontalProps) {
|
|
const Title = titleAs;
|
|
|
|
return (
|
|
<CardShell
|
|
as={as}
|
|
linked
|
|
className={cx(
|
|
"flex-col overflow-hidden sm:flex-row sm:items-stretch",
|
|
className,
|
|
)}
|
|
>
|
|
{/* Stacked: the ratio reserves the height. Side by side: a fixed 240px
|
|
column that stretches to whatever the text column needs. */}
|
|
{image ? (
|
|
<CardMedia
|
|
image={image}
|
|
className="aspect-[6/5] w-full sm:aspect-auto sm:w-60 sm:shrink-0"
|
|
/>
|
|
) : null}
|
|
|
|
<div className="flex flex-1 flex-col justify-between gap-md p-lg">
|
|
<div className="flex flex-col gap-xs">
|
|
{eyebrow ? <CardEyebrow>{eyebrow}</CardEyebrow> : null}
|
|
|
|
<Title className="sh-card-title body-lg-bold text-text-primary">
|
|
<CardLink href={href} className="sh-card-link">
|
|
{title}
|
|
</CardLink>
|
|
</Title>
|
|
|
|
{excerpt ? (
|
|
<p className="body-sm text-text-secondary line-clamp-2">{excerpt}</p>
|
|
) : null}
|
|
</div>
|
|
|
|
<CardActionHint label={actionLabel} />
|
|
</div>
|
|
</CardShell>
|
|
);
|
|
}
|