# Tag

Komponente des SBB Design Systems Lyne.

- Paket: `@sbb-esta/lyne-elements` (Angular: `@sbb-esta/lyne-angular`)
- Aufbau: ein Element mit optionaler Gruppierung
- Kategorien: Container
- Status: Gestaltungsrichtlinien vollständig

## Links

- Seite auf digital.sbb.ch: https://digital.sbb.ch/de/design-system/lyne/components/tag/
- Storybook: https://lyne-elements.app.sbb.ch/?path=/docs/elements-tag--docs
- Angular (`@sbb-esta/lyne-angular`): https://lyne-angular.app.sbb.ch/angular/components/tag/overview (API: https://lyne-angular.app.sbb.ch/angular/components/tag/api)
- GitHub: https://github.com/sbb-design-systems/lyne-components

## Elemente

- `sbb-tag`, mehrere lassen sich zusammenfassen mit `sbb-tag-group`: It displays a selectable element which can be used as a filter.

## Verwandte Komponenten

- Ähnlich: [Tabs](https://digital.sbb.ch/de/design-system/lyne/components/tabs/index.md)

## Übersicht

### Was macht die Komponente?
Ein Tag ist ein kleines Beschriftungselement, das zur Kategorisierung und als Filter dient.

### Wann soll die Komponente eingesetzt werden?
* Um Inhalte nach bestimmten Kriterien zu filtern und zu kategorisieren.
* Um Nutzenden die Möglichkeit zu geben, Inhalte nach definierten Eigenschaften zu durchsuchen.
* Um die Benutzeroberfläche übersichtlicher zu gestalten.

### Regeln.
* Tags sollen kurz und eindeutig beschriftet sein.
* Verwende eine logische und intuitive Reihenfolge der Tags, um die Benutzerfreundlichkeit zu maximieren.
* Vermeide zu viele Tags auf einmal, um die Übersichtlichkeit zu gewährleisten.

## Implementation (Web Components, Englisch)

Tags categorize large amounts of information and filter content through user selection.

The `<sbb-tag-group>` is a container for one or more `<sbb-tag>` components.
Each `<sbb-tag>` must have a `value` property.

```html
<sbb-tag-group>
  <sbb-tag value="all">All</sbb-tag>
  <sbb-tag value="phones" amount="23">Phones</sbb-tag>
  <sbb-tag value="computer" amount="3">Computer</sbb-tag>
  <sbb-tag value="laptop" amount="99">Laptop</sbb-tag>
</sbb-tag-group>
```

### Style

The `size` property on `<sbb-tag-group>` (values: `s`, `m`) is applied to all contained `<sbb-tag>` elements.

```html
<sbb-tag-group size="m">
  <sbb-tag value="all">All</sbb-tag>
  <sbb-tag value="phones">Phones</sbb-tag>
  <sbb-tag value="computer">Computer</sbb-tag>
</sbb-tag-group>

<sbb-tag-group size="s">
  <sbb-tag value="all">All</sbb-tag>
  <sbb-tag value="phones">Phones</sbb-tag>
  <sbb-tag value="computer">Computer</sbb-tag>
</sbb-tag-group>
```

### Interactions

#### Exclusive selection vs. multiple selection

By default, `<sbb-tag-group>` behaves like a radio button group: only one tag can be selected at a time.
The `value` of the `<sbb-tag-group>` reflects the `value` of the selected `<sbb-tag>`.

Set the `multiple` property to allow multiple selections (checkbox behavior).
In this mode, the `value` is an array containing all selected tag values.

```html
<sbb-tag-group multiple>
  <sbb-tag value="all">All</sbb-tag>
  <sbb-tag value="phones" checked>Phones</sbb-tag>
  <sbb-tag value="computer" checked>Computer</sbb-tag>
  <sbb-tag value="laptop">Laptop</sbb-tag>
</sbb-tag-group>
```

**Note:** Changing the `multiple` property at runtime is not supported. Set this property during initialization.

#### Advanced usage: multiple and exclusive mixed

```ts
const uncheckAllTag = () => {
  document.getElementById('all').removeAttribute('checked');
};

const uncheckTags = () => {
  Array.from(document.querySelectorAll('sbb-tag'))
    .filter((e) => e.getAttribute('id') !== 'all' && !e.getAttribute('disabled'))
    .forEach((e) => e.removeAttribute('checked'));
};
```

```html
<sbb-tag-group aria-label="Select your desired device to filter it" multiple>
  <sbb-tag id="all" onchange="uncheckTags()" value="All" checked> All </sbb-tag>
  <sbb-tag value="phones" onchange="uncheckAllTag()">Phones</sbb-tag>
  <sbb-tag value="computer" onchange="uncheckAllTag()">Computer</sbb-tag>
  <sbb-tag value="laptop" onchange="uncheckAllTag()">Laptop</sbb-tag>
</sbb-tag-group>
```

### States

Tags support `checked` and `disabled` states. Set `disabled` on the `<sbb-tag-group>` to disable all contained tags.

### Slots

It is possible to provide a label via an unnamed slot; the component can optionally display a `<sbb-icon>`
at the component start using the `iconName` property or via custom content using the `icon` slot.

It's also possible to display a numeric amount at the component's end using the `amount` property or slot.

```html
<sbb-tag value="All" icon-name="pie-small" amount="123"> All </sbb-tag>

<sbb-tag value="None">
  <sbb-icon slot="icon" name="pie-small"></sbb-icon>
  None
  <span slot="amount">123</span>
</sbb-tag>
```

### Complex Values

The `<sbb-tag>` element supports any types of values, including complex objects.
The type can be specified using the generic type parameter `T` of `SbbTag<T>`.

```html
<sbb-tag .value=${{value: 'value', name: 'name'}} name="name">Option</sbb-tag>
```

### Events

Consumers can listen to the native `change` and `input` events on the `<sbb-tag>`.
The current state can be read from `event.target.checked`, while the value from `event.target.value`.
It's recommended to check the parent's `<sbb-tag-group>` for the value.

### Accessibility

#### Exclusive mode (default)

In exclusive (non-multiple) mode, `<sbb-tag-group>` behaves like a radio group (`role="radiogroup"`).
Each `<sbb-tag>` acts as a radio button and the state is reflected via `aria-checked`.

Keyboard navigation follows the roving tabindex pattern:

- Only the currently selected tag (or the first tag if none is selected) receives `tabindex="0"`;
  all other tags receive `tabindex="-1"`.
- **Arrow keys** (Left/Right/Up/Down) move focus and selection to the adjacent tag, wrapping around
  at the ends. Disabled tags are skipped automatically.
- **Tab** moves focus into and out of the group without changing the selection.

```html
<sbb-tag-group accessibility-label="Select your desired device to filter it">
  <sbb-tag value="all" checked>All</sbb-tag>
  <sbb-tag value="phones">Phones</sbb-tag>
  <sbb-tag value="computer">Computer</sbb-tag>
  <sbb-tag value="laptop">Laptop</sbb-tag>
</sbb-tag-group>
```

#### Multiple mode

In multiple mode, each `<sbb-tag>` behaves like a toggle button. The state is reflected via `aria-pressed`.

The `<sbb-tag-group>` applies `role="group"` (when no `accessibilityLabel` is set) to convey
the association between the individual tags. Each group should be given a label via `accessibilityLabel`
that communicates the collective meaning of all tags.

The `accessibilityLabel` property on `<sbb-tag-group>` is forwarded as `aria-label` to the
inner list element. When provided, the implicit `role="group"` is omitted in favor of the
labeled list.

```html
<sbb-tag-group multiple accessibility-label="Select your desired font styles to filter it">
  <sbb-tag value="bold" checked>Bold</sbb-tag>
  <sbb-tag value="italic">Italic</sbb-tag>
  <sbb-tag value="underline">Underline</sbb-tag>
</sbb-tag-group>
```

## API (Web Components, Englisch)

Vollständige API-Tabellen (Attribute, Events, Slots, CSS-Eigenschaften): https://digital.sbb.ch/de/design-system/lyne/components/tag/api.md
