Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsLayout Blocks

Carousel

Touch-friendly slider with multiple variants — slide, card/3D, fade, and free-scroll. Built on Embla Carousel with autoplay, loop, RTL, and vertical orientation support.

Showcase

Usage

import {
  Carousel,
  CarouselContent,
  CarouselItem,
  CarouselPrevious,
  CarouselNext,
  CarouselDots,
} from "@tessinaui/ui/carousel";

<Carousel size="full" loop autoplay={4000}>
  <CarouselContent>
    <CarouselItem>Slide 1</CarouselItem>
    <CarouselItem>Slide 2</CarouselItem>
    <CarouselItem>Slide 3</CarouselItem>
  </CarouselContent>
  <CarouselPrevious />
  <CarouselNext />
  <CarouselDots />
</Carousel>

API

Carousel

PropTypeDefaultDescription
variant"default" | "card" | "fade" | "scroll""default"Animation style — card scales adjacent slides, fade crossfades, scroll is native overflow scroll
size"sm" | "md" | "lg" | "full" | "auto""full"Default item width — sm=200px, md=300px, lg=420px, full=viewport, auto=content
rounded"none" | "sm" | "md" | "lg" | "xl" | "full""none"Corner radius applied to inner card wrapper (variant=card)
orientation"horizontal" | "vertical""horizontal"Scroll axis
gap"none" | "sm" | "md" | "lg" | "xl""md"Spacing between items (0/8/16/24/32px)
align"start" | "center" | "end""start"Where snap points align within the viewport
loopbooleanfalseInfinite loop
dragFreebooleanfalseFree momentum scrolling — no snapping
autoplayboolean | numberfalseAuto-advance — true = 3000ms, or pass a number for custom delay
dir"ltr" | "rtl""ltr"Text direction — RTL mirrors scroll
optsEmblaOptionsType—Pass-through options to underlying Embla instance
setApi(api: CarouselApi) => void—Receive the Embla API instance for imperative control

CarouselItem

PropTypeDefaultDescription
sizeCarouselSizeinheritedOverride the carousel's size for this item

CarouselPrevious / CarouselNext

PropTypeDefaultDescription
navVariant"default" | "ghost" | "solid""default"Button visual — default is bordered white, ghost is translucent, solid is primary fill
navSize"sm" | "md" | "lg""md"Button size (32/40/48px square)
position"overlay" | "inline""overlay"overlay floats over the viewport; inline flows in normal layout

CarouselDots

PropTypeDefaultDescription
dotVariant"circle" | "pill" | "line""circle"Indicator shape

useCarouselApi

const { setApi, current, count } = useCarouselApi();

<Carousel setApi={setApi} ... />

<p>{current + 1} / {count}</p>

Variants

default

Standard slide carousel — instant snap with smooth easing.

<Carousel size="full">...</Carousel>

card

Center-focused carousel where adjacent slides scale down and fade. Modeled after the HeroUI carousel pattern. Pair with align="center" and size="lg" for the classic stacked-card effect.

<Carousel variant="card" size="lg" align="center" loop gap="lg">
  <CarouselContent>...</CarouselContent>
</Carousel>

fade

Opacity crossfade between slides — best for full-width testimonials, hero rotations, or anywhere a side-scroll animation would feel jarring.

<Carousel variant="fade" size="full" loop autoplay={5000}>
  <CarouselContent>...</CarouselContent>
</Carousel>

scroll

Native overflow scroll with momentum — no snap, no arrows, just drag. The Satispay / Afterpay "explore brands" pattern. Combine with dragFree for the smoothest feel.

<Carousel variant="scroll" size="sm" gap="md" dragFree>
  <CarouselContent>...</CarouselContent>
</Carousel>

Autoplay

Pass a boolean to use the default 3000ms interval, or a number for custom timing. Autoplay pauses on user interaction and on hover.

<Carousel autoplay loop>...</Carousel>
<Carousel autoplay={6000} loop>...</Carousel>

Vertical orientation

<Carousel orientation="vertical" className="h-64">
  <CarouselContent className="h-full">
    <CarouselItem>...</CarouselItem>
  </CarouselContent>
  <CarouselPrevious />
  <CarouselNext />
</Carousel>

RTL

The carousel's scroll direction reverses and the prev/next icons flip naturally.

<Carousel dir="rtl" loop>...</Carousel>

Skeleton

Render CarouselSkeleton while content loads.

<CarouselSkeleton count={3} size="md" rounded="lg" aspectRatio="4/3" />

Accessibility

  • Root has role="region" and aria-roledescription="carousel"
  • Each item has role="group" and aria-roledescription="slide"
  • Prev / Next buttons have aria-label="Previous slide" / "Next slide"
  • Dots have aria-label="Go to slide N" and aria-current on the active dot
  • Touch / swipe / keyboard arrow navigation handled by Embla

Card

A flexible surface container for grouping related content. Four variants (elevated/outlined/filled/ghost), five intents, six rounded options, five sizes, horizontal layout, interactive states, and LTR/RTL support.

Divider

A thin line that separates content. Horizontal or vertical, solid / dashed / dotted, five thickness sizes, tonal colours, optional inline label, and RTL support.

On this page

ShowcaseUsageAPICarouselCarouselItemCarouselPrevious / CarouselNextCarouselDotsuseCarouselApiVariantsdefaultcardfadescrollAutoplayVertical orientationRTLSkeletonAccessibility