11"use client"
22
3- import { EditionUseCaseCard } from "@/components/cards/EditionUseCaseCard "
3+ import { SwipeCard } from "@/components/cards/SwipeCard "
44import { Section } from "@/components/ui/Section"
55import { cn } from "@/lib/utils"
66import type { SwipeCardsLayoutBlock } from "@/lib/cms"
77import { Button } from "@code0-tech/pictor"
88import { IconChevronLeft , IconChevronRight } from "@tabler/icons-react"
99import { m as motion , type PanInfo , type Variants } from "motion/react"
10- import { useState } from "react"
10+ import { type TouchEvent as ReactTouchEvent , useRef , useState } from "react"
1111import { useWebHaptics } from "web-haptics/react"
1212
1313interface SwipeCardSectionProps {
@@ -16,6 +16,8 @@ interface SwipeCardSectionProps {
1616
1717export function SwipeCardSection ( { content } : SwipeCardSectionProps ) {
1818 const [ focusedIndex , setFocusedIndex ] = useState ( 0 )
19+ const touchStartX = useRef < number | null > ( null )
20+ const handledTouchSwipe = useRef ( false )
1921 const { trigger } = useWebHaptics ( )
2022
2123 if ( ! content ?. cards ?. length ) return null
@@ -34,6 +36,11 @@ export function SwipeCardSection({ content }: SwipeCardSectionProps) {
3436 }
3537
3638 const handleDragEnd = ( _event : MouseEvent | TouchEvent | PointerEvent , info : PanInfo ) => {
39+ if ( handledTouchSwipe . current ) {
40+ handledTouchSwipe . current = false
41+ return
42+ }
43+
3744 const swipeThreshold = 48
3845
3946 if ( Math . abs ( info . offset . x ) < swipeThreshold ) return
@@ -46,6 +53,34 @@ export function SwipeCardSection({ content }: SwipeCardSectionProps) {
4653 handleNext ( )
4754 }
4855
56+ const handleTouchStart = ( event : ReactTouchEvent < HTMLDivElement > ) => {
57+ handledTouchSwipe . current = true
58+ touchStartX . current = event . touches [ 0 ] ?. clientX ?? null
59+ }
60+
61+ const handleTouchEnd = ( event : ReactTouchEvent < HTMLDivElement > ) => {
62+ window . setTimeout ( ( ) => {
63+ handledTouchSwipe . current = false
64+ } , 250 )
65+
66+ if ( touchStartX . current === null ) return
67+
68+ const touchEndX = event . changedTouches [ 0 ] ?. clientX
69+ if ( touchEndX === undefined ) return
70+
71+ const offsetX = touchEndX - touchStartX . current
72+ touchStartX . current = null
73+
74+ if ( Math . abs ( offsetX ) < 48 ) return
75+
76+ if ( offsetX > 0 ) {
77+ handlePrevious ( )
78+ return
79+ }
80+
81+ handleNext ( )
82+ }
83+
4984 const staggerContainer : Variants = {
5085 hidden : { } ,
5186 show : {
@@ -118,12 +153,14 @@ export function SwipeCardSection({ content }: SwipeCardSectionProps) {
118153 dragConstraints = { { left : 0 , right : 0 } }
119154 dragElastic = { 0.08 }
120155 onDragEnd = { handleDragEnd }
156+ onTouchStart = { handleTouchStart }
157+ onTouchEnd = { handleTouchEnd }
121158 >
122159 < div className = "relative flex w-full items-stretch justify-center" >
123- < div className = "invisible pointer-events-none grid w-[60%]" >
160+ < div className = "invisible pointer-events-none grid w-full sm:w-[80%] lg:w- [60%]" >
124161 { cards . map ( ( card , index ) => (
125162 < div key = { card . id || index } className = "col-start-1 row-start-1" >
126- < EditionUseCaseCard
163+ < SwipeCard
127164 title = { card . title }
128165 description = { card . description }
129166 image = { card . image }
@@ -143,16 +180,16 @@ export function SwipeCardSection({ content }: SwipeCardSectionProps) {
143180 < div
144181 key = { card . id || index }
145182 className = { cn (
146- "absolute inset-y-0 h-full w-full transition-all duration-500 ease-out" ,
147- "left-1/2 w-[60%]" ,
183+ "absolute top-0 w-full transition-all duration-500 ease-out" ,
184+ "left-1/2 w-full sm:w-[80%] lg:w- [60%]" ,
148185 ! isVisibleMobile && "lg:opacity-100 lg:pointer-events-auto opacity-0 pointer-events-none" ,
149186 ! isVisibleDesktop && "lg:opacity-0 lg:pointer-events-none" ,
150187 ) }
151188 style = { {
152189 transform : `translateX(calc(-50% + ${ offset * 104 } %))` ,
153190 } }
154191 >
155- < EditionUseCaseCard
192+ < SwipeCard
156193 title = { card . title }
157194 description = { card . description }
158195 image = { card . image }
0 commit comments