Skip to content

Commit 16da754

Browse files
committed
feat: improve scrollcard with image fullscreen option & improved
placement & padding
1 parent b3df86f commit 16da754

3 files changed

Lines changed: 188 additions & 171 deletions

File tree

src/blocks/ScrollCardBlock.ts

Lines changed: 143 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,149 @@
11
import type { Block } from "payload"
22

33
export const ScrollCardBlock: Block = {
4-
slug: "scrollCards",
5-
labels: {
6-
singular: "Scroll Cards",
7-
plural: "Scroll Cards Blocks",
8-
},
9-
fields: [
10-
{
11-
name: "items",
12-
label: "Items",
13-
type: "array",
14-
required: true,
15-
fields: [
16-
{
17-
name: "title",
18-
type: "text",
19-
required: true,
20-
localized: true,
21-
},
22-
{
23-
name: "description",
24-
type: "textarea",
25-
required: true,
26-
localized: true,
27-
},
28-
{
29-
name: "showImageBorder",
30-
label: "Show Image Border",
31-
type: "checkbox",
32-
defaultValue: true,
33-
},
34-
{
35-
name: "sectionLayout",
36-
label: "Section Layout",
37-
type: "select",
38-
required: true,
39-
defaultValue: "imageRight",
40-
options: [
41-
{
42-
label: "Image right",
43-
value: "imageRight",
44-
},
45-
{
46-
label: "Image left",
47-
value: "imageLeft",
48-
},
49-
],
50-
},
51-
{
52-
name: "gradient",
53-
label: "Gradient",
54-
type: "select",
55-
required: false,
56-
defaultValue: "blue",
57-
options: [
58-
{
59-
label: "Blue",
60-
value: "blue",
61-
},
62-
{
63-
label: "Yellow",
64-
value: "yellow",
65-
},
66-
{
67-
label: "Pink",
68-
value: "pink",
69-
},
70-
{
71-
label: "Aqua",
72-
value: "aqua",
73-
},
74-
{
75-
label: "Brand",
76-
value: "brand",
77-
},
78-
{
79-
label: "Neutral",
80-
value: "neutral",
81-
},
82-
],
83-
},
84-
{
85-
name: "gradientDirection",
86-
label: "Gradient Direction",
87-
type: "select",
88-
required: false,
89-
defaultValue: "topLeft",
90-
options: [
91-
{
92-
label: "Top left",
93-
value: "topLeft",
94-
},
95-
{
96-
label: "Top right",
97-
value: "topRight",
98-
},
99-
{
100-
label: "Bottom left",
101-
value: "bottomLeft",
102-
},
103-
{
104-
label: "Bottom right",
105-
value: "bottomRight",
106-
},
107-
],
108-
},
109-
{
110-
name: "bulletPoints",
111-
label: "Bullet Points",
112-
type: "text",
113-
required: false,
114-
hasMany: true,
115-
localized: true,
116-
},
117-
{
118-
name: "image",
119-
label: "Image",
120-
type: "upload",
121-
relationTo: "media",
122-
required: false,
123-
},
4+
slug: "scrollCards",
5+
labels: {
6+
singular: "Scroll Cards",
7+
plural: "Scroll Cards Blocks",
8+
},
9+
fields: [
12410
{
125-
name: "link",
126-
label: "Link",
127-
type: "group",
128-
fields: [
129-
{
130-
name: "label",
131-
type: "text",
132-
required: false,
133-
localized: true,
134-
},
135-
{
136-
name: "url",
137-
type: "text",
138-
required: false,
139-
},
140-
],
11+
name: "items",
12+
label: "Items",
13+
type: "array",
14+
required: true,
15+
fields: [
16+
{
17+
name: "title",
18+
type: "text",
19+
required: true,
20+
localized: true,
21+
},
22+
{
23+
name: "description",
24+
type: "textarea",
25+
required: false,
26+
localized: true,
27+
},
28+
{
29+
name: "showImageBorder",
30+
label: "Show Image Border",
31+
type: "checkbox",
32+
defaultValue: true,
33+
},
34+
{
35+
name: "sectionLayout",
36+
label: "Section Layout",
37+
type: "select",
38+
required: true,
39+
defaultValue: "imageRight",
40+
options: [
41+
{
42+
label: "Image right",
43+
value: "imageRight",
44+
},
45+
{
46+
label: "Image left",
47+
value: "imageLeft",
48+
},
49+
{
50+
label: "Image fullscreen",
51+
value: "imageFullscreen",
52+
},
53+
],
54+
},
55+
{
56+
name: "gradient",
57+
label: "Gradient",
58+
type: "select",
59+
required: false,
60+
defaultValue: "blue",
61+
options: [
62+
{
63+
label: "Blue",
64+
value: "blue",
65+
},
66+
{
67+
label: "Yellow",
68+
value: "yellow",
69+
},
70+
{
71+
label: "Pink",
72+
value: "pink",
73+
},
74+
{
75+
label: "Aqua",
76+
value: "aqua",
77+
},
78+
{
79+
label: "Brand",
80+
value: "brand",
81+
},
82+
{
83+
label: "Neutral",
84+
value: "neutral",
85+
},
86+
],
87+
},
88+
{
89+
name: "gradientDirection",
90+
label: "Gradient Direction",
91+
type: "select",
92+
required: false,
93+
defaultValue: "topLeft",
94+
options: [
95+
{
96+
label: "Top left",
97+
value: "topLeft",
98+
},
99+
{
100+
label: "Top right",
101+
value: "topRight",
102+
},
103+
{
104+
label: "Bottom left",
105+
value: "bottomLeft",
106+
},
107+
{
108+
label: "Bottom right",
109+
value: "bottomRight",
110+
},
111+
],
112+
},
113+
{
114+
name: "bulletPoints",
115+
label: "Bullet Points",
116+
type: "text",
117+
required: false,
118+
hasMany: true,
119+
localized: true,
120+
},
121+
{
122+
name: "image",
123+
label: "Image",
124+
type: "upload",
125+
relationTo: "media",
126+
required: false,
127+
},
128+
{
129+
name: "link",
130+
label: "Link",
131+
type: "group",
132+
fields: [
133+
{
134+
name: "label",
135+
type: "text",
136+
required: false,
137+
localized: true,
138+
},
139+
{
140+
name: "url",
141+
type: "text",
142+
required: false,
143+
},
144+
],
145+
},
146+
],
141147
},
142-
],
143-
},
144-
],
148+
],
145149
}

