If a carousel only has a single item, no controls and no pagination are
rendered.
Required CSS
The element with the -items-container class has to be a horizontal scroll
container, since the controls and the auto rotation move the carousel by
scrolling it:
.carousel-items-container {
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.carousel-items {
display: flex;
}
.carousel-item {
flex: 0 0 100%;
scroll-snap-align: center;
}
The items must not shrink. Scroll snapping is optional, but without it a
slide can come to rest half shown. Whether the movement is animated
depends on scroll-behavior. If you animate it, turn it off with a
@media (prefers-reduced-motion) media query.
Styling
The carousel has a data-active-index attribute, and data-paused while
the rotation is stopped. The visible slide has aria-current, its
pagination tab has aria-selected, and with loop={false} the previous and
next buttons are disabled at the ends.
The pause button changes its label, not its content. Put both icons into the
slot and use a CSS selector on data-paused to pick one:
<:pause label="Pause slide show" resume_label="Resume slide show">
<.icon name="pause" class="when-running" />
<.icon name="play" class="when-paused" />
</:pause>
.carousel:not([data-paused]) .when-paused,
.carousel[data-paused] .when-running {
display: none;
}
Localization
carousel_roledescription, slide_roledescription, pagination_label and
the labels of the :pause slot default to English. They are announced by
screen readers and should be translated. The pagination_slide_label and
the labels of the :previous and :next slots should also be translated.
Usage
<.carousel label="Our Dogs">
<:previous label="Previous Slide">
<Heroicons.chevron_left />
</:previous>
<:next label="Next Slide">
<Heroicons.chevron_right />
</:next>
<:item label="1 of 3">
<.image
src="https://github.com/woylie/doggo/blob/main/assets/images/dog_1.webp?raw=true"
alt="A gray-muzzled dog in a camouflage coat and harness."
ratio="16:9"
/>
</:item>
<:item label="2 of 3">
<.image
src="https://github.com/woylie/doggo/blob/main/assets/images/dog_2.webp?raw=true"
alt="A small curly-haired white dog seen from the side."
ratio="16:9"
/>
</:item>
<:item label="3 of 3">
<.image
src="https://github.com/woylie/doggo/blob/main/assets/images/dog_3.webp?raw=true"
alt="A large cream-colored dog on a leash, looking up."
ratio="16:9"
/>
</:item>
</.carousel>
This component needs the Doggo.Carousel JavaScript hook. See
Phoenix LiveView Hooks for
registering it.
Keyboard
Left and Right - previous or next slide, with the focus on a
pagination tab. With loop they wrap, without it they stop at the ends.
Home and End - first or last slide, with the focus on a pagination
tab.
The pagination is a single tab stop. The arrow keys need the colocated hook.