# Carousel

Component of the SBB design system Lyne.

- Package: `@sbb-esta/lyne-elements` (Angular: `@sbb-esta/lyne-angular`)
- Structure: main element with parts; use parts only within the element they belong to
- Categories: Container
- Status: Design guidelines complete

## Links

- Page on digital.sbb.ch: https://digital.sbb.ch/en/design-system/lyne/components/carousel/
- Storybook: https://lyne-elements.app.sbb.ch/?path=/docs/elements-carousel--docs
- Angular (`@sbb-esta/lyne-angular`): https://lyne-angular.app.sbb.ch/angular/components/carousel/overview (API: https://lyne-angular.app.sbb.ch/angular/components/carousel/api)
- Figma: https://www.figma.com/design/mWknI2rC5DJmOgRO61WKai/Lyne-Components?node-id=7491-19
- GitHub: https://github.com/sbb-design-systems/lyne-components/tree/v5.12.0/src/elements/carousel

## Elements

- `sbb-carousel`: It displays a carousel component.
  - `sbb-carousel-item`, only within `sbb-carousel`: It displays an item contained into the `sbb-carousel` component.
  - `sbb-carousel-list`, only within `sbb-carousel`: It displays a list of `sbb-carousel-item` components.

## Overview

### What does the component do?
A carousel shows several pieces of content, for example images, one after another within a limited area. Users scroll horizontally through the slides by swiping, using the [paginator](https://digital.sbb.ch/en/design-system/lyne/components/paginator/) or the arrow keys.

### When should the component be used?
* When several similar pieces of content are to be displayed, but there is not enough space for all of them at once.
* When the focus is on a visual or content sequence (e.g. highlights, campaigns, products).

### Rules.
* A carousel has no more than 7 slides.
* Each slide has a clear focus.
* All slides are the same size.
* Carousels do not change automatically, only through user action.
* Images need alternative text. If an image is linked, it is placed inside the link.

## Implementation (web components)

The `<sbb-carousel>` is a slideshow component that can be used to display a
series of items, as images, once at a time, allowing users to cycle
through them via horizontal scrolling or using controls (e.g. a paginator).

The component must be used together with a
[sbb-compact-paginator](https://lyne-elements.app.sbb.ch/?path=/docs/elements-paginator--docs)
and a `<sbb-carousel-list>`, which accepts one or more `<sbb-carousel-item>`.

```html
<sbb-carousel>
  <sbb-carousel-list>
    <sbb-carousel-item>
      <img src="../img-1.jpg" alt="Image 1" height="300" width="400" />
    </sbb-carousel-item>
    <sbb-carousel-item>
      <sbb-image
        image-src="../image.jpg"
        alt="SBB image"
        style="width: 800px; height: 600px;"
      ></sbb-image>
    </sbb-carousel-item>
    <sbb-carousel-item>
      <div class="sbb-image">
        <img src="../image.jpg" alt="SBB image" height="300" width="400" />
        <figcaption>Caption for picture</figcaption>
      </div>
    </sbb-carousel-item>
  </sbb-carousel-list>
  <sbb-compact-paginator></sbb-compact-paginator>
</sbb-carousel>
```

The `length` and the `pageSize` properties of the `<sbb-compact-paginator>`
are automatically set based on the number of slotted images.

The values of the `accessibilityPageLabel`, `accessibilityPreviousPageLabel` and `accessibilityNextPageLabel` properties
are also set, in order to automatically override the 'page' keyword to the 'slide' one.
If needed, consumers can provide their own values.

The `<sbb-carousel-item>` supports native `img` tags, `<sbb-image>`, `picture`
and also custom content, appropriately formatted.
Since it doesn't have a fixed size, it's important for consumers to define
the dimensions of slotted images to correctly render the component.

### Interactions

It's possible to switch between items using the paginator controls, or, if the component is focused, using the arrow keys.

| Keyboard                            | Action                         |
| ----------------------------------- | ------------------------------ |
| <kbd>Down Arrow / Right Arrow</kbd> | Navigate to the next item.     |
| <kbd>Up Arrow / Left Arrow</kbd>    | Navigate to the previous item. |

### Events

The `<sbb-carousel-item>` component provides the two events `beforeshow`
and `show`; their dispatch is related to scroll events in the
`<sbb-carousel-list>`.
The `beforeshow` is dispatched when an item is being scrolled into view
and the `show` is dispatched when the item is fully visible.

### Style

The carousel determines its dimensions by reading the dimensions from the first slotted `<sbb-carousel-item>` element.
It is the consumers' responsibility to set the correct height and width of the items, and to ensure that they are all the same size.

These dimensions are read only once, when the component is first connected to the DOM or first becomes visible.
In special cases, such as when the carousel size needs to be responsive, it is recommended to manually
set the width and height CSS properties on the `<sbb-carousel-list>` element.
Manually set dimensions will take precedence over the automatically read dimensions.

### Accessibility

Following the [ARIA carousel pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/),
the `<sbb-carousel>` component has `role="region"` and `aria-label="carousel"` and the `<sbb-carousel-list>` component has `aria-atomic='true'` and `aria-live='polite'`.
If no `aria-label` is provided on the slotted `<sbb-carousel-item>`
instances, the component sets a default value on them..

To not break the accessibility when links are used together with images, please place the image within the anchor tag.

```html
<sbb-carousel>
  <sbb-carousel-list>
    <sbb-carousel-item>
      <a href="#" target="_blank">
        <img src="../img-1.jpg" alt="SBB image" height="300" width="400" />
      </a>
    </sbb-carousel-item>
    ...
</sbb-carousel>
```

## API (web components)

Full API tables (attributes, events, slots, CSS properties): https://digital.sbb.ch/en/design-system/lyne/components/carousel/api.md
