Carousel 10.18.1

ARIA

This is an effective way of displaying multiple images or content in a single space.

Not only does it conserve screen real estate, but it also guides visitors to concentrate on crucial website content, significantly enhancing the overall visual appeal.

To support Arabic languages this component requires setting up the isRtl prop directly.

Anatomy

<Carousel>
  <Carousel.LeftArrow>...</Carousel.LeftArrow>
  <Carousel.Reel>
    <Carousel.Item>...</Carousel.Item>
  <Carousel.Reel>
  <Carousel.Indicators/>
  </Carousel.RightArrow>...</Carousel.RightArrow>
</Carousel>

Default

  • 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
"use client";

import { Carousel } from "@heathmont/moon-core-tw";
import {
  ControlsChevronLeftSmall,
  ControlsChevronRightSmall,
} from "@heathmont/moon-icons-tw";

const Default = () => {
  const items = Array.from({ length: 25 }, (index) => index);
  return (
    <div className="flex flex-col w-full items-center">
      <Carousel
        scrollTo={5}
        data-testid="carousel"
        className="w-full sm:max-w-auto"
      >
        <Carousel.LeftArrow data-testid="left-arrow">
          <ControlsChevronLeftSmall />
        </Carousel.LeftArrow>
        <Carousel.Reel>
          {items.map((_, index) => (
            <Carousel.Item
              key={index}
              className="w-full max-w-80 h-48 border border-beerus"
              data-testid={`carousel-${index}`}
            >
              {index}
            </Carousel.Item>
          ))}
        </Carousel.Reel>
        <Carousel.RightArrow data-testid="right-arrow">
          <ControlsChevronRightSmall />
        </Carousel.RightArrow>
      </Carousel>
    </div>
  );
};

