import React, { useRef, useState } from 'react' import { color } from '../_utils/branding' import { Button, ButtonStatus } from '../button' import { ArrowIcon } from '../icon/arrowIcon' import { BaseSection, SectionContentSize } from '../layout/section/baseSection' import { TextSubHeaderStrong } from '../typography/subHeaderStrong' import { StyledTestimonials } from './Testimonials.style' const SWIPE_TRESHOLD = 60 type Testimonial = Readonly<{ quote: string author: string }> export type TestimonialsProps = Readonly<{ illustration: JSX.Element testimonials: Array a11y: Readonly<{ mainTitle: string prev: string next: string }> }> export const Testimonials = ({ illustration, testimonials, a11y }: TestimonialsProps) => { const [activeTestimonial, setActiveTestimonial] = useState(0) const touchXInitialPosition = useRef(null) const touchXPosition = useRef(null) /** * We implemented a loop carousel. Clicking next when we reached the end * will make it start at the beginning. * * Prev & Next methods are called by swiping or by clicking the buttons */ const prev = (): void => { const active = activeTestimonial - 1 < 0 ? testimonials.length - 1 : activeTestimonial - 1 setActiveTestimonial(active) } const next = (): void => { const active = activeTestimonial + 1 > testimonials.length - 1 ? 0 : activeTestimonial + 1 setActiveTestimonial(active) } /** * Naive swipe implementation. Added a threshold to avoid swiping by just scrolling the page */ const onTouchStart = (e: React.TouchEvent): void => { if (e.touches.length === 1) { touchXInitialPosition.current = e.touches[0].pageX } } const onTouchMove = (e: React.TouchEvent): void => { if (e.touches.length === 1) { touchXPosition.current = e.touches[0].pageX } } const onTouchEnd = (): void => { if (touchXInitialPosition.current !== null && touchXPosition.current !== null) { const diff = touchXPosition.current - touchXInitialPosition.current if (Math.abs(diff) > SWIPE_TRESHOLD) { if (diff > 0) { prev() } else { next() } } touchXPosition.current = null touchXInitialPosition.current = null } } return ( {illustration} {testimonials.map( ({ quote, author }: Testimonial): JSX.Element => (
  • {quote} {author}
  • ), )}
    {testimonials.map( ({ author }: Testimonial, i: number): JSX.Element => ( ), )}
    ) }