TwitchClone / src / utils / homeSlide2 / index.tsx
index.tsx
Raw
import React, {
  useEffect,
  useCallback,
  useState,
  ReactElement,
  useRef,
} from "react";
import styles from "./styles.module.css";
import classNames from "../helpers/className";

const defaultCardItems = [
  <div key="key1">
    <h2>First Item</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
  </div>,
  <div key="key2">
    <h2>Second Item</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
  </div>,
  <div key="key3">
    <h2>Third Item</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
  </div>,
];

type Indexes = {
  previousIndex: number;
  currentIndex: number;
  nextIndex: number;
  nextIndex2: number;
  previousIndex2: number;
};

const setCardStatus = (
  indexes: Indexes,
  cardIndex: number,
  showSummary = false
) => {
  // console.log(indexes, cardIndex);
  if (indexes.currentIndex === cardIndex) {
    return styles.active;
  } else if (indexes.nextIndex === cardIndex) {
    return showSummary
      ? `${styles.noTranslate as string}`
      : `${styles.next as string}`;
  } else if (indexes.previousIndex === cardIndex) {
    return showSummary
      ? `${styles.noTranslate as string}`
      : (styles.prev as string);
  } else if (indexes.nextIndex2 === cardIndex) {
    return showSummary
      ? `${styles.noTranslate as string}`
      : (styles.next2 as string);
  } else if (indexes.previousIndex2 === cardIndex) {
    return showSummary
      ? `${styles.noTranslate as string}`
      : (styles.prev2 as string);
  }
  return styles.inactive as string;
};
const getValidChildren = (children: React.ReactNode): React.ReactElement[] => {
  return React.Children.toArray(children).filter(
    (child): child is React.ReactElement => React.isValidElement(child)
  );
};
// type CardType = React.ReactElement & { key: string | number };
type CardType = React.ReactElement;

type CardCarouselProps = {
  cardClassName: string;
  children: CardType[];
  containerClassName: string;
  autoRotate: boolean;
  showSummary: boolean;
  leftButton: React.ReactNode;
  rightButton: React.ReactNode;
  style: React.CSSProperties;
  onCardChange: (indexes: Indexes) => void;
  rotationInterval: number;
  defaultCardItems?: CardType[];
};

