Match the Learn guide grid to the frames, and put the tag and small Rule on the guide card.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
9ea3f9fd0a
commit
4b0d15e89b
8 files changed
+99
-12
No files matched your search
@@ -32,6 +32,20 @@ export const metadata: Metadata = routeMetadata("/learn", {
|
||||
|
||||
const CASE_STUDY_TILE_RADIUS_CLASS = "rounded-[23.093px]";
|
||||
|
||||
/** Figma card grid: 1 column below 640, 2 from 640, 3 from 1024, 4 from 1440. */
|
||||
const ARTICLE_GRID_CLASS = [
|
||||
"flex flex-col gap-[var(--space-050)]",
|
||||
"md:flex-row md:flex-wrap md:justify-center md:gap-[var(--space-400)]",
|
||||
"md:px-[var(--space-1200)] md:py-[var(--space-600)]",
|
||||
"lg:px-[var(--space-1800)] lg:pt-[var(--space-800)] lg:pb-[var(--space-1800)]",
|
||||
"[&>*]:min-w-0 [&>*]:w-full",
|
||||
"md:[&>*]:w-[calc((100%-var(--space-400))/2)]",
|
||||
"lg:[&>*]:w-[calc((100%-2*var(--space-400))/3)]",
|
||||
"xl:[&>*]:w-[calc((100%-3*var(--space-400))/4)]",
|
||||
].join(" ");
|
||||
|
||||
const GUIDE_TAG_SRC = "/content/blog/how-communityrule-works-tag.svg";
|
||||
|
||||
const CASE_STUDY_LINK_CLASS = [
|
||||
CASE_STUDY_TILE_RADIUS_CLASS,
|
||||
"block shrink-0 cursor-pointer outline-none transition-[opacity,transform] duration-200",
|
||||
@@ -163,14 +177,14 @@ export default function LearnPage() {
|
||||
|
||||
<div
|
||||
data-testid="learn-article-grid"
|
||||
className="flex flex-col space-y-[var(--space-050)] sm:space-y-[var(--space-200)] sm:px-[var(--space-500)] sm:pt-[var(--space-600)] sm:pb-[var(--space-600)] smd:flex-row smd:flex-wrap smd:justify-center smd:gap-[var(--space-200)] smd:space-y-0 smd:px-[var(--space-500)] smd:pt-[var(--space-600)] smd:pb-[var(--space-600)] md:gap-[var(--space-400)] md:px-[var(--space-800)] xmd:gap-[var(--space-300)] lg:gap-[var(--space-400)] lg:px-[var(--space-1800)] lg:pt-[var(--space-800)] lg:pb-[var(--space-1800)] lg2:gap-x-[var(--space-400)] lg2:gap-y-[var(--space-600)] xl:gap-x-[var(--space-400)] xl:gap-y-[var(--space-400)] [&>*]:min-w-0 [&>*]:w-full smd:[&>*]:w-[calc((100%-var(--space-200))/2)] md:[&>*]:w-[calc((100%-var(--space-400))/2)] xmd:[&>*]:w-[calc((100%-2*var(--space-300))/3)] lg:[&>*]:w-[calc((100%-2*var(--space-400))/3)] lg2:[&>*]:w-[calc((100%-3*var(--space-400))/4)] xl:[&>*]:w-[calc((100%-4*var(--space-400))/5)]"
|
||||
className={ARTICLE_GRID_CLASS}
|
||||
>
|
||||
<ContentThumbnailTemplate
|
||||
post={guidePost}
|
||||
variant="responsive"
|
||||
href={page.guideCard.href}
|
||||
showByline={false}
|
||||
showLeadingImage={false}
|
||||
leadingImageSrc={GUIDE_TAG_SRC}
|
||||
leadingImageAlt=""
|
||||
/>
|
||||
{articlePosts.map((post) => (
|
||||
|
||||
+3
-1
@@ -24,6 +24,7 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
|
||||
showByline = true,
|
||||
showLeadingImage = true,
|
||||
leadingImageAlt,
|
||||
leadingImageSrc,
|
||||
}) => {
|
||||
const variant = variantProp;
|
||||
const sizing = sizingProp;
|
||||
@@ -56,7 +57,7 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
|
||||
};
|
||||
|
||||
// For "responsive", emit both orientations so the <picture> source can
|
||||
// swap at smd without a second card in the DOM.
|
||||
// swap at md (640px) without a second card in the DOM.
|
||||
const backgroundImage =
|
||||
variant === "responsive"
|
||||
? getBackgroundImage(post, "horizontal")
|
||||
@@ -78,6 +79,7 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
|
||||
showByline={showByline}
|
||||
showLeadingImage={showLeadingImage}
|
||||
leadingImageAlt={leadingImageAlt}
|
||||
leadingImageSrc={leadingImageSrc}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -11,8 +11,8 @@ export interface ContentThumbnailTemplateProps {
|
||||
post: BlogPost;
|
||||
className?: string;
|
||||
/**
|
||||
* vertical | horizontal — single layout. responsive — horizontal at <smd,
|
||||
* vertical at ≥smd (Learn grid); single card, viewport-swapped via <picture>.
|
||||
* vertical | horizontal — single layout. responsive — horizontal below md
|
||||
* (640px), vertical from md up (Learn grid); one card, swapped via <picture>.
|
||||
*/
|
||||
variant?: ContentThumbnailTemplateVariantValue;
|
||||
/**
|
||||
@@ -28,6 +28,8 @@ export interface ContentThumbnailTemplateProps {
|
||||
showLeadingImage?: boolean;
|
||||
/** Alt for the tag mark. Empty when the mark repeats the title. */
|
||||
leadingImageAlt?: string;
|
||||
/** Tag mark source. Falls back to the catalog tag for the post slug. */
|
||||
leadingImageSrc?: string;
|
||||
}
|
||||
|
||||
export interface ContentThumbnailTemplateViewProps {
|
||||
@@ -42,4 +44,5 @@ export interface ContentThumbnailTemplateViewProps {
|
||||
showByline: boolean;
|
||||
showLeadingImage: boolean;
|
||||
leadingImageAlt?: string;
|
||||
leadingImageSrc?: string;
|
||||
}
|
||||
@@ -14,18 +14,19 @@ function ContentThumbnailTemplateView({
|
||||
showByline,
|
||||
showLeadingImage,
|
||||
leadingImageAlt,
|
||||
leadingImageSrc,
|
||||
}: ContentThumbnailTemplateViewProps) {
|
||||
if (variant === "responsive") {
|
||||
// Single card; <picture> swaps the orientation-specific image at smd
|
||||
// (530px), aspect-ratio and content positioning switch via Tailwind.
|
||||
// Single card; <picture> swaps to the vertical image at md (640px),
|
||||
// which is where Learn's grid goes from one landscape card to two.
|
||||
return (
|
||||
<Link href={href} className={`group block w-full ${className}`}>
|
||||
<div className="relative aspect-[320/225.5] w-full overflow-hidden smd:aspect-[260/390]">
|
||||
<div className="relative aspect-[320/225.5] w-full overflow-hidden md:aspect-[260/390]">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<picture>
|
||||
{backgroundImageSmd ? (
|
||||
<source
|
||||
media="(min-width: 530px)"
|
||||
media="(min-width: 640px)"
|
||||
srcSet={backgroundImageSmd}
|
||||
/>
|
||||
) : null}
|
||||
@@ -37,13 +38,14 @@ function ContentThumbnailTemplateView({
|
||||
/>
|
||||
</picture>
|
||||
</div>
|
||||
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] max-h-[48%] overflow-hidden smd:left-[6.923%] smd:top-[4.615%] smd:w-[76.923%]">
|
||||
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] max-h-[68%] overflow-hidden md:left-[6.923%] md:top-[4.615%] md:max-h-[48%] md:w-[76.923%]">
|
||||
<ContentContainer
|
||||
post={post}
|
||||
size="xs"
|
||||
showByline={showByline}
|
||||
showLeadingImage={showLeadingImage}
|
||||
leadingImageAlt={leadingImageAlt}
|
||||
leadingImageSrc={leadingImageSrc}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -72,6 +74,7 @@ function ContentThumbnailTemplateView({
|
||||
showByline={showByline}
|
||||
showLeadingImage={showLeadingImage}
|
||||
leadingImageAlt={leadingImageAlt}
|
||||
leadingImageSrc={leadingImageSrc}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -97,6 +100,7 @@ function ContentThumbnailTemplateView({
|
||||
showByline={showByline}
|
||||
showLeadingImage={showLeadingImage}
|
||||
leadingImageAlt={leadingImageAlt}
|
||||
leadingImageSrc={leadingImageSrc}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,6 +128,7 @@ function ContentThumbnailTemplateView({
|
||||
showByline={showByline}
|
||||
showLeadingImage={showLeadingImage}
|
||||
leadingImageAlt={leadingImageAlt}
|
||||
leadingImageSrc={leadingImageSrc}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -149,6 +154,7 @@ function ContentThumbnailTemplateView({
|
||||
showByline={showByline}
|
||||
showLeadingImage={showLeadingImage}
|
||||
leadingImageAlt={leadingImageAlt}
|
||||
leadingImageSrc={leadingImageSrc}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user