Carousel
shadcn-htmx/carouselFreeComponent
A slideshow built on native CSS scroll-snap (snap-x mandatory; each slide snap-center). WAI-ARIA carousel/slide roles, real <button> prev/next that scroll by one slide; touch, trackpad and keyboard scrolling are the platform's.
Live preview
live · rendered by the registry
Rendered by shadcn-htmx on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://shadcn-htmx.productdevbook.com/r/carousel.jsonSource
1/** @jsxImportSource hono/jsx */2import type { PropsWithChildren } from "hono/jsx"3import { cn, type ClassValue } from "@/registry/lib/cn"45// Carousel — shadcn-htmx, htmx v4 + Tailwind v4.6//7// shadcn/ui ships a Carousel built on the Embla JS engine. We don't copy that8// React code; we mirror its anatomy (Carousel / CarouselContent / CarouselItem9// / CarouselPrevious / CarouselNext) and translate it to a NATIVE, no-engine10// implementation. Source of truth for the API shape:11// repos/shadcn-ui/apps/v4/registry/new-york-v4/ui/carousel.tsx (anatomy only)12//13// Accessibility contract follows the WAI-ARIA APG carousel pattern (Basic14// carousel: previous/next controls, no auto-rotation):15// repos/aria-practices/content/patterns/carousel/carousel-pattern.html16// repos/aria-practices/content/patterns/carousel/examples/carousel-1-prev-next.html17//18// How this differs from Embla / shadcn:19// - The scroller is a plain horizontally-overflowing element using CSS20// scroll-snap (`snap-x snap-mandatory`, each slide `snap-center`). Scrolling21// itself is therefore native: mouse wheel, trackpad, touch swipe, and the22// browser's own keyboard scrolling all work with zero JS, and the snap23// points keep slides aligned. Tailwind v4 ships these utilities natively24// (repos/tailwindcss/.../src/utilities.ts: snap-x, snap-mandatory,25// snap-center, scroll-smooth, overscroll-x-contain; motion-safe variant in26// src/variants.ts).27// - The only thing the platform does NOT give us is "advance by exactly one28// slide when the Prev/Next buttons are pressed" + the buttons' disabled29// state at the ends. public/site.js (keyed on data-slot="carousel") owns30// that: it calls Element.scrollBy() with the slide width31// (repos/mdn/files/en-us/web/api/element/scrollby/index.md).32//33// APG roles/states/properties (Basic carousel):34// - Root container: role="group" + aria-roledescription="carousel" + an35// accessible name via aria-label / aria-labelledby. Because the36// roledescription is "carousel", the label must NOT contain the word37// "carousel". (carousel-pattern.html, "Basic carousel elements")38// - Each slide: role="group" + aria-roledescription="slide" + an accessible39// name. When slides have no unique name, "N of M" is the sanctioned40// fallback because group elements don't support aria-setsize/aria-posinset.41// - The element wrapping the slides has aria-atomic="false" + aria-live.42// … truncated
More from shadcn-htmx
All 83 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | shadcn-htmx | Components | Free | no deps | |
| Active Searchactive-search | shadcn-htmx | Components | Free | no deps | |
| Alertalert | shadcn-htmx | Components | Free | no deps | |
| Alert Dialogalert-dialog | shadcn-htmx | Components | Free | no deps | |
| Aspect Ratioaspect-ratio | shadcn-htmx | Components | Free | no deps | |
| Auto Gridauto-grid | shadcn-htmx | Components | Free | no deps | |
| Autocompleteautocomplete | shadcn-htmx | Components | Free | no deps | |
| Autosize Textareaautosize-textarea | shadcn-htmx | Components | Free | no deps |
