index.js

import React from 'react';
import { useState } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { useSwipeable } from 'react-swipeable';
import useWindowWidth from '../../../hooks/common/useWindowWidth';
import { sendEventViewItem } from '../../../utility/analytics/events';
import PlainText from '../../composite/plain-text';

import './index.scss';

const PREV = 'prev';
const NEXT = 'next';
const CAROUSEL_MAX_COUNT = 5;

export default function CarouselImages({ data }) {
  const location = useLocation();
  const width = useWindowWidth();
  const [index, setIndex] = useState(0);
  const _data = { ...data, list: data.list.slice(0, CAROUSEL_MAX_COUNT) };
  const { list } = _data;

  // Swipe Handler
  const swipeHandlers = useSwipeable({
    onSwipedRight: onClickPrev,
    onSwipedLeft: onClickNext
  });

  // EVENT HANDLERS
  function chevronClicked(type) {
    let _index;
    const imageCount = list.length;
    if (!type) throw Error('chevron type not passed to click handler');
    if (type === PREV) {
      _index = index === 0 ? imageCount - 1 : index - 1;
    }
    if (type === NEXT) {
      _index = index === imageCount - 1 ? 0 : index + 1;
    }
    setIndex(_index);
  }

  function onClickPrev() {
    chevronClicked(PREV);
  }

  function onClickNext() {
    chevronClicked(NEXT);
  }

  // Analytics
  function send(params) {
    sendEventViewItem(params, location);
  }

  return (
    <div className="carousel">
      <ol className="carousel-indicators">
        {list.map((image, _index) => {
          return <li className={`${index === _index ? ' active' : ''}`} key={_index.toString()}></li>;
        })}
      </ol>
      <div className="carousel-images" {...swipeHandlers}>
        {list.map((image, _index) => {
          const isActive = index === _index;
          const imageClass = isActive ? 'active' : '';
          // NOTE: auto loading type loads image immediately
          // NOTE: eager loading type would definately be loaded unlike lazy
          const loadingType = isActive ? 'auto' : 'eager';
          const { url, title, videoId } = image;
          return (
            <div className={`carousel-image ${imageClass}`} key={videoId}>
              <h2 className="title">
                <PlainText text={title} />
              </h2>
              <div className="background">
                <Link to={`/watch/${videoId}`} onClick={() => send({ to: `/watch/${videoId}`, title, videoId })}>
                  <img src={url} className="image" alt={title} style={{ width: width + 'px' }} loading={loadingType} />
                </Link>
              </div>
            </div>
          );
        })}
      </div>
      <a className="carousel-control-prev" onClick={onClickPrev}>
        <svg className="icon prev-chevron" fill="none">
          <use href="#next-chevron"></use>
        </svg>
      </a>
      <a className="carousel-control-next" onClick={onClickNext}>
        <svg className="icon next-chevron" fill="none">
          <use href="#next-chevron"></use>
        </svg>
      </a>
    </div>
  );
}