export default Default;

    Customized Arrows

    You can use any custom trigger for the previous/next button.

    • 0
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    "use client";
    
    import { Button, Carousel } from "@heathmont/moon-core-tw";
    
    type RenderProps = {
      scrollLeftToStep?: () => void;
      scrollRightToStep?: () => void;
      canScrollLeft?: boolean;
      canScrollRight?: boolean;
    };
    
    const Example = () => {
      const items = Array.from({ length: 25 }, (index) => index);
      return (
        <div className="flex flex-col w-full items-center">
          <Carousel scrollTo={5} className="w-full sm:max-w-auto">
            {({
              scrollLeftToStep,
              scrollRightToStep,
              canScrollLeft,
              canScrollRight,
            }: RenderProps) => (
              <>
                <Button
                  onClick={scrollLeftToStep}
                  disabled={!canScrollLeft}
                  className="my-4"
                  data-testid="scroll-left"
                >
                  Scroll to left
                </Button>
                <Carousel.Reel>
                  {items.map((_, index) => (
                    <Carousel.Item
                      key={index}
                      className="w-full max-w-80 h-48 border border-beerus"
                      data-testid={`carousel-${index}`}
                    >
                      {index}
                    </Carousel.Item>
                  ))}
                </Carousel.Reel>
                <Button
                  onClick={scrollRightToStep}
                  disabled={!canScrollRight}
                  className="my-4"
                  data-testid="scroll-right"
                >
                  Scroll to Right
                </Button>
              </>
            )}
          </Carousel>
        </div>
      );
    };
    
    export default Example;
    

      Showing Indicators

      You have the option to display dots as indicators.

      • 0
      • 1
      • 2
      • 3
      • 4
      "use client";
      
      import { Carousel } from "@heathmont/moon-core-tw";
      import {
        ControlsChevronLeftSmall,
        ControlsChevronRightSmall,
      } from "@heathmont/moon-icons-tw";
      
      const Example = () => {
        const items = Array.from({ length: 5 }, (index) => index);
        return (
          <div className="flex flex-col w-full items-center">
            <Carousel step={1} selectedIndex={1} className="w-full max-w-80">
              <Carousel.LeftArrow data-testid="scroll-left">
                <ControlsChevronLeftSmall />
              </Carousel.LeftArrow>
              <Carousel.Reel>
                {items.map((_, index) => (
                  <Carousel.Item
                    key={index}
                    className="w-full max-w-80 h-48 border border-beerus"
                    data-testid={`carousel-${index}`}
                  >
                    {index}
                  </Carousel.Item>
                ))}
              </Carousel.Reel>
              <Carousel.RightArrow data-testid="scroll-right">
                <ControlsChevronRightSmall />
              </Carousel.RightArrow>
              <Carousel.Indicators />
            </Carousel>
          </div>
        );
      };
      
      export default Example;
      

        Different gap

        You can define the gap between slides using the className property.

        • 0
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        "use client";
        
        import { Carousel } from "@heathmont/moon-core-tw";
        import {
          ControlsChevronLeftSmall,
          ControlsChevronRightSmall,
        } from "@heathmont/moon-icons-tw";
        
        const Spaces = () => {
          const items = Array.from({ length: 10 }, (index) => index);
          return (
            <div className="flex flex-col items-center gap-4 w-full">
              <Carousel className="w-full sm:max-w-auto">
                <Carousel.LeftArrow data-testid="scroll-left">
                  <ControlsChevronLeftSmall />
                </Carousel.LeftArrow>
                <Carousel.Reel className="gap-20">
                  {items.map((_, index) => (
                    <Carousel.Item
                      key={index}
                      className="w-full max-w-80 h-48 border border-beerus"
                      data-testid={`carousel-${index}`}
                    >
                      {index}
                    </Carousel.Item>
                  ))}
                </Carousel.Reel>
                <Carousel.RightArrow data-testid="scroll-right">
                  <ControlsChevronRightSmall />
                </Carousel.RightArrow>
              </Carousel>
            </div>
          );
        };
        
        export default Spaces;
        

          Visible Indices

          To access to indices visible in the carousel viewport, you can utilize the render prop, accessing firstVisibleIndex and lastVisibleIndex.

          • Current index: 0

            Visible indices:-1--1

          • Current index: 1

            Visible indices:-1--1

          • Current index: 2

            Visible indices:-1--1

          • Current index: 3

            Visible indices:-1--1

          • Current index: 4

            Visible indices:-1--1

          • Current index: 5

            Visible indices:-1--1

          • Current index: 6

            Visible indices:-1--1

          • Current index: 7

            Visible indices:-1--1

          • Current index: 8

            Visible indices:-1--1

          • Current index: 9

            Visible indices:-1--1

          • Current index: 10

            Visible indices:-1--1

          • Current index: 11

            Visible indices:-1--1

          • Current index: 12

            Visible indices:-1--1

          • Current index: 13

            Visible indices:-1--1

          • Current index: 14

            Visible indices:-1--1

          • Current index: 15

            Visible indices:-1--1

          • Current index: 16

            Visible indices:-1--1

          • Current index: 17

            Visible indices:-1--1

          • Current index: 18

            Visible indices:-1--1

          • Current index: 19

            Visible indices:-1--1

          • Current index: 20

            Visible indices:-1--1

          • Current index: 21

            Visible indices:-1--1

          • Current index: 22

            Visible indices:-1--1

          • Current index: 23

            Visible indices:-1--1

          • Current index: 24

            Visible indices:-1--1

          "use client";
          
          import { Carousel } from "@heathmont/moon-core-tw";
          import {
            ControlsChevronLeftSmall,
            ControlsChevronRightSmall,
          } from "@heathmont/moon-icons-tw";
          
          type RenderProps = {
            firstVisibleIndex?: number;
            lastVisibleIndex?: number;
          };
          
          const VisibleIndices = () => {
            const items = Array.from({ length: 25 }, (index) => index);
            return (
              <div className="flex flex-col items-center gap-4 w-full">
                <Carousel className="w-full sm:max-w-auto">
                  {({ firstVisibleIndex, lastVisibleIndex }: RenderProps) => (
                    <>
                      <Carousel.LeftArrow data-testid="scroll-left">
                        <ControlsChevronLeftSmall />
                      </Carousel.LeftArrow>
                      <Carousel.Reel>
                        {items.map((_, index) => (
                          <Carousel.Item
                            key={index}
                            className="w-full max-w-80 h-48 border border-beerus flex-col" /* flex-col added, Carousel.Item have as base flex */
                            data-testid={`carousel-${index}`}
                          >
                            <p>Current index: {index}</p>
                            <p data-testid={`visible-indices-${index}`}>
                              Visible indices:
                              {`${firstVisibleIndex}-${lastVisibleIndex}`}
                            </p>
                          </Carousel.Item>
                        ))}
                      </Carousel.Reel>
                      <Carousel.RightArrow data-testid="scroll-right">
                        <ControlsChevronRightSmall />
                      </Carousel.RightArrow>
                    </>
                  )}
                </Carousel>
              </div>
            );
          };
          
          export default VisibleIndices;
          

            Selected Index

            The selectedIndex prop enables the carousel to display a particular index.

            • 0
            • 1
            • 2
            • 3
            • 4
            "use client";
            
            import { Carousel, Chip } from "@heathmont/moon-core-tw";
            import { useState } from "react";
            
            const ITEMS = Array.from({ length: 5 }, (index) => index);
            
            const SelectIndex = () => {
              const [selected, setSelected] = useState(0);
              return (
                <div className="flex flex-col items-center gap-4 w-full">
                  <div className="flex gap-1">
                    {ITEMS.map((_, index) => (
                      <Chip
                        key={index}
                        isActive={selected === index}
                        onClick={() => setSelected(index)}
                        className="px-4"
                        data-testid={`carousel-button-${index}`}
                      >
                        {index}
                      </Chip>
                    ))}
                  </div>
                  <Carousel
                    step={1}
                    selectedIndex={selected}
                    className="w-full max-w-80"
                    data-testid="selectedIndex-carousel"
                  >
                    <Carousel.Reel>
                      {ITEMS.map((_, index) => (
                        <Carousel.Item
                          key={index}
                          className="w-full h-48 border border-beerus"
                          data-testid={`carousel-${index}`}
                        >
                          {index}
                        </Carousel.Item>
                      ))}
                    </Carousel.Reel>
                  </Carousel>
                </div>
              );
            };
            
            export default SelectIndex;
            

              Auto Slide

              If the carousel is intended to advance automatically, you can achieve this by setting the autoSlideDelay prop with the specified time in milliseconds.

              • 0
              • 1
              • 2
              • 3
              • 4
              • 5
              • 6
              • 7
              • 8
              • 9
              • 10
              • 11
              • 12
              • 13
              • 14
              • 15
              • 16
              • 17
              • 18
              • 19
              • 20
              • 21
              • 22
              • 23
              • 24
              "use client";
              
              import { Carousel } from "@heathmont/moon-core-tw";
              
              const AutoSlide = () => {
                const items = Array.from({ length: 25 }, (index) => index);
                return (
                  <div className="flex flex-col w-full items-center">
                    <Carousel
                      autoSlideDelay={3000}
                      step={1}
                      data-testid="autoSlide-carousel"
                      className="w-full sm:max-w-auto"
                    >
                      <Carousel.Reel>
                        {items.map((_, index) => (
                          <Carousel.Item
                            key={index}
                            className="w-full max-w-80 h-48 border border-beerus"
                            data-testid={`carousel-${index}`}
                          >
                            {index}
                          </Carousel.Item>
                        ))}
                      </Carousel.Reel>
                    </Carousel>
                  </div>
                );
              };
              
              export default AutoSlide;
              

                RTL support

                • 4
                • 3
                • 2
                • 1
                • 0
                "use client";
                
                import { Carousel, Chip } from "@heathmont/moon-core-tw";
                import { useState } from "react";
                
                const RTLSupport = () => {
                  const [selected, setSelected] = useState(0);
                  const items = Array.from({ length: 5 }, (index) => index);
                  return (
                    <div
                      className="flex flex-col items-center gap-4 w-full"
                      dir="rtl"
                      data-testid="carousel"
                    >
                      <div className="flex gap-1">
                        {items.map((_, index) => (
                          <Chip
                            key={index}
                            isActive={selected === index}
                            onClick={() => setSelected(index)}
                            className="px-4"
                            data-testid={`carousel-button-${index}`}
                          >
                            {index}
                          </Chip>
                        ))}
                      </div>
                      <Carousel step={1} selectedIndex={selected} className="w-[320px]" isRtl>
                        <Carousel.Reel>
                          {items.map((_, index) => (
                            <Carousel.Item
                              key={index}
                              className="w-80 h-48 border border-beerus"
                              data-testid={`carousel-${index}`}
                            >
                              {index}
                            </Carousel.Item>
                          ))}
                        </Carousel.Reel>
                      </Carousel>
                    </div>
                  );
                };
                
                export default RTLSupport;
                

                  Swipe or Drag disabled

                  Add isSwipeDragDisabled to disable swipe/drag over the carousel content.

                  • 0
                  • 1
                  • 2
                  • 3
                  • 4
                  "use client";
                  
                  import { Carousel, Chip } from "@heathmont/moon-core-tw";
                  import { useState } from "react";
                  
                  const ITEMS = Array.from({ length: 5 }, (index) => index);
                  
                  const SwipeDragDisabled = () => {
                    const [selected, setSelected] = useState(0);
                    return (
                      <div className="items-center gap-4 w-full flex flex-col">
                        <div className="flex gap-1">
                          {ITEMS.map((_, index) => (
                            <Chip
                              key={index}
                              isActive={selected === index}
                              onClick={() => setSelected(index)}
                              className="px-4"
                              data-testid={`carousel-button-${index}`}
                            >
                              {index}
                            </Chip>
                          ))}
                        </div>
                        <Carousel
                          step={1}
                          selectedIndex={selected}
                          className="w-full max-w-80"
                          data-testid="selectedIndex-carousel"
                          isSwipeDragDisabled
                        >
                          <Carousel.Reel>
                            {ITEMS.map((_, index) => (
                              <Carousel.Item
                                key={index}
                                className="w-full h-48 border border-beerus"
                                data-testid={`carousel-${index}`}
                              >
                                {index}
                              </Carousel.Item>
                            ))}
                          </Carousel.Reel>
                        </Carousel>
                      </div>
                    );
                  };
                  
                  export default SwipeDragDisabled;
                  

                    These are props specific to the Carousel component:

                    Name
                    Type
                    Default
                    scrollTo
                    number-
                    step
                    number5
                    selectedIndex
                    number-
                    scrollLeftToStep
                    "() => void"-
                    scrollRightToStep
                    "() => void"-
                    canScrollLeft
                    boolean-
                    canScrollRight
                    boolean-
                    firstVisibleIndex
                    number-
                    lastVisibleIndex
                    number-
                    autoSlideDelay
                    number-
                    isRtl
                    boolean-
                    isSwipeDragDisabled
                    booleanfalse