//children: Element[], autoRotate: boolean, onCardChange: (event: any) => void, containerClassName: string, cardClassName: string, leftButton: Element, rightButton: Element , rotationInterval: number, showSummary: boolean, style: any}
export const StackedCarouselTwo: React.FC<CardCarouselProps> = ({
  showSummary,
  style,
  onCardChange,
  containerClassName,
  cardClassName,
  leftButton,
  rightButton,
  autoRotate = true,
  rotationInterval = 2000,
  //handleCardChange,
  children,
}) =>
  // showSummary: boolean;
  // style: any;
  // onCardChange: (event: any) => void;
  // containerClassName: string;
  // cardClassName: string;
  // leftButton: ReactElement<any, any>;
  // rightButton: ReactElement<any, any>;
  // autoRotate: boolean;
  // rotationInterval: number;
  // children: any;
  //handleCardChange: (card: number) => void;
  {
    // let cardItems = showSummary ? [1, ...(children  as CardType[])] : (children as CardType[])|| defaultCardItems;
    const cardItems = showSummary
      ? [
          <div key="summary">1</div>,
          ...React.Children.map(children, (child, index) => (
            <React.Fragment key={index}>{child}</React.Fragment>
          )),
        ]
      : React.Children.map(children, (child, index) => (
          <React.Fragment key={index}>{child}</React.Fragment>
        ));

    // console.log(showSummary);
    const [indexes, setIndexes] = useState({
      previousIndex: cardItems.length - 1,
      currentIndex: 0,
      nextIndex: 1,
      nextIndex2: 2,
      previousIndex2: cardItems.length - 2,
    });

    const handleCardTransition = useCallback(() => {
      // console.log("card before change =", indexes.currentIndex);
      // If we've reached the end, start again from the first card,
      // but carry previous value over
      if (indexes.currentIndex >= cardItems.length - 1) {
        setIndexes({
          previousIndex: cardItems.length - 1,
          currentIndex: 0,
          nextIndex: 1,
          nextIndex2: 2,
          previousIndex2: cardItems.length - 2,
        });
        //console.log("useEffect - r", 0);
        //handleCardChange(0);
      } else {
        setIndexes((prevState) => ({
          previousIndex: prevState.currentIndex,
          previousIndex2: prevState.previousIndex,
          currentIndex: prevState.currentIndex + 1,
          nextIndex:
            prevState.currentIndex + 2 === cardItems.length
              ? 0
              : prevState.currentIndex + 2,
          nextIndex2:
            prevState.currentIndex + 3 === cardItems.length
              ? 0
              : prevState.currentIndex + 3,
        }));
        //console.log("useeffect - rr", indexes.currentIndex - 1);
        //handleCardChange(indexes.currentIndex + 1);
      }
    }, [indexes.currentIndex]);

    const handleLeftButton = useCallback(() => {
      // If we've reached the end, start again from the first card,
      // but carry previous value over
      if (indexes.currentIndex <= 0) {
        setIndexes({
          previousIndex: cardItems.length - 2,
          previousIndex2: cardItems.length - 3,
          currentIndex: cardItems.length - 1,
          nextIndex: 0,
          nextIndex2: 1,
        });

        //console.log("useEffect - l", cardItems.length - 1);
        //handleCardChange(cardItems.length - 1);
      } else {
        setIndexes((prevState) => ({
          nextIndex: prevState.currentIndex,
          currentIndex: prevState.currentIndex - 1,
          previousIndex:
            prevState.currentIndex - 1 <= 0
              ? cardItems.length - 1
              : prevState.currentIndex - 2,
          previousIndex2:
            prevState.currentIndex - 2 <= 0
              ? cardItems.length - 1
              : prevState.currentIndex - 3,
          nextIndex2: prevState.currentIndex + 1,
        }));
        //console.log("useeffect - l", indexes.currentIndex - 1);
        //handleCardChange(indexes.currentIndex - 1);
      }
    }, [indexes.currentIndex]);

    useEffect(() => {
      onCardChange && onCardChange(indexes);
      const transitionInterval = setInterval(() => {
        autoRotate && handleCardTransition();
      }, rotationInterval);
      return () => clearInterval(transitionInterval);
    }, [handleCardTransition, indexes, autoRotate]);

    return (
      //container: flex items-start m-auto pb-[13%] pl-[10%] pr-[13%] mb-[26%] max-h-[20%] xs:max-sm:min-h-[27vh] sm:max-md:min-h-[27vh] md:max-lg:pl-[8%] row-reverse overflow-hidden h-[10rem] w-full
      <div
        className={classNames(
          `${styles.container as string}`,
          `scrollbar-hide 2xs:max-lg:pb-0`
        )}
      >
        {leftButton ? (
          // spans: z-1000 cursor-pointer
          <span onClick={handleLeftButton}>{leftButton}</span>
        ) : (
          // leftbutton: translate-y-[50%] blue text-[2em] p-[5px]
          <span className={styles.leftButton} onClick={handleLeftButton}>
            &lsaquo;
          </span>
        )}
        {/* cardCarousel: "list style none" p-0 relative w-full  combine with containerClassName input*/}
        <ul
          style={{ ...style }}
          className={`${styles.cardCarousel as string} ${
            containerClassName
              ? containerClassName
              : (styles.carouselDefault as string)
          }`}
        >
          {cardItems.map((card: React.ReactElement, index: number) => {
            if (showSummary && index === 0) {
              // cardItems.shift()
              const cardsGallery = cardItems.slice(1);
              return (
                // combine with cardClassName input* card: w-full h-full "box shadow: 0 10px 5px rgba(0, 0, 0, 0.1) transition: "all 0.5s ease-in-out" grid gtc-"repeat(auto-fit, minmax(80px, 1fr))" gtr-"repeat(auto-fit, minmax(80px, 1fr))" grid-gap-0
                <li
                  key={"stacked-carousel"}
                  className={`${cardClassName ?? ""} ${styles.card ?? ""} ${
                    styles.cardSummary ?? ""
                  } ${setCardStatus(indexes, index, showSummary) ?? ""}`}

                  // className={`${cardClassName ? cardClassName : ""} ${
                  //   styles.card as string
                  // } ${styles.cardSummary as string} ${setCardStatus(
                  //   indexes,
                  //   index as number,
                  //   showSummary
                  // ) as string}`}
                >
                  {cardsGallery.map((cardItem: CardType, cardIndex: number) => (
                    <div
                      key={cardItem.key}
                      className={`${cardClassName ?? ""} ${
                        setCardStatus(indexes, cardIndex, showSummary) ?? ""
                      }`}

                      // className={`${cardClassName ? cardClassName : ""} ${
                      //   setCardStatus(indexes, cardIndex, showSummary) as string
                      // }`}
                    >
                      {cardItem}
                    </div>
                  ))}
                </li>
              );
            } else {
              return (
                // combine with cardClassName input* card: w-full h-full "box shadow: "
                <li
                  key={card.key as string | number}
                  className={`${cardClassName ? cardClassName : ""} ${
                    styles.card as string
                  } ${setCardStatus(indexes, index, showSummary) ?? ""}`}
                >
                  {card}
                </li>
              );
            }
          })}
        </ul>
        {/* rightbutton:blue text-[2em] p-[5px] ??absolute ??translate-x-[75vw] */}
        {rightButton ? (
          <span onClick={handleCardTransition}>{rightButton}</span>
        ) : (
          <span
            style={{ position: "absolute", transform: "translateX(75vw)" }}
            className={styles.rightButton}
            onClick={handleCardTransition}
          >
            &rsaquo;
          </span>
        )}
      </div>
    );
  };