Carousel
The Carousel component displays a series of content in a horizontal scrollable view with optional navigation dots and controls.
Source
LLM docs
Package
npm install @plocks/carouselExamples
6
Properties
60
Playground
Basics
Enable
autoPlay and loop on Carousel to rotate a small set of slides without custom pagination controls.Loading demo…
import { Block, Text } from '@plocks/ui';
import { Carousel } from '@plocks/carousel';
const slides = ['#4C1D95', '#155E75', '#166534'];
export function Demo() {
return (
<Carousel h={200} loop autoPlay autoPlayInterval={4500} showDots>
{slides.map((bg, index) => (
<Block key={bg} bg={bg} radius="lg" h="full" align="center" justify="center">
<Text variant="h3" c="white">
Slide {index + 1}
</Text>
</Block>
))}
</Carousel>
);
}Vertical orientation
Set
orientation="vertical" to rotate content along the Y-axis while keeping arrow and dot controls aligned for keyboard and touch users. Vertical carousels size to their container, so give the carousel an explicit h.Loading demo…
import { Block, Text } from '@plocks/ui';
import { Carousel } from '@plocks/carousel';
const slides = ['#DC2626', '#2563EB', '#0F766E'];
export function Demo() {
return (
<Carousel
orientation="vertical"
h={280}
loop
autoPlay
autoPlayInterval={4500}
showArrows
showDots
>
{slides.map((bg, index) => (
<Block key={bg} bg={bg} radius="lg" h="full" align="center" justify="center">
<Text variant="h3" c="white">
Slide {index + 1}
</Text>
</Block>
))}
</Carousel>
);
}Image overlay
Layer an absolutely positioned
Block with a semi-transparent bg on top of each slide to keep text and buttons readable on photography.Loading demo…
import { Block, Image, Text } from '@plocks/ui';
import { Carousel } from '@plocks/carousel';
const scenes = [
{ title: 'Mountain escape', src: require('../../../../assets/images/scene-mountains.png') },
{ title: 'Forest retreat', src: require('../../../../assets/images/scene-forest.png') },
{ title: 'Desert journey', src: require('../../../../assets/images/scene-desert.png') },
];
export function Demo() {
return (
<Carousel h={280} loop showArrows showDots>
{scenes.map(({ title, src }) => (
<Block key={title} h="full" radius="lg" style={{ overflow: 'hidden' }}>
<Image src={src} w="100%" h="100%" resizeMode="cover" />
<Block
position="absolute"
top={0}
right={0}
bottom={0}
left={0}
bg="rgba(15,23,42,0.45)"
p="lg"
justify="flex-end"
>
<Text variant="h3" c="white">
{title}
</Text>
</Block>
</Block>
))}
</Carousel>
);
}Multiple slides
Combine
itemsPerPage with the Embla-style breakpoints prop to show more slides as the viewport grows. Keep slidesToScroll={1} so only one card advances at a time, even when desktop layouts show multiple slides side-by-side.Loading demo…
import { Block, Text } from '@plocks/ui';
import { Carousel } from '@plocks/carousel';
const slides = ['#1D4ED8', '#0F766E', '#C026D3', '#B45309', '#7C3AED'];
export function Demo() {
return (
<Carousel
h={180}
loop
showDots
slideGap={12}
itemsPerPage={1}
slidesToScroll={1}
breakpoints={{
'@media (min-width: 768px)': { itemsPerPage: 2 },
'@media (min-width: 1200px)': { itemsPerPage: 4 },
}}
>
{slides.map((bg, index) => (
<Block key={bg} bg={bg} radius="lg" h="full" align="center" justify="center">
<Text variant="h4" c="white">
Slide {index + 1}
</Text>
</Block>
))}
</Carousel>
);
}Performance tuning
Pair
windowSize with reducedMotion to keep large or data-heavy carousels responsive while still exposing arrow navigation.Loading demo…
import { Block, Text } from '@plocks/ui';
import { Carousel } from '@plocks/carousel';
const slides = ['#1E3A8A', '#047857', '#9333EA', '#B91C1C', '#B45309', '#0F766E'];
export function Demo() {
return (
<Carousel h={180} loop showArrows windowSize={3} reducedMotion slideGap={12}>
{slides.map((bg, index) => (
<Block key={bg} bg={bg} radius="lg" h="full" align="center" justify="center">
<Text variant="h4" c="white">
Slide {index + 1}
</Text>
</Block>
))}
</Carousel>
);
}Drag & motion
Tune the interaction model with
dragFree, skipSnaps, dragThreshold, and duration to match Embla-style motion control.Loading demo…
import { Block, Text } from '@plocks/ui';
import { Carousel } from '@plocks/carousel';
function slides(colors: string[]) {
return colors.map((bg, index) => (
<Block key={bg} bg={bg} radius="lg" h="full" align="center" justify="center">
<Text variant="h4" c="white">
Slide {index + 1}
</Text>
</Block>
));
}
export function Demo() {
return (
<Block fullWidth gap="lg">
<Text variant="h5">Free momentum (dragFree)</Text>
<Carousel h={160} dragFree itemsPerPage={2} slideGap={12}>
{slides(['#0EA5E9', '#6366F1', '#8B5CF6', '#A855F7'])}
</Carousel>
<Text variant="h5">Locked snaps (skipSnaps off)</Text>
<Carousel
h={160}
itemsPerPage={2}
slidesToScroll={1}
skipSnaps={false}
dragThreshold={45}
duration={650}
slideGap={12}
>
{slides(['#F97316', '#EA580C', '#C2410C', '#9A3412'])}
</Carousel>
</Block>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources