@blossom-carousel/vue
Blossom Carousel
A native-scroll-first carousel enhanced with drag support for Vue.
Installation
npm install @blossom-carousel/vue
Full installation instructions
Vue
import { BlossomCarousel } from "@blossom-carousel/vue";
import "@blossom-carousel/vue/style.css";
const app = createApp({});
app.component("BlossomCarousel", BlossomCarousel);
Nuxt
Install globally plugins/blossom-carousel.js
import { BlossomCarousel } from "@blossom-carousel/vue";
import "@blossom-carousel/vue/style.css";
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component("BlossomCarousel", BlossomCarousel);
});
Usage
<BlossomCarousel>
<div v-for="i in 12">Slide {{ i }}</div>
</BlossomCarousel>
as
Define the HTMLElement of the carousel root.
<BlossomCarousel as="ul">
<li v-for="i in 12">Slide {{ i }}</li>
</BlossomCarousel>
Renders as
<ul>
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
...
</ul>
Navigation controls
Place previous, next, and dot controls outside the carousel with <BlossomPrev>, <BlossomNext>, and <BlossomDots>. Link them to the carousel with an id on <BlossomCarousel>, and a matching for prop on each control and mark slides with data-blossom-slide.
<BlossomCarousel id="my-carousel">
<div v-for="i in 12" :key="i" data-blossom-slide>Slide {{ i }}</div>
</BlossomCarousel>
<BlossomPrev for="my-carousel" />
<BlossomDots for="my-carousel" />
<BlossomNext for="my-carousel" />
Prev/Next Buttons
<BlossomPrev> and <BlossomNext> are aware of configured scroll-snap and will navigate between snap points. When no scroll-snap is configured, they will slide they carousel proportionally.
Slot your own content to replace the default button icon.
<BlossomPrev for="my-carousel">
<span>Previous</span>
</BlossomPrev>
Custom navigation UI
useNavigation exposes the same reactive state the built-in controls use. Pass a string, a ref, or undefined:
<script setup>
import { useId } from "vue";
import { useNavigation } from "@blossom-carousel/vue";
const carouselId = useId();
const state = useNavigation(carouselId);
</script>
state is a ref with canPrev, canNext, activeIndex, and count.
Dots
<BlossomDots> renders one button per slide marked with data-blossom-slide.
Default styles can be themed with CSS custom properties on the component or any ancestor:
/* defaults */
--blossom-dot-size: 0.625rem;
--blossom-dot-radius: 50%;
--blossom-dot-color: currentColor;
--blossom-dot-opacity: 0.35;
--blossom-dot-hover-opacity: 0.6;
--blossom-dot-active-opacity: 1;
To bring your own dots, provide a default slot and render <BlossomDot> inside it. This will configure the dot as a <button> with navigation wired up.
Now you can style the dot as you please and attach any button attributes you need.
<BlossomDots for="my-carousel" v-slot="{ index, active }">
<BlossomDot
class="my-dot"
:data-active="active"
:aria-label="`Photo ${index + 1}`"
>
{{ index + 1 }}
</BlossomDot>
</BlossomDots>
Scroll behavior
Every navigation control scrolls smoothly by default. Set the behavior prop to "instant" or "auto" to change that. On <BlossomDots> it applies to every dot; a <BlossomDot> can override it for itself.
<BlossomPrev for="my-carousel" behavior="instant" />
<BlossomDots for="my-carousel" behavior="instant" />
<BlossomNext for="my-carousel" behavior="instant" />
The prop is rendered as a data-blossom-behavior attribute on the button. Setting that attribute yourself takes precedence over the prop.
Listening for commands
Listen for command events on the carousel to know when any navigation control is triggered or a method is called:
- previous (
--blossom-prev) - next (
--blossom-next) - dot (
--blossom-goto-{index}).
These events are not fired by drag or free scrolling. Read event.command (or event.detail.command where the Invoker Commands polyfill applies).
<BlossomCarousel @command="handleCommand">
<div v-for="i in 12" :key="i" data-blossom-slide>Slide {{ i }}</div>
</BlossomCarousel>
<script setup lang="ts">
const handleCommand = (event: CustomEvent) => {
const command = event?.command || event?.detail?.command;
};
</script>
Global registration
Register the components alongside BlossomCarousel:
import {
BlossomCarousel,
BlossomPrev,
BlossomNext,
BlossomDots,
BlossomDot,
useNavigation,
} from "@blossom-carousel/vue";
import "@blossom-carousel/vue/style.css";
const app = createApp({});
app.component("BlossomCarousel", BlossomCarousel);
app.component("BlossomPrev", BlossomPrev);
app.component("BlossomNext", BlossomNext);
app.component("BlossomDots", BlossomDots);
app.component("BlossomDot", BlossomDot);
Methods
Get a template ref to <BlossomCarousel> to navigate from your own code:
prev(options?)scrolls to the previous snap point or page.next(options?)scrolls to the next snap point or page.goTo(index, options?)scrolls to the slide at a zero-basedindex, counting slides marked withdata-blossom-slide.elis a ref to the carousel's root element.
options.behavior accepts "smooth" (default), "instant" or "auto". The methods use native scrolling, so they also work on touch devices where the drag engine isn't loaded.
<script setup>
import { useTemplateRef } from "vue";
const carousel = useTemplateRef("carousel");
</script>
<template>
<BlossomCarousel ref="carousel">
<div v-for="i in 12" :key="i" data-blossom-slide>Slide {{ i }}</div>
</BlossomCarousel>
<button @click="carousel.goTo(0, { behavior: 'instant' })">Back to start</button>
</template>
Overscroll API
Tap into Blossom's drag engine's overscroll behavior to create your own style.
<template>
<!-- prevent and overwrite Blossom's default rubberbanding effect -->
<BlossomCarousel @overscroll.prevent="onOverscroll">
<div v-for="i in 12" :key="i">Slide {{ i }}</div>
</BlossomCarousel>
</template>
<script setup>
function onOverscroll(event) {
const overScroll = event.detail.left;
Array.from(blossomCarousel.value.children).forEach((slide) => {
slide.style.transform = `scale(${1 - overScroll * 0.1})`;
});
}
</script>
Examples
Explore ready-to-copy carousel patterns grouped by complexity.
Related Packages
A lightweight carousel library with fluid motion and great swipe precision
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.8.0 | ^3.5.13 | MIT | |
| 1.7.0 | ^3.5.13 | MIT | |
| 1.6.1 | ^3.5.13 | MIT | |
| 1.6.0 | ^3.5.13 | MIT | |
| 1.5.3 | ^3.5.13 | MIT | |
| 1.5.2 | ^3.5.13 | MIT | |
| 1.5.1 | ^3.5.13 | MIT | |
| 1.5.0 | ^3.5.13 | MIT | |
| 1.4.0 | ^3.5.13 | MIT | |
| 1.3.2 | ^3.5.13 | MIT | |
| 1.3.1 | ^3.5.13 | MIT | |
| 1.3.0 | ^3.5.13 | MIT | |
| 1.2.2 | ^3.5.13 | MIT | |
| 1.2.1 | ^3.5.13 | MIT | |
| 1.2.0 | ^3.5.13 | MIT | |
| 1.1.1 | ^3.5.13 | MIT | |
| 1.1.0 | ^3.5.13 | MIT | |
| 1.0.4 | ^3.5.13 | MIT | |
| 1.0.3 | ^3.5.13 | MIT | |
| 1.0.2 | ^3.5.13 | MIT | |
| 1.0.1 | ^3.5.13 | MIT | |
| 1.0.0 | ^3.5.13 | MIT | |
| 0.2.0 | ^3.5.13 | MIT | |
| 0.1.10 | ^3.5.13 | MIT | |
| 0.1.9 | ^3.5.13 | MIT | |
| 0.1.8 | ^3.5.13 | MIT | |
| 0.1.7 | ^3.5.13 | MIT | |
| 0.1.6 | ^3.5.13 | MIT | |
| 0.1.5 | ^3.5.13 | MIT | |
| 0.1.4 | ^3.5.13 | MIT |
Showing the latest 30 of 44. See every release on npm