useCarousel
Hook that manages carousel scroll snapping, swipe gestures, and page-based navigation.
Usage#
import { useCarousel } from '@primereact/headless/carousel';
const carousel = useCarousel({ align: 'center' });
return (
<div {...carousel.rootProps}>
<div ref={carousel.contentRef} {...carousel.contentProps}>
<div {...carousel.getItemProps(0)}></div>
</div>
<div {...carousel.indicatorsProps}>
<button {...carousel.getIndicatorProps(0)}></button>
</div>
<button {...carousel.getPrevProps(carousel.state.isPrevDisabled)}></button>
<button {...carousel.getNextProps(carousel.state.isNextDisabled)}></button>
</div>
);useCarousel manages scroll snapping, swipe gestures, and page tracking for a content slider — see Primitive for a component-based API.
Features#
- Returns spread-ready prop objects (
rootProps,contentProps,getItemProps,getNextProps,getPrevProps,indicatorsProps,getIndicatorProps) - CSS scroll-snap based navigation with configurable snap type
- Mouse swipe gestures via PointerEvent with automatic snap-to-closest
- IntersectionObserver-driven
data-inviewattribute on items - Imperative methods:
next(),prev(),scrollToPage(),scrollToSlide() - Exposes
state.page,state.swiping,state.isPrevDisabled,state.isNextDisabled,state.snapPoints
Behavior#
Default Page#
Set defaultPage to start on a specific page index.
const carousel = useCarousel({ defaultPage: 2 });Controlled Page#
Use page and onPageChange for full programmatic control over the current page.
const [page, setPage] = React.useState(0);
const carousel = useCarousel({
page,
onPageChange: (e) => setPage(e.value)
});Controlled Slide#
Use slide and onSlideChange to control by item index rather than page index. This is useful for gallery-style carousels where each item maps 1:1 to a page.
const [slide, setSlide] = React.useState(0);
const carousel = useCarousel({
slide,
onSlideChange: (e) => setSlide(e.value)
});Alignment#
Set align to 'start', 'center', or 'end' to control how items snap within the viewport.
const carousel = useCarousel({ align: 'start' });Slides Per Page#
Set slidesPerPage to control the number of visible items. Fractional values like 1.5 show partial items to hint at more content.
const carousel = useCarousel({ slidesPerPage: 1.5, align: 'start' });Orientation#
Set orientation to 'vertical' for a vertical carousel.
const carousel = useCarousel({ orientation: 'vertical' });Loop#
Set loop to enable infinite navigation. Navigation buttons are never disabled in loop mode.
const carousel = useCarousel({ loop: true });Variable Size#
Set autoSize to allow items with different widths. Items use their natural size instead of calculating from slidesPerPage.
const carousel = useCarousel({ autoSize: true });Spacing#
Set spacing to define the gap between items in pixels.
const carousel = useCarousel({ spacing: 24 });Using state.page and state.swiping#
The hook exposes reactive state for custom UI logic.
const carousel = useCarousel();
<span>Page {carousel.state.page + 1}</span>;
{
carousel.state.swiping && <span>Swiping...</span>;
}CSS Custom Properties#
contentProps.style sets three CSS custom properties on the content element. These can be consumed in item sizing and layout calculations.
| Variable | Description |
|---|---|
--slides-per-page | Number of visible slides per page, derived from slidesPerPage. |
--spacing-items | Gap between items in pixels, derived from spacing. |
--scroll-snap-type | Resolved scroll-snap-type value (e.g. x mandatory). |
[data-scope='carousel'][data-part='item'] {
flex-basis: calc(100% / var(--slides-per-page) - var(--spacing-items) * (var(--slides-per-page) - 1) / var(--slides-per-page));
}Custom Styling with Data Attributes#
Prop objects include orientation and state-dependent data attributes.
[data-scope='carousel'][data-part='content'][data-orientation='horizontal'] {
overflow-x: scroll;
}
[data-scope='carousel'][data-part='content'][data-orientation='vertical'] {
flex-direction: column;
overflow-y: scroll;
}
[data-scope='carousel'][data-part='item'][data-inview] {
opacity: 1;
}
[data-scope='carousel'][data-part='indicator'][data-active] {
background: var(--primary);
}API#
useCarousel#
| Name | Type | Default |
|---|---|---|
autoSize | boolean | false |
| Whether the carousel should auto size. | ||
orientation | "horizontal" | "vertical" | 'horizontal' |
| Orientation of the carousel. | ||
align | "center" | "start" | "end" | 'center' |
| Alignment of the carousel items. | ||
loop | boolean | false |
| Whether the carousel should loop. | ||
snapType | "mandatory" | "proximity" | 'mandatory' |
| Scroll snap type applied to the track. | ||
spacing | number | 16 |
| Spacing between carousel items. | ||
slidesPerPage | number | 1 |
| How many slides are visible per page. Supports fractions (e.g. 1.5). | ||
page | number | undefined |
| Index of the active slide. | ||
slide | number | undefined |
| Index of the active slide. | ||
defaultPage | number | 0 |
| Default index of the active slide. | ||
onPageChange | (event: useCarouselChangeEvent) => void | — |
| Callback fired when the carousel's page changes. | ||
onSlideChange | (event: useCarouselChangeEvent) => void | — |
| Callback fired when the active slide (by value) changes. | ||
Accessibility#
See Carousel Primitive for WAI-ARIA compliance details and keyboard support.