React and Next.js
Install
pnpm add @blossom-carousel/react
bun add @blossom-carousel/react
yarn add @blossom-carousel/react
npm install @blossom-carousel/react
React usage
import { BlossomCarousel } from "@blossom-carousel/react";
import "@blossom-carousel/react/style.css";
export function App() {
return (
<BlossomCarousel>
{Array.from({ length: 12 }, (_, index) => (
<div key={index}>Slide {index + 1}</div>
))}
</BlossomCarousel>
);
}
Next.js setup
Import the stylesheet from a global entry point.
import "@blossom-carousel/react/style.css";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Then render the carousel from a component.
import { BlossomCarousel } from "@blossom-carousel/react";
export function FeaturedCarousel() {
return (
<BlossomCarousel>
{Array.from({ length: 12 }, (_, index) => (
<div key={index}>Slide {index + 1}</div>
))}
</BlossomCarousel>
);
}
Semantic root element
Use as="ul" for list-like carousels.
<BlossomCarousel as="ul">
{Array.from({ length: 12 }, (_, index) => (
<li key={index}>Slide {index + 1}</li>
))}
</BlossomCarousel>;
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">
{Array.from({ length: 12 }, (_, index) => (
<div key={index} data-blossom-slide>
Slide {index + 1}
</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 the carousel proportionally.
Slot your own content to replace the default button icon.
<BlossomPrev for="my-carousel">
<span>Previous</span>
</BlossomPrev>;
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">
{({ index, active }) => (
<BlossomDot
className="my-dot"
data-active={active}
aria-label={`Photo ${index + 1}`}
>
{index + 1}
</BlossomDot>
)}
</BlossomDots>;
Listening for commands
Listen for command events on the carousel to know when any navigation control is triggered:
- 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 onCommand={handleCommand}>
{Array.from({ length: 12 }, (_, index) => (
<div key={index} data-blossom-slide>
Slide {index + 1}
</div>
))}
</BlossomCarousel>;
function handleCommand(event: CustomEvent) {
const command = event?.command || event?.detail?.command;
}
See the Buttons and Dots examples for live demos.
Overscroll API
Tap into Blossom's drag engine's overscroll behavior to create your own style.
import { useRef } from "react";
import { BlossomCarousel } from "@blossom-carousel/react";
export function App() {
const blossomCarousel = useRef<HTMLElement | null>(null);
function onOverscroll(event: CustomEvent<{ left: number }>) {
// prevent and overwrite Blossom's default rubberbanding effect
event.preventDefault();
const overScroll = event.detail.left;
Array.from(blossomCarousel.current?.children ?? []).forEach((slide) => {
(slide as HTMLElement).style.transform = `scale(${1 - overScroll * 0.1})`;
});
}
return (
<BlossomCarousel
ref={blossomCarousel}
onOverscroll={(event) => {
onOverscroll(event as CustomEvent<{ left: number }>);
}}
>
{Array.from({ length: 12 }, (_, index) => (
<div key={index}>Slide {index + 1}</div>
))}
</BlossomCarousel>
);
}