Carousel
Набор компонентов для создания списков с прокруткой (галерей).
Состав
При сборке карусели используйте структуру, в которой корневым элементом
является Carousel
со вложенными в него CarouselItem
или CarouselCol
.
При необходимости отображения элементов карусели в сетке, оборачивайте карусель в CarouselGridWrapper
.
Carousel
CarouselGridWrapper
CarouselItem
CarouselCol
Использование
CSS Scroll Snap
- В компоненте
Carousel
укажите свойствоscrollSnapType
:
import React from 'react';
import { Carousel } from '@salutejs/plasma-web';
export const MyGallery = () = (
<Carousel scrollSnapType="mandatory">
// Элементы карусели помещаются здесь
</Carousel>
);
- Также укажите свойство
scrollSnapAlign
для элемента карусели:
import React from 'react';
import { CarouselItem } from '@salutejs/plasma-web';
export const MyGalleryItem = ({ children }) => (
<CarouselItem scrollSnapAlign="center">{children}</CarouselItem>
);
Определение центрального элемента
Карусель может определять активный элемент при прокрутке.
Для этого укажите свойства detectActive
, detectThreshold
и обработчик onIndexChange
:
import React from 'react';
import { Carousel } from '@salutejs/plasma-web';
export const MyGallery = () = (
<Carousel detectActive detectThreshold={0.5} onIndexChange={(index) => console.log(index)}>
// Элементы карусели помещаются здесь
</Carousel>
);
Стилизация центрального элемента
Элементы видимой части (viewport
) можно стилизовать, например, увеличивать или менять *прозрачность.
В момент прокрутки карусели (с помощью колесика мыши, стрелок пульта или касанием)
с определенной периодичностью вызывается обработчик скролла,
который на основании положения элемента относительно viewport
(внутренние границы карусели) вызывает тот или иной коллбек:
Название | Описание | Аргументы | Возвращаемое значение |
---|---|---|---|
scaleCallback | Обработчик для элементов внутри viewport . Коллбек вызывается для видимого элемента, к нему применяется необходимая стилизация. | itemEl: HTMLElement , slot: number | void |
scaleResetCallback | Обработчик для элементов вне viewport . Элемент невидим, стилизация сбрасывается. | itemEl: HTMLElement | void |
Для обозначения позиции элемента внутри viewport
, карусель использует значение slot
:
0
равен центральному элементу;-1
и1
первый слева и справа от центрального;-2
и2
и т.д., соответственно, для второго и далее.
import React from 'react';
import { Carousel } from '@salutejs/plasma-web';
/**
* Функция увеличения центрального элемента.
* Предположим, что у нас 5 элементов во `viewport`.
* Тогда ряд slots будет таким: -2 -1 0 1 2.
* Центральный элемент примет opacity = 1, боковые - opacity = 0.5, а крайние слева и справа - opacity = 0
*/
const scaleCallback = (itemEl: HTMLElement, slot: number) => {
itemEl.style.opacity = `${1 - Math.abs(slot) / 2}`;
};
/**
* Функция сброса стилей элементов вне `viewport`.
*/
const scaleResetCallback = (itemEl: HTMLElement) => {
itemEl.style.opacity = '';
};
export const MyGallery = () = (
<Carousel scaleCallback={stylingCallback} scaleResetCallback={stylingResetCallback}>
// Элементы карусели помещаются здесь
</Carousel>
);
- В данном примере используются
Grid
иCSS Scroll Snap
. - В качестве основного блока разметки контейнер (Container), а колонки (Col) помещаются в строки (Row).
- Карусель поддерживает определение (
detectActive
) активного элемента.
Доступность
Для достижения доступности карусели необходимо выполнить слежующие условия:
- в элемент карусели добавьте атрибут
aria-label
, со значением, обозначающим текущую позицию в списке; - разместите кнопки "назад" и "вперед" для навигации по карусели;
- укажите корректный атрибут
id
для секции карусели.
<section id="carousel-example">
<Button text="Prev" aria-controls="carousel-example" />
<Button text="Next" aria-controls="carousel-example" />
<Carousel>
{items.map((item, i) => <CarouselItem aria-label={`${i + 1} из ${items.length}`} />)}
</Carousel>
</section>