Yugen UI

Carousel

Carousel presents content one slide at a time, navigated with previous / next buttons, dots, thumbnails or the arrow keys.

The track uses CSS scroll-snap, so swiping and scrolling work natively on every device. loop wraps around at both ends; slidesPerView (e.g. 1.15) and gap reveal part of the next slide. Autoplay shows its progress inside the active dot and pauses on hover, when a slide has focus or when the tab is hidden. It doesn't start on its own if the user prefers reduced motion. Each slide is labeled “Slide x / n”; the dots and thumbnails are a tablist controlled with the arrow keys (swapped in RTL) and Home / End.

Fluent 2 for the web

Tokens, components and docs stay in sync.

Bloom follows your brand

Change data-brand and the illustration follows.

Expressive style

Gradients are for illustrations and heroes only.

Light & dark

Switch themes right in the example frame.

Import

Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.

TSX
// npm install yugen-uiimport {  Carousel, CarouselViewport, CarouselCard, CarouselNavContainer, CarouselThumbnails, CarouselThumbnail,} from "yugen-ui";

Variants

Each tile is a standalone example: hover to copy, or press Code to see the source.

Mountains at dawn

Mountains at dawn

Hills at sunset

Hills at sunset

Pine forest

Pine forest

Lake at night

Lake at night

Desert

Desert

Peek & loop

slidesPerView={1.15} reveals 15% of the next slide, gap="medium" widens the spacing; loop wraps around at both ends.

Shortcuts

Press Ctrl + K to open the command palette from anywhere.

Dark theme

Switch between Web Light and Web Dark right in the example frame.

Local brand

Set data-brand on an element to recolor just that area.

Autoplay with progress

The active dot grows longer and fills up over autoplayInterval; hovering or focusing a slide, or hiding the tab, pauses it.

Mountains at dawn
Hills at sunset
Pine forest
Lake at night
Desert

Thumbnails

CarouselThumbnails replaces the dots: a tablist of small images that scrolls to the active one. Give each image an aria-label.

Usage

Do
  • Give the Carousel an aria-label. Each slide is labeled “Slide x / n” automatically; thumbnails should have their own aria-label.
  • Keep 3–6 slides of the same kind; use a fractional slidesPerView (1.15, 2.5) to hint that more content follows.
  • When autoplay is on, always show the pause button (CarouselNavContainer showAutoplayToggle).
Don't
  • Don't put important information only in a hidden slide.
  • Don't turn autoplay on by default for content people need to read carefully.
  • Don't use both dots and thumbnails in the same Carousel.

Props

Prop · TypeDefaultDescription
loopbooleanDefault: falseWraps around at both ends. The old name circular is deprecated (removed in 1.0).
slidesPerViewnumberDefault: —Number of slides visible at once; a fraction reveals the next slide (1.15, 2.5). Leave it empty for 100%.
gap"none" | "extra-small" | "small" | "medium" | "large" | "extra-large"Default: "small"Spacing between slides (spacing token). The short names "XS" … "XL" are deprecated (removed in 1.0).
autoplay / defaultAutoplay / onAutoplayChangeboolean / boolean / (value) => voidDefault: — / falseAutoplay (controlled / uncontrolled). defaultAutoplay is ignored under prefers-reduced-motion.
autoplayIntervalnumberDefault: 4000Time per slide (ms); progress shows in the active dot / thumbnail.
activeIndex / defaultActiveIndex / onActiveIndexChangenumber / number / (index: number) => voidDefault: — / 0Current slide, counted from 0 (controlled / uncontrolled); called when the current slide changes.
CarouselCard.classNamestringDefault: —basis-full by default; basis-4/5 or basis-1/2 when slidesPerView isn't used.
CarouselNavContainer.showAutoplayTogglebooleanDefault: falseShows the button that turns autoplay on / off. The old name autoplay is deprecated (removed in 1.0).
CarouselNavContainer.previousLabel / nextLabelstringDefault: "Previous slide" / "Next slide"aria-label of the navigation buttons. The old name prevLabel is deprecated (removed in 1.0).
CarouselThumbnails / CarouselThumbnailHTMLAttributes / ButtonHTMLAttributesDefault: —Thumbnail tablist; each CarouselThumbnail matches the slide at the same position.

Messages

Text built into the component: labels, aria-labels, screen reader announcements.

English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.

messages.carousel

Key · TypeDefault (English)messagesVi
slide(index: number, count: number) => string

Tên từng slide / chấm / thumbnail và thông báo slide hiện tại; index đếm từ 1.

Default (English)(index, count) => `Slide ${index} of ${count}`messagesVi(index, count) => `Slide ${index} / ${count}`
roleDescriptionstring

aria-roledescription của vùng carousel.

Default (English)"carousel"messagesVi"carousel"
slideRoleDescriptionstring

aria-roledescription của từng slide.

Default (English)"slide"messagesVi"slide"
previousstring

aria-label nút slide trước.

Default (English)"Previous slide"messagesVi"Slide trước"
nextstring

aria-label nút slide sau.

Default (English)"Next slide"messagesVi"Slide tiếp theo"
autoplaystring

aria-label nút bật / tắt tự chạy.

Default (English)"Autoplay"messagesVi"Tự động chạy"
chooseSlidestring

aria-label dãy chấm / thumbnail (tablist).

Default (English)"Choose slide"messagesVi"Chọn slide"