src/components/sections/ScrollCardSection.tsx

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,11 @@ export function ScrollCardSection({ content }: ScrollCardSectionProps) {
103103
const image = getImage(item.image)
104104
const imageUrl = getMediaUrl(image?.url)
105105
const itemSettings = item as {
106-
sectionLayout?: "imageRight" | "imageLeft" | null
106+
sectionLayout?: "imageRight" | "imageLeft" | "imageFullscreen" | null
107107
showImageBorder?: boolean | null
108108
}
109109
const isImageLeft = itemSettings.sectionLayout === "imageLeft"
110+
const isFullscreen = itemSettings.sectionLayout === "imageFullscreen"
110111
const showImageBorder = itemSettings.showImageBorder ?? true
111112
const segmentProgress = index === 0 ? 1 : clamp((scrollProgress - (index - 1) * viewportHeight) / viewportHeight, 0, 1)
112113
const translateY = (1 - segmentProgress) * 100
@@ -125,37 +126,49 @@ export function ScrollCardSection({ content }: ScrollCardSectionProps) {
125126
size="lg"
126127
gradientDirection={item.gradientDirection}
127128
radialGradient={item.gradient}
128-
className="relative grid h-[80%] overflow-hidden bg-primary! p-4 md:grid-cols-[0.95fr_1.05fr]"
129+
className={cn(
130+
isFullscreen ? "relative h-[80%] overflow-hidden bg-primary p-0" : "relative grid h-[80%] overflow-hidden bg-primary p-12 md:grid-cols-[0.95fr_1.05fr]"
131+
)}
129132
>
130-
<div className={cn("relative z-10 flex h-full flex-col justify-between gap-10 rounded-3xl p-4 md:p-8", isImageLeft && "md:order-2")}>
131-
<div className="flex flex-col gap-4">
132-
<h2 className="max-w-xl text-3xl font-semibold text-white md:text-5xl">{item.title}</h2>
133-
<p className="max-w-xl text-base leading-7 text-white/75 md:text-lg">{item.description}</p>
133+
{isFullscreen ? (
134+
<div className={cn("relative z-10 h-full w-full overflow-hidden rounded-3xl", showImageBorder && "border border-white/10")}>
135+
{imageUrl && <Image src={imageUrl} alt={image?.alt ?? item.title} fill sizes="100vw" className="object-cover object-center" />}
134136
</div>
135-
136-
<div className="space-y-6">
137-
<ul className="grid gap-2 text-sm text-white/75 md:text-base">
138-
{item.bulletPoints?.map((point, pointIndex) => (
139-
<li key={`${item.id ?? item.title}-point-${pointIndex}`} className="flex items-start gap-3">
140-
<span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-brand" />
141-
<span>{point}</span>
142-
</li>
143-
))}
144-
</ul>
145-
146-
{item.link?.label && item.link?.url && <LinkButton href={item.link.url}>{item.link.label}</LinkButton>}
147-
</div>
148-
</div>
149-
150-
<div
151-
className={cn(
152-
"relative z-10 aspect-video w-full self-center overflow-hidden rounded-2xl",
153-
showImageBorder && "border border-white/10",
154-
isImageLeft && "md:order-1"
155-
)}
156-
>
157-
{imageUrl && <Image src={imageUrl} alt={image?.alt ?? item.title} fill sizes="(min-width: 768px) 50vw, 100vw" className="object-contain object-center" />}
158-
</div>
137+
) : (
138+
<>
139+
<div className={cn("relative z-10 flex h-full flex-col justify-center gap-8 rounded-3xl", isImageLeft && "md:order-2")}>
140+
<div className="flex flex-col gap-4">
141+
<h2 className="max-w-xl text-3xl font-semibold text-white md:text-5xl">{item.title}</h2>
142+
<p className="max-w-xl text-base leading-7 text-white/75 md:text-lg">{item.description}</p>
143+
</div>
144+
145+
<div className="space-y-6">
146+
<ul className="grid gap-2 text-sm text-white/75 md:text-base">
147+
{item.bulletPoints?.map((point, pointIndex) => (
148+
<li key={`${item.id ?? item.title}-point-${pointIndex}`} className="flex items-start gap-3">
149+
<span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-brand" />
150+
<span>{point}</span>
151+
</li>
152+
))}
153+
</ul>
154+
155+
{item.link?.label && item.link?.url && <LinkButton href={item.link.url}>{item.link.label}</LinkButton>}
156+
</div>
157+
</div>
158+
159+
<div
160+
className={cn(
161+
"relative z-10 aspect-video w-full self-center overflow-hidden rounded-2xl",
162+
showImageBorder && "border border-white/10",
163+
isImageLeft && "md:order-1"
164+
)}
165+
>
166+
{imageUrl && (
167+
<Image src={imageUrl} alt={image?.alt ?? item.title} fill sizes="(min-width: 768px) 50vw, 100vw" className="object-contain object-center" />
168+
)}
169+
</div>
170+
</>
171+
)}
159172
</Card>
160173
</motion.article>
161174
)

src/payload-types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,9 @@ export interface Page {
479479
| {
480480
items: {
481481
title: string;
482-
description: string;
482+
description?: string | null;
483483
showImageBorder?: boolean | null;
484-
sectionLayout: 'imageRight' | 'imageLeft';
484+
sectionLayout: 'imageRight' | 'imageLeft' | 'imageFullscreen';
485485
gradient?: ('blue' | 'yellow' | 'pink' | 'aqua' | 'brand' | 'neutral') | null;
486486
gradientDirection?: ('topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight') | null;
487487
bulletPoints?: string[] | null;

0 commit comments

Comments
 (0)