Getting Started
App Providerglobal.d.tsThemesTypes
cn(...args)Text ParserUnits Converters
AnchorAvatarBreadcrumbBurgerButtonCardCarouselCheckerCodeColor PickerCommandConfettiCopyButtonDouble Helix WordsFloating IndicatorGroupHighlight TextIndicatorInputKbdLabelLoaderPaginationPassword RequirementPolymorphic SlotProgressProseRatingRunning AreaScroll AreaSheetsSkeletonSliderStackSvgTableTabsTextareaTimelineTimesToasterTooltipTyping WordsTypography
useClickOutsideuseClipboarduseDeviceInfouseDialoguseDidUpdateuseDirectionuseDisclosureuseDocumentTitleuseDocumentVisibilityuseElementInfouseEyeDropperuseFetchuseFullscreenuseGeoLocationuseHotkeysuseHoveruseIduseImagePopupuseInputStateuseIntersectionuseIntervaluseIsomorphicEffectuseListStateuseLocalStorageuseMeasureScrollbaruseMediaQueryuseMergedRefuseMouseuseMoveuseMutationObserveruseNetworkuseOpenStateuseOrientationuseOSusePaginationusePWAInstalleruseRandomColorsuseReducedMotionuseReloaduseResizeObserveruseScrollIntoViewuseStateHistoryuseTimeoutuseTouchuseTriggeruseUncontrolleduseValidatedStateuseViewportSizeuseWindowEventuseWindowScroll
Docs
Web
Components
Carousel
Card

A flexible container for organizing and displaying content in a structured format.

Checker

A versatile input component that includes checkboxes, switches, and radio buttons for interactive selection.


Edit this page on GitHub
  • Started
  • Utilities
  • Configuration
  • Components
  • Hooks
  • Examples
  • Github
  • Contributing
⌘+J

© 2025 oeri rights MIT


Designed in Earth-616

Built by oeri

Carousel

A component that allows users to cycle through a set of items, such as images or content, in a horizontal or vertical layout.

Usage

Basic usage example to quickly understand the functionality of the Carousel component. Demonstrates slide navigation, default layout, and interaction behaviors.

1
2
3
4
5
import { Carousel } from "@/ui/carousel";

export function CarouselDemo() {
  return (
    <Carousel opts={{ dragFree: false }}>
      {[...Array(5)].map((_, index) => (
        <Carousel.Item key={index}>
          <div className="flex h-64 w-[300px] min-w-[300px] items-center justify-center rounded-lg border bg-background text-muted shadow-sm font-heading">
            {index + 1}
          </div>
        </Carousel.Item>
      ))}
    </Carousel>
  );
}

Peer Dependencies

Install required dependencies before using the Carousel. These libraries handle the low-level carousel mechanics to ensure smooth performance and rich features.

pnpm add embla-carousel@latest embla-carousel-react@latest
npm install embla-carousel@latest embla-carousel-react@latest
yarn add embla-carousel@latest embla-carousel-react@latest
bun add embla-carousel@latest embla-carousel-react@latest

Properties

Interactive configurator to customize the Carousel component. Explore options such as slide spacing, alignment, looping behavior, and other layout or navigation settings.

1
2
3
4
5
Spacing
Height
import { Carousel, type CarouselProps } from "@/ui/carousel";

export function CarouselDemo() {
  return (
    <Carousel height={448}>
      {[...Array(5)].map((_, index) => (
        <Carousel.Item key={index}>
          <div className="flex h-64 w-[300px] min-w-[300px] items-center justify-center rounded-lg border bg-background text-muted shadow-sm font-heading">
            {index + 1}
          </div>
        </Carousel.Item>
      ))}
    </Carousel>
  );
}

Create Carousel with Hook

Demonstrates how to control the Carousel manually using the provided hook API. Gives you more flexibility and fine-grained control over slide behavior and carousel interactions.

1
2
3
4
5
"use client";
import { useCarousel } from "@/ui/carousel";
import { cn } from "@/utils/cn";
import type { CarouselProps } from "@/ui/carousel";

import classes from "./carousel.module.css";

