Flow / Carousel
A carousel for stepping through a sequence of slides, with previous and next controls and optional looping.
Basic Carousel
<div class="vd-flow" data-vd-loop="true">
<div class="vd-flow-track">
<div class="vd-flow-slide">Slide One</div>
<div class="vd-flow-slide">Slide Two</div>
<div class="vd-flow-slide">Slide Three</div>
</div>
<button class="vd-flow-prev" aria-label="Previous slide">‹</button>
<button class="vd-flow-next" aria-label="Next slide">›</button>
</div>Fade Variant
<!-- Add .vd-flow-fade for crossfade -->
<div class="vd-flow vd-flow-fade">
<div class="vd-flow-track">
<div class="vd-flow-slide">...</div>
<div class="vd-flow-slide">...</div>
</div>
<button class="vd-flow-prev">‹</button>
<button class="vd-flow-next">›</button>
</div>Autoplay with Indicators
<!-- Autoplay with indicators -->
<div class="vd-flow"
data-vd-autoplay="true"
data-vd-interval="4000"
data-vd-loop="true">
<div class="vd-flow-track">
<div class="vd-flow-slide">...</div>
<div class="vd-flow-slide">...</div>
</div>
<button class="vd-flow-prev">...</button>
<button class="vd-flow-next">...</button>
<div class="vd-flow-indicators">
<button aria-label="Go to slide 1"></button>
<button aria-label="Go to slide 2"></button>
</div>
</div>Compact Size
Large Size
API Reference
Wiring
import { ref } from 'vue';
import { useFlow } from "@vanduo-oss/vd3";
const root = ref<HTMLElement | null>(null);
useFlow(root); // wires every .vd-flow inside root; cleanup on unmount
// react to slide changes
root.value?.addEventListener('flow:change', (e) => {
console.log('slide', e.detail.current); // { current, previous, total }
});CSS Classes
| Class | Description | Type |
|---|---|---|
.vd-flow | Base carousel container — required | Base |
.vd-carousel | Alias for .vd-flow | Base |
.vd-flow-track | Inner wrapper holding all slides; handles translation | Structure |
.vd-flow-slide | Individual slide element within the track | Structure |
.vd-flow-prev | Previous-slide navigation button | Control |
.vd-flow-next | Next-slide navigation button | Control |
.vd-flow-indicators | Container for dot indicators; one button per slide | Control |
.vd-flow-fade | Crossfade transition instead of horizontal slide | Modifier |
.vd-flow-compact | Reduced padding and height for compact layouts | Size |
.vd-flow-lg | Increased padding and height for hero-style carousels | Size |
Data Attributes
| Attribute | Description | Default |
|---|---|---|
data-vd-autoplay | Enable automatic slide advancement when set to "true" | false |
data-vd-interval | Time in milliseconds between auto-advances | 5000 |
data-vd-loop | Loops back to the first slide after the last; set to "false" to disable | true |
Composable API
| Symbol | Description |
|---|---|
useFlow(root) | Composable — wires every .vd-flow inside the root ref (prev/next, indicators, keyboard, touch swipe, autoplay). Call once in setup(). |
(automatic cleanup) | Listeners and autoplay timers are cleared on component unmount. |
Events
| Event | Description | Detail |
|---|---|---|
flow:change | Fired on the .vd-flow element after a slide transition completes | { index, slide, direction } |
Accessibility
- Navigation buttons include
aria-labelattributes for screen readers - Indicator buttons use
aria-label="Go to slide N"for identification - Active indicator receives
aria-current="true"and.is-activeclass - Autoplay pauses on
:hoverand:focus-withinto respect user interaction - Keyboard navigation: ArrowLeft / ArrowRight move between slides when focused
- The carousel container uses
role="region"andaria-roledescription="carousel" - Each slide uses
role="group"andaria-roledescription="slide"