Carousel
A horizontally scrolling collection of slides riding native CSS scroll snap.
View code
<Carousel
aria-label="Product tour"
mix={[is("100%"), maxIs("32rem")]}
style={{ "--ui-carousel-slide-size": "100%", "--ui-carousel-gap": "0px" }}
>
<Carousel.Viewport id="preview-tour" mix={[carouselControls()]}>
<Carousel.Track>
{SLIDES.map((slide) => (
<Carousel.Slide key={slide.id} data-carousel-slide aria-label={slide.title}>
<figure mix={[vstack({ gap: 2, align: "stretch" }), m(0)]}>
<img
src={poster(slide.hue)}
alt={`${slide.title} screenshot`}
mix={[is("100%"), bs("9rem"), fit("cover"), rounded("lg")]}
/>
<figcaption mix={[vstack({ gap: 0, align: "start" })]}>
<span mix={[text("sm"), weight("medium")]}>{slide.title}</span>
<span mix={[text("xs"), fg("neutral")]}>{slide.caption}</span>
</figcaption>
</figure>
</Carousel.Slide>
))}
</Carousel.Track>
</Carousel.Viewport>
<Carousel.Controls mix={[justify("between")]}>
<Carousel.Previous commandfor="preview-tour" aria-label="Previous slide" />
<div mix={[hstack({ gap: 2, align: "center" })]}>
{SLIDES.map((slide, index) => (
<button
key={slide.id}
type="button"
commandfor="preview-tour"
command="--ui-goto"
data-slide={String(index)}
aria-label={`Go to ${slide.title}`}
mix={[
is("0.5rem"),
bs("0.5rem"),
m(0),
rounded("full"),
border({ width: 0 }),
cursor("pointer"),
// carouselControls() marks the dot naming the slide in view.
when("&:not([aria-current])", bg("neutral.border-hover")),
when("&[aria-current]", bg("neutral.solid")),
]}
/>
))}
</div>
<Carousel.Next commandfor="preview-tour" aria-label="Next slide" />
</Carousel.Controls>
</Carousel>Installation
An ordinary dependency: install it, import the theme once, and import the component where it is used.
npm add @sdxc/uiimport "@sdxc/ui/theme.css";Usage
import { Carousel } from "@sdxc/ui";The carousel root: a <section> stacking Carousel.Viewport and
Carousel.Controls in a column, declaring the --ui-carousel-*
custom properties its descendants read with per-instance defaults.
Composition
The parts the component publishes, each a static property of the host.
CarouselCarousel.ViewportA<div>scrolling Carousel.Track along the inline axis via logical properties for correct writing direction, with mandatory scroll-snap stops; scroll padding reads--ui-carousel-paddingto clear the track's own padding.Carousel.TrackThe carousel's slide row: a<div>laying its Carousel.Slide children out in one inline row, gapped by--ui-carousel-gapand padded by--ui-carousel-paddingso the first and last slide can still center.Carousel.SlideA single slide: a<div>held at--ui-carousel-slide-sizealong the inline axis, snapping to its inline-start edge so the viewport settles on a slide boundary.Carousel.ControlsThe carousel's control row: a<div>laying Carousel.Previous and Carousel.Next out as an end-aligned, vertically centered row.Carousel.PreviousA static control scrolling Carousel.Viewport named bycommandforback one slide when a hydratedcarouselControls()mixin handles"--ui-prev"; customchildrenreplacing the chevron still need their ownaria-label.Carousel.NextA static control scrolling Carousel.Viewport named bycommandforforward one slide when a hydratedcarouselControls()mixin handles"--ui-next"; customchildrenreplacing the chevron still need their ownaria-label.
Props
Read from the component's own types, so every prop, every default and every allowed value is listed.
Also accepts everything in TagProps<"section">.
Carousel.Viewport
Also accepts everything in TagProps<"div">.
Carousel.Track
Also accepts everything in TagProps<"div">.
Carousel.Slide
Also accepts everything in TagProps<"div">.
Carousel.Controls
Also accepts everything in TagProps<"div">.
Carousel.Previous
| Prop | Type | Description |
|---|---|---|
commandfor | string | id of the Carousel.Viewport this control scrolls back through. |
command? | "--ui-prev" | Invoker Commands verb a carouselControls() mixin listens for. Defaults to "--ui-prev". |
Also accepts everything in Omit<Button.Props, "commandfor" | "command">.
Carousel.Next
| Prop | Type | Description |
|---|---|---|
commandfor | string | id of the Carousel.Viewport this control scrolls forward through. |
command? | "--ui-next" | Invoker Commands verb a carouselControls() mixin listens for. Defaults to "--ui-next". |
Also accepts everything in Omit<Button.Props, "commandfor" | "command">.