1+ import { StaggerContainer , StaggerItem } from "@/components/animations/Stagger"
12import { LinkButton } from "@/components/ui/LinkButton"
23import { Section } from "@/components/ui/Section"
34import type { ScrollCardsLayoutBlock } from "@/lib/cms"
@@ -16,6 +17,39 @@ function getImage(image: number | Media | null | undefined) {
1617 return typeof image === "object" ? image : null
1718}
1819
20+ type ScrollCardItem = NonNullable < ScrollCardsLayoutBlock [ "items" ] > [ number ]
21+
22+ function ScrollCardContent ( { item, centered = false } : { item : ScrollCardItem ; centered ?: boolean } ) {
23+ return (
24+ < StaggerContainer className = { cn ( "flex flex-col gap-6" , centered ? "items-center text-center" : "text-left" ) } delayChildren = { 0.04 } staggerChildren = { 0.08 } >
25+ < StaggerItem as = "h2" y = { 14 } duration = { 0.38 } className = { cn ( "text-3xl font-semibold text-white md:text-5xl" , centered ? "max-w-4xl" : "max-w-xl" ) } >
26+ { item . title }
27+ </ StaggerItem >
28+
29+ { item . description && (
30+ < StaggerItem as = "p" y = { 14 } duration = { 0.38 } className = { cn ( "text-base leading-7 text-secondary md:text-lg" , centered ? "max-w-2xl" : "max-w-xl" ) } >
31+ { item . description }
32+ </ StaggerItem >
33+ ) }
34+
35+ < StaggerItem as = "ul" y = { 14 } duration = { 0.38 } className = "grid gap-2 text-sm text-secondary md:text-base" >
36+ { item . bulletPoints ?. map ( ( point , pointIndex ) => (
37+ < li key = { `${ item . id ?? item . title } -point-${ pointIndex } ` } className = "flex items-start gap-3" >
38+ < span className = "mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-brand" />
39+ < span > { point } </ span >
40+ </ li >
41+ ) ) }
42+ </ StaggerItem >
43+
44+ { item . link ?. label && item . link ?. url && (
45+ < StaggerItem y = { 14 } duration = { 0.38 } >
46+ < LinkButton href = { item . link . url } > { item . link . label } </ LinkButton >
47+ </ StaggerItem >
48+ ) }
49+ </ StaggerContainer >
50+ )
51+ }
52+
1953export function ScrollCardSection ( { content } : ScrollCardSectionProps ) {
2054 const items = content ?. items ?. filter ( ( item ) => Boolean ( item . title ) ) ?? [ ]
2155 if ( items . length === 0 ) return null
@@ -62,46 +96,15 @@ export function ScrollCardSection({ content }: ScrollCardSectionProps) {
6296 { imageUrl && < Image src = { imageUrl } alt = { image ?. alt ?? item . title } fill sizes = "100vw" className = "object-cover object-center" /> }
6397
6498 < div className = "absolute inset-0 z-20 flex items-center justify-center" >
65- < div className = "mx-auto flex max-w-4xl flex-col items-center gap-6 px-6 text-center" >
66- < h2 className = "text-3xl font-semibold text-white md:text-5xl" > { item . title } </ h2 >
67-
68- { item . description && < p className = "max-w-2xl text-base leading-7 text-secondary md:text-lg" > { item . description } </ p > }
69-
70- < div className = "space-y-6" >
71- < ul className = "grid gap-2 text-sm text-secondary md:text-base" >
72- { item . bulletPoints ?. map ( ( point , pointIndex ) => (
73- < li key = { `${ item . id ?? item . title } -point-${ pointIndex } ` } className = "flex items-start gap-3" >
74- < span className = "mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-brand" />
75- < span > { point } </ span >
76- </ li >
77- ) ) }
78- </ ul >
79-
80- { item . link ?. label && item . link ?. url && < LinkButton href = { item . link . url } > { item . link . label } </ LinkButton > }
81- </ div >
99+ < div className = "mx-auto max-w-4xl px-6" >
100+ < ScrollCardContent item = { item } centered />
82101 </ div >
83102 </ div >
84103 </ div >
85104 ) : isSideFullscreen ? (
86105 < >
87106 < div className = { cn ( "relative z-10 flex flex-col justify-center gap-6 p-6 sm:p-8 md:h-full md:gap-8 md:p-12" , isSideFullscreenLeft && "md:order-2" ) } >
88- < div className = "flex flex-col gap-4" >
89- < h2 className = "max-w-xl text-3xl font-semibold text-white md:text-5xl" > { item . title } </ h2 >
90- < p className = "max-w-xl text-base leading-7 text-secondary md:text-lg" > { item . description } </ p >
91- </ div >
92-
93- < div className = "space-y-6" >
94- < ul className = "grid gap-2 text-sm text-secondary md:text-base" >
95- { item . bulletPoints ?. map ( ( point , pointIndex ) => (
96- < li key = { `${ item . id ?? item . title } -point-${ pointIndex } ` } className = "flex items-start gap-3" >
97- < span className = "mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-brand" />
98- < span > { point } </ span >
99- </ li >
100- ) ) }
101- </ ul >
102-
103- { item . link ?. label && item . link ?. url && < LinkButton href = { item . link . url } > { item . link . label } </ LinkButton > }
104- </ div >
107+ < ScrollCardContent item = { item } />
105108 </ div >
106109
107110 < div
@@ -118,23 +121,7 @@ export function ScrollCardSection({ content }: ScrollCardSectionProps) {
118121 ) : (
119122 < >
120123 < div className = { cn ( "relative z-10 flex h-full flex-col justify-center gap-8 rounded-3xl" , isImageLeft && "md:order-2" ) } >
121- < div className = "flex flex-col gap-4" >
122- < h2 className = "max-w-xl text-3xl font-semibold text-white md:text-5xl" > { item . title } </ h2 >
123- { item . description && < p className = "max-w-xl text-base leading-7 text-secondary md:text-lg" > { item . description } </ p > }
124- </ div >
125-
126- < div className = "space-y-6" >
127- < ul className = "grid gap-2 text-sm text-secondary md:text-base" >
128- { item . bulletPoints ?. map ( ( point , pointIndex ) => (
129- < li key = { `${ item . id ?? item . title } -point-${ pointIndex } ` } className = "flex items-start gap-3" >
130- < span className = "mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-brand" />
131- < span > { point } </ span >
132- </ li >
133- ) ) }
134- </ ul >
135-
136- { item . link ?. label && item . link ?. url && < LinkButton href = { item . link . url } > { item . link . label } </ LinkButton > }
137- </ div >
124+ < ScrollCardContent item = { item } />
138125 </ div >
139126
140127 < div
0 commit comments