Carousel

free

Carousel presents ordered media or panels one at a time inside the current surface.

Gallery image 1
Gallery image 2
Gallery image 3
Gallery image 4
Gallery image 5
import Carousel from '@/components/ui/carousel';

const images = Array.from({ length: 5 }, (_, index) => ({
  src: `/img/thumbs/misc/img-${index + 1}.png`,

Installation

Add this component with the NateUI CLI.

npx nateui@latest add Carousel

Examples

Basic

Gallery image 1
Gallery image 2
Gallery image 3
Gallery image 4
Gallery image 5
import Carousel from '@/components/ui/carousel';

const images = Array.from({ length: 5 }, (_, index) => ({
  src: `/img/thumbs/misc/img-${index + 1}.png`,

Sizes

Gallery image 1
Gallery image 2
Gallery image 3
Gallery image 4
Gallery image 5
import Carousel from '@/components/ui/carousel';

const images = Array.from({ length: 5 }, (_, index) => ({
  src: `/img/thumbs/misc/img-${index + 1}.png`,

Loop

Gallery image 1
Gallery image 2
Gallery image 3
Gallery image 4
Gallery image 5
import Carousel from '@/components/ui/carousel';

const images = Array.from({ length: 5 }, (_, index) => ({
  src: `/img/thumbs/misc/img-${index + 1}.png`,

Vertical

Gallery image 1
Gallery image 2
Gallery image 3
Gallery image 4
Gallery image 5
import Carousel from '@/components/ui/carousel';

const images = Array.from({ length: 5 }, (_, index) => ({
  src: `/img/thumbs/misc/img-${index + 1}.png`,

Trigger Placement

Gallery image 1
Gallery image 2
Gallery image 3
Gallery image 1
Gallery image 2
Gallery image 3
import Carousel from '@/components/ui/carousel';

const images = Array.from({ length: 3 }, (_, index) => ({
  src: `/img/thumbs/misc/img-${index + 1}.png`,
Gallery image 1
Gallery image 2
Gallery image 3
Gallery image 4
Gallery image 5
import { useState } from 'react';
import Carousel from '@/components/ui/carousel';
import type { CarouselApi } from '@/components/ui/carousel';

API

Carousel exposes a compound root with content, item, previous, and next subcomponents. The root accepts native div props.

PropDescriptionTypeDefault
childrenCarousel content and controls, usually Carousel.Content, Carousel.Item, Carousel.Previous, and Carousel.Next.ReactNode-
classNameClass names applied to the carousel root.string-
orientationDirection used for keyboard navigation, drag movement, and item spacing.CarouselOrientation'horizontal'
optsCarousel behavior options. The current implementation applies loop and startIndex.CarouselOptions{}
setApiReceives the imperative carousel API for external controls and slide state.CarouselApiHandler-
refRef forwarded to the carousel root.Ref<HTMLDivElement>-
...nativeDivPropsNative props for the carousel root div.NativeCarouselDivProps-
PropDescriptionTypeDefault
childrenCarousel items rendered inside the draggable content strip.ReactNode-
classNameClass names applied to the moving content strip.string-
refRef forwarded to the content strip.Ref<HTMLDivElement>-
...nativeDivPropsNative props for the content strip div.NativeCarouselContentProps-
PropDescriptionTypeDefault
childrenSlide content.ReactNode-
classNameClass names applied to the slide wrapper. Use basis utilities for multi-slide layouts.string-
refRef forwarded to the slide wrapper.Ref<HTMLDivElement>-
...nativeDivPropsNative props for the slide wrapper div.NativeCarouselItemProps-
PropDescriptionTypeDefault
classNameClass names applied to the trigger button for placement or local layout.string-
variantButton variant used by the trigger.ButtonVariant'default'
sizeButton size used by the trigger.ControlSize'sm'
disabledOverride the trigger disabled state. If omitted, the trigger is disabled when it cannot scroll.booleanDerived from scroll state
...buttonPropsButton props except icon, shape, and aria-label, which the carousel trigger owns.CarouselTriggerProps-

Types

type CarouselOrientation = 'horizontal' | 'vertical';
 
type CarouselOptions = {
  align?: 'start' | 'center' | 'end';
  loop?: boolean;
  dragFree?: boolean;
  skipSnaps?: boolean;
  startIndex?: number;
};
 
type CarouselApi = {
  scrollPrev: () => void;
  scrollNext: () => void;
  canScrollPrev: boolean;
  canScrollNext: boolean;
  selectedIndex: number;
  scrollTo: (index: number) => void;
  scrollSnapCount: number;
};
 
type CarouselApiHandler = (api: CarouselApi) => void;
type ButtonVariant = 'solid' | 'subtle' | 'default' | 'ghost' | 'link';
type ControlSize = 'sm' | 'md' | 'lg';
type NativeCarouselDivProps = ComponentProps<'div'>;
type NativeCarouselContentProps = ComponentProps<'div'>;
type NativeCarouselItemProps = ComponentProps<'div'>;
type CarouselTriggerProps = Omit<
  ComponentPropsWithoutRef<typeof Button>,
  'icon' | 'shape' | 'aria-label'
>;