Carousel
A carousel component for cycling through content slides with pixel-art styling.
| Name | Category | Description | Type | Default |
|---|---|---|---|---|
direction | Style | Carousel direction | 'horizontal' | 'vertical' | 'horizontal' |
show-arrow | Style | When to show navigation arrows | 'always' | 'hover' | 'never' | 'hover' |
show-indicators | Style | Whether to show slide indicators | boolean | true |
height | Style | Container height | string | — |
color | Color | Color theme. Supports preset names (primary / success / warning / danger / info) or custom hex colors | string | — |
indicator-trigger | Behavior | How indicators trigger navigation | 'click' | 'hover' | 'click' |
model-value / v-model | Content | Currently active slide index | number | 0 |
change | Event | Triggered when the active slide changes | (current: number, prev: number) => void | — |
default | Slot | Carousel content, should contain CarouselItem components | — | |
CarouselItemdefault | Slot | Slide content | — | |
next | Expose | Go to the next slide | () => void | — |
prev | Expose | Go to the previous slide | () => void | — |
goTo | Expose | Go to a specific slide by index | (index: number) => void | — |
Basic Usage
A simple carousel with multiple slides. Use arrow keys or click the navigation arrows and indicators to switch slides.
<template>
<px-carousel height="200px">
<px-carousel-item v-for="i in 4" :key="i">
<div
:style="{
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '24px',
fontWeight: 'bold',
background: `var(--px-color-primary-light-${i + 5})`,
color: 'var(--px-text-color-primary)',
}"
>
Slide {{ i }}
</div>
</px-carousel-item>
</px-carousel>
</template>Vertical Direction
Set direction="vertical" for a vertically scrolling carousel. Requires a fixed height.
<template>
<px-carousel height="200px" direction="vertical">
<px-carousel-item v-for="i in 4" :key="i">
<div
:style="{
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '24px',
fontWeight: 'bold',
background: `var(--px-color-warning-light-${i + 5})`,
color: 'var(--px-text-color-primary)',
}"
>
Slide {{ i }}
</div>
</px-carousel-item>
</px-carousel>
</template>Indicator Trigger
Use indicator-trigger to control whether indicators respond to click (default) or hover.
<script setup>
import { ref } from 'vue';
const trigger = ref('click');
</script>
<template>
<div style="margin-bottom: 12px">
<label>
<input type="radio" value="click" v-model="trigger" /> Click
</label>
<label style="margin-left: 12px">
<input type="radio" value="hover" v-model="trigger" /> Hover
</label>
</div>
<px-carousel height="200px" :indicator-trigger="trigger">
<px-carousel-item v-for="i in 4" :key="i">
<div
:style="{
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '24px',
fontWeight: 'bold',
background: `var(--px-color-info-light-${i + 5})`,
color: 'var(--px-text-color-primary)',
}"
>
Slide {{ i }}
</div>
</px-carousel-item>
</px-carousel>
</template>Arrow Visibility
Control when navigation arrows appear with show-arrow: always, hover (default), or never.
<script setup>
import { ref } from 'vue';
const showArrow = ref('hover');
</script>
<template>
<div style="margin-bottom: 12px">
<label>
<input type="radio" value="always" v-model="showArrow" /> Always
</label>
<label style="margin-left: 12px">
<input type="radio" value="hover" v-model="showArrow" /> Hover
</label>
<label style="margin-left: 12px">
<input type="radio" value="never" v-model="showArrow" /> Never
</label>
</div>
<px-carousel height="200px" :show-arrow="showArrow">
<px-carousel-item v-for="i in 3" :key="i">
<div
:style="{
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '24px',
fontWeight: 'bold',
background: `var(--px-color-danger-light-${i + 5})`,
color: 'var(--px-text-color-primary)',
}"
>
Slide {{ i }}
</div>
</px-carousel-item>
</px-carousel>
</template>Color Variants
Use the color prop with preset names or custom hex values to style the carousel border, shadow, arrows, and indicators.
<script setup>
import { ref } from 'vue';
const color = ref('primary');
const colors = ['primary', 'success', 'warning', 'danger', 'info'];
</script>
<template>
<div style="margin-bottom: 12px; display: flex; gap: 8px">
<px-button
v-for="c in colors"
:key="c"
:type="c"
:plain="color !== c"
size="small"
@click="color = c"
>
{{ c }}
</px-button>
</div>
<px-carousel height="200px" :color="color">
<px-carousel-item v-for="i in 4" :key="i">
<div
:style="{
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '24px',
fontWeight: 'bold',
background: `var(--px-fill-color-light)`,
color: 'var(--px-text-color-primary)',
}"
>
Slide {{ i }}
</div>
</px-carousel-item>
</px-carousel>
</template>Programmatic Navigation
Access next(), prev(), and goTo(index) methods via a template ref for programmatic control.
<script setup>
import { ref } from 'vue';
const carouselRef = ref();
const current = ref(0);
</script>
<template>
<div style="margin-bottom: 12px; display: flex; gap: 8px">
<px-button @click="carouselRef?.prev()">Prev</px-button>
<px-button @click="carouselRef?.next()">Next</px-button>
<px-button @click="carouselRef?.goTo(0)">Go to 1</px-button>
<px-button @click="carouselRef?.goTo(2)">Go to 3</px-button>
<span style="line-height: 32px; margin-left: 8px">Current: {{ current }}</span>
</div>
<px-carousel ref="carouselRef" v-model="current" height="200px" show-arrow="always">
<px-carousel-item v-for="i in 4" :key="i">
<div
:style="{
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '24px',
fontWeight: 'bold',
background: `var(--px-color-info-light-${i + 5})`,
color: 'var(--px-text-color-primary)',
}"
>
Slide {{ i }}
</div>
</px-carousel-item>
</px-carousel>
</template>