Carousel
Горизонтальная прокрутка слайдов. Принимает children как массив React-элементов и управляет переключением через стрелки, пагинацию и свайп. Поддерживает infiniteScroll, autoSwipe, несколько элементов в viewport (showItems) и управляемый режим (state).
Когда использовать
- Галереи изображений и медиа.
- Онбординг с несколькими шагами.
- Секции «Похожие товары», «Недавние проекты» — несколько карточек в viewport (
showItems > 1).
Когда не нужен: для табличных данных (используйте @cloud-ru/ds-tabs), для форм (обычная вертикальная прокрутка), для длинных списков (виртуализация).
Анатомия
Controls visibility
Режим отображения стрелок и пагинации: hover — элементы управления проявляются по наведению (чище в галереях), always — видны всегда (рекомендуется для touch и для onboarding).
Установка
pnpm add @cloud-ru/ds-carousel
import { Carousel } from '@cloud-ru/ds-carousel'
Примеры использования
1. Базовая карусель
import { Carousel } from '@cloud-ru/ds-carousel';
export function Basic() {
return (
<div style={{ width: 480 }}>
<Carousel>
<div style={{ height: 180, background: '#4f46e5', color: '#fff', display: 'grid', placeItems: 'center' }}>
Slide 1
</div>
<div style={{ height: 180, background: '#0ea5e9', color: '#fff', display: 'grid', placeItems: 'center' }}>
Slide 2
</div>
</Carousel>
</div>
);
}2. Три элемента в viewport
import { Carousel } from '@cloud-ru/ds-carousel';
export function ThreePerView() {
return (
<div style={{ width: 600 }}>
<Carousel showItems={3} gap='12px'>
{Array.from({ length: 6 }).map((_, i) => (
<div
key={i}
style={{ height: 120, background: '#f3f4f6', display: 'grid', placeItems: 'center', borderRadius: 8 }}
>
Card {i + 1}
</div>
))}
</Carousel>
</div>
);
}3. Бесконечная с автопрокруткой
import { Carousel } from '@cloud-ru/ds-carousel';
export function Infinite() {
return (
<div style={{ width: 480 }}>
<Carousel infiniteScroll autoSwipe={3}>
<div style={{ height: 180, background: '#10b981', color: '#fff', display: 'grid', placeItems: 'center' }}>
Slide 1
</div>
<div style={{ height: 180, background: '#f59e0b', color: '#fff', display: 'grid', placeItems: 'center' }}>
Slide 2
</div>
<div style={{ height: 180, background: '#ec4899', color: '#fff', display: 'grid', placeItems: 'center' }}>
Slide 3
</div>
</Carousel>
</div>
);
}Props
Types
CarouselProps| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
arrows | boolean | true | no | Использовать стрелки для переключения страниц. На mobile по умолчанию скрыты (`CAROUSEL_LAYOUT_PRESETS`), вернуть — через `layoutPresets`. |
autoSwipe | number | — | no | Автоматическое переключение слайдов в секундах |
children | ReactElement<any, string | JSXElementConstructor<any>>[] | — | yes | Массив айтемов |
className | string | — | no | CSS - класснейм |
controlsVisibility | "always" | "hover" | hover | no | Управление видимостью стрелок: 'hover' — по ховеру, 'always' — всегда |
data-test-id | string | — | no | |
gap | string | var(--dimension-2m) | no | Расстояние между айтемами |
infiniteScroll | boolean | false | no | Цикличная прокрутка |
layoutPresets | Partial<Record<LayoutType, Partial<CarouselLayoutDefaults>>> | — | no | Override mobile-дефолтов адаптива для этого инстанса (deep-merge поверх `CAROUSEL_LAYOUT_PRESETS`). Escape-hatch: обычно не нужен — DS-пресет применяется автоматически по `AdaptiveProvider`. |
pagination | boolean | true | no | Использовать пагинацию для переключения страниц |
scrollBy | number | Math.trunc(show) | no | Сдвиг айтемов при смене 1 страницы |
showItems | number | 1 | no | Кол-во отображаемых единовременно айтемов |
state | { page: number; onChange(page: number): void; } | — | no | Управление состоянием извне |
swipe | boolean | true | no | Переключение страниц свайпом |
swipeActivateLength | number | 48 | no | Минимальная длина в px для активации свайпа |
transition | number | 0.4 | no | Время переключения 1 страницы (в s) |
Unions
Types
CarouselProps
CarouselLayoutDefaults
Unions
ControlsVisibility
Related props
LayoutPresets
Адаптивность
Carousel — адаптивный компонент класса preset-defaults: DOM один, по раскладке меняются только дефолты пропсов. Раскладку компонент читает из контекста @cloud-ru/ds-adaptive — отдельного пропа layoutType нет.
На mobile стрелки скрыты: страницы листаются свайпом и пагинацией.
| Проп | desktop | mobile |
|---|---|---|
arrows | true | false |
Источник mobile-дефолтов — экспортируемая константа CAROUSEL_LAYOUT_PRESETS.
Как переопределить
Приоритет (от высшего к низшему): layoutPresets[layout] (инстанс) → DS-пресет CAROUSEL_LAYOUT_PRESETS → явный проп (= desktop-значение) → базовый дефолт.
import { Carousel } from '@cloud-ru/ds-carousel'
// Явный проп задаёт desktop-значение, на mobile стрелки по-прежнему скрыты
<Carousel arrows={false}>{items}</Carousel>
// Вернуть стрелки на mobile
<Carousel layoutPresets={{ mobile: { arrows: true } }}>{items}</Carousel>