export function CarouselHooksDemo({ plugins,  orientation="horizontal" }: { orientation?: CarouselProps["orientation"]; plugins?: CarouselProps["plugins"] }) {
  const { carouselRef, stopOnHover, opts } = useCarousel({ orientation }, plugins);
  const dataState = { "data-orientation": opts.orientation };
  return (
    <div ref={carouselRef} className={cn("group/viewport", classes.viewport)} {...dataState}>
      <div className={classes.container} {...dataState}>
        {[...Array(5)].map((_, index) => (
          <div key={index} className={classes.content} {...dataState} {...stopOnHover}>
            <div className={classes.item} {...dataState}>{index + 1}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

Plugins

Optional plugins to extend the functionality of your Carousel. Install additional features such as auto-scrolling and autoplay for richer experiences.

pnpm add embla-carousel-auto-scroll@latest embla-carousel-autoplay@latest
npm install embla-carousel-auto-scroll@latest embla-carousel-autoplay@latest
yarn add embla-carousel-auto-scroll@latest embla-carousel-autoplay@latest
bun add embla-carousel-auto-scroll@latest embla-carousel-autoplay@latest

AutoScroll

Example using the AutoScroll plugin to enable continuous, smooth scrolling of slides without manual input. Ideal for showcases, product sliders, or passive visual storytelling.

1
2
3
4
5
import { Carousel } from "@/ui/carousel";
import AutoScroll from "embla-carousel-auto-scroll";

export function CarouselAutoScrollDemo() {
  return (
    <Carousel plugins={[AutoScroll({ playOnInit: true, speed: 0.35, direction: "forward" })]}>
      {[...Array(5)].map((_, index) => (
        <Carousel.Item key={index}>
          <div className="flex h-64 w-[300px] min-w-[300px] items-center justify-center rounded-lg border bg-background text-muted shadow-sm font-heading">
            {index + 1}
          </div>
        </Carousel.Item>
      ))}
    </Carousel>
  );
}

Autoplay

Example using the Autoplay plugin to advance slides automatically at timed intervals. Useful for banner sliders, announcement carousels, or interactive landing pages.

1
2
3
4
5
import { Carousel } from "@/ui/carousel";
import AutoPlay from "embla-carousel-autoplay";

export function CarouselAutoPlayDemo() {
  return (
    <Carousel plugins={[AutoPlay({ playOnInit: true })]}>
      {[...Array(5)].map((_, index) => (
        <Carousel.Item key={index}>
          <div className="flex h-64 w-[300px] min-w-[300px] items-center justify-center rounded-lg border bg-background text-muted shadow-sm font-heading">
            {index + 1}
          </div>
        </Carousel.Item>
      ))}
    </Carousel>
  );
}

Structure

Independent Components

import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, CarouselIndicators } from "@/ui/carousel";
 
export function CarouselDemo() {
  return (
    <Carousel>
      <CarouselContent>
        {datas.map((data, index) => (
          <CarouselItem key={index}>{index}</CarouselItem>
        ))}
      </CarouselContent>
      <CarouselPrevious />
      <CarouselNext />
      <CarouselIndicators />
    </Carousel>
  );
}

Compound Components

"use client";
import { Carousel } from "@/ui/carousel";
 
export function CarouselDemo() {
  return (
    <Carousel>
      <Carousel.Content>
        {datas.map((data, index) => (
          <Carousel.Item key={index}>{index}</Carousel.Item>
        ))}
      </Carousel.Content>
      <Carousel.Previous />
      <Carousel.Next />
      <Carousel.Indicators />
    </Carousel>
  );
}

Declarative Props API

import { Carousel } from "@/ui/carousel";
 
export function CarouselDemo() {
  return (
    <Carousel withControls withIndicators>
      {datas.map((data, index) => (
        <Carousel.Item key={index}>{index}</Carousel.Item>
      ))}
    </Carousel>
  );
}

API References

Styles API

type T = "root" | "content" | "item" | "previous" | "next" | "indicators" | "indicator";
Styles APITypeDefaultAnnotation
unstyled?Partial<Record<T, boolean>>falseif true, default styles will be removed
className?stringundefinedpass to root component <div>
classNames?Partial<Record<T, string>>undefined
style?CSSPropertiesundefinedpass to root component <div>
styles?Partial<Record<T, CSSProperties>>undefined

Props API

Props APITypeDefaultAnnotation
dir?"ltr" | "rtl"ltr
orientation?"horizontal" | "vertical"horizontal
onPreviousSlide?() => voidundefinedCalled when previous itemr is shown
onNextSlide?() => voidundefinedCalled when next item is shown
onItemChange?(index: number) => voidundefinedCalled with slide index when slide changes
setApi?(api: CarouselApi) => voidundefinedCalled with item index when item changes
plugins?EmblaPluginType[]undefinedCalled embla API as ref
spacing?number | string16Key of number to set gap between slides
withControls?booleanfalseDetermines whether next/previous controls should be displayed
withIndicators?booleanfalseDetermines whether indicators should be displayed
opts?CarouselOptionsundefinedPassing props EmblaOptionsType
controlsOffset?number | string0Controls position of the next and previous controls
height?CSSProperties["height"]undefinedSlides container height, required for vertical orientation
controlSize?CSSProperties["width"]undefinedControls size of the next and previous controls
withKeyboardEvents?booleantrueDetermines whether arrow key should switch slides
previousControlProps?ComponentPropsWithoutRef<"button">undefinedProps passed down to previous control
nextControlProps?ComponentPropsWithoutRef<"button">undefinedProps passed down to next control
icons?{ previous?: ReactNode; next?: React.ReactNode }ChveronIconIcon of the previous or next as control

Source Codes

Full working code example, including necessary markup and styles. You can copy and paste this code directly to start using the component immediately.

carousel.tsx