From 52af78a31ab324dca34eb8837354b49594b2f9e9 Mon Sep 17 00:00:00 2001 From: Philip Peterson <1326208+philip-peterson@users.noreply.github.com> Date: Wed, 3 Jun 2026 01:40:45 -0700 Subject: [PATCH] Add touch/swipe support to testimonials carousel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live drag tracks the finger with transition disabled; slight rubber-band resistance at both edges. On touchend, snaps to the nearest card boundary within [−maxLeft, 0]. Co-Authored-By: Claude Sonnet 4.6 --- .../js/components/rpt-testimonials.js | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/riverside_pt/js/components/rpt-testimonials.js b/web/modules/custom/riverside_pt/js/components/rpt-testimonials.js index aaa6997..02e67f3 100644 --- a/web/modules/custom/riverside_pt/js/components/rpt-testimonials.js +++ b/web/modules/custom/riverside_pt/js/components/rpt-testimonials.js @@ -75,6 +75,38 @@ function Testimonials() { }; }, []); + var touchStartX = useRef(0); + var touchStartLeft = useRef(0); + var dragging = useRef(false); + + var onTouchStart = function (e) { + touchStartX.current = e.touches[0].clientX; + touchStartLeft.current = leftRef.current; + dragging.current = true; + }; + + var onTouchMove = function (e) { + if (!dragging.current) return; + var delta = e.touches[0].clientX - touchStartX.current; + var max = measureMax(); + var raw = touchStartLeft.current + delta; + // allow slight overscroll resistance at the edges + if (raw > 0) raw = raw / 3; + if (raw < -max) raw = -max + (raw + max) / 3; + setLeft(raw); + }; + + var onTouchEnd = function () { + if (!dragging.current) return; + dragging.current = false; + var max = measureMax(); + setLeft(function (l) { + var clamped = Math.min(0, Math.max(-max, l)); + // snap to nearest card boundary + return -Math.round(-clamped / STEP) * STEP; + }); + }; + var atStart = left >= 0; return html` @@ -105,7 +137,10 @@ function Testimonials() {
${TESTIMONIALS.map(function (t, i) { return html`