# Icon

Komponente des SBB Design Systems Lyne.

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

## Links

- Seite auf digital.sbb.ch: https://digital.sbb.ch/de/design-system/lyne/components/icon/
- Storybook: https://lyne-elements.app.sbb.ch/?path=/docs/elements-icon--docs
- Angular (`@sbb-esta/lyne-angular`): https://lyne-angular.app.sbb.ch/angular/components/icon/overview (API: https://lyne-angular.app.sbb.ch/angular/components/icon/api)
- Figma: https://www.figma.com/design/mWknI2rC5DJmOgRO61WKai/Lyne-Components?node-id=31076-318118
- GitHub: https://github.com/sbb-design-systems/lyne-components/tree/v5.12.0/src/elements/icon

## Elemente

- `sbb-icon`: Displays an icon loaded from a registered namespace.

## Übersicht

### Was macht die Komponente?
Ein Icon ist ein grafisches Symbol. Es stellt Funktionen, Inhalte oder Aktionen visuell dar.

### Wann soll die Komponente eingesetzt werden?
* Um Funktionen oder Aktionen visuell zu unterstützen und hervorzuheben.
* Um Platz zu sparen.
* Um Informationen oder Status schnell erkennbar zu machen.
* Um die Navigation zu unterstützen.

### Regeln.
* Icons gibt es in 3 Grössen (24 x 24, 36 x 36 und 48 x 48 Pixel). Andere Grössen sind nicht erlaubt.
* Icons haben eine Strichstärke von 1 Pixel. Ausnahmen sind nur im Header erlaubt.
* Die Grösse des Icons passt zur umgebenden Schrift und zu anderen Elementen.
* Icons werden sparsam und nur dort eingesetzt, wo sie die Nutzung verbessern.
* Ein Icon allein ist für Screenreader nicht verständlich und ist standardmässig ausgeblendet. Dekorative Icons bleiben ausgeblendet. Trägt ein Icon eine Information oder ist es interaktiv, braucht es eine Textalternative (z. B. `aria-label` am umgebenden Element) oder einen [Tooltip](https://digital.sbb.ch/de/design-system/lyne/components/tooltip/).

## Implementation (Web Components, Englisch)

The `<sbb-icon>` component provides a solid way of rendering registered and named icons.

The component will dynamically load an SVG for each icon, avoiding multiple requests to the same icon.
The icon components are not tied to specific icon sets; you can register custom namespaces
and then provide the `<sbb-icon>` with the `name` property in the format `name="icon-name"` or `name="namespace:icon-name"`.

Note that if you do not provide a namespace, the default namespace will be used pointing to the `SBB Icons CDN`.

```html
<!-- Will use the default namespace -->
<sbb-icon name="app-icon-medium"></sbb-icon>
```

** Register custom icon namespace **

```ts
import { mergeConfig } from '@sbb-esta/lyne-elements/core.js';

mergeConfig({
  icon: {
    namespaces: new Map<string, string>().set('your-namespace', 'https://domain-of-your-icons/'),
  },
});
```

** Register custom interceptor **

```ts
import { mergeConfig } from '@sbb-esta/lyne-elements/core.js';

mergeConfig({
  icon: {
    interceptor: ({ namespace, name, request }) => {
      if (namespace === 'your-namespace') {
        // Do your own logic
        return Promise.resolve(`<svg-fake data-name="${name}"></svg-fake>`);
      }
      return request();
    },
  },
});
```

Custom namespaces and interceptors must be registered globally before the first request is made.

If using the default SBB CDN, ensure that the icon name has the size suffix.
E.g. if in the Design (Figma) the icon is called 'circle-plus', the icon name will be either 'circle-plus-small' or 'circle-plus-medium'.

### Accessibility

Similar to an `<img>` element, an icon alone does not convey any useful information for a screen-reader user.
The user of `<sbb-icon>` must provide additional information pertaining to how the icon is used.
Based on the use-cases described below, `<sbb-icon>` is marked as `aria-hidden="true"` by default,
but this can be overridden by adding `aria-hidden="false"` to the element.

In thinking about accessibility, it is useful to place icon use into one of three categories:

1. **Decorative**: the icon conveys no real semantic meaning and is purely cosmetic.
2. **Interactive**: a user will click or otherwise interact with the icon to perform some action.
3. **Indicator**: the icon is not interactive, but it conveys some information, such as a status.
   This includes using the icon in place of a text inside a larger message.

## API (Web Components, Englisch)

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