# Overlay

Komponente des SBB Design Systems Lyne.

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

## Links

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

## Elemente

- `sbb-overlay`: It displays an interactive overlay element.

## Verwandte Komponenten

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

## Übersicht

### Was macht die Komponente?
Ein Overlay zeigt Inhalte über der Applikation, z.B. ein Formular oder eine Detailansicht. Die Seite dahinter ist nicht bedienbar und scrollt nicht. Es hat einen immer sichtbaren Schliessen-Button und kann die volle Seitenbreite einnehmen (expanded).

### Wann soll die Komponente eingesetzt werden?
* Um die Aufmerksamkeit auf umfangreiche Inhalte oder eine Aufgabe zu lenken, z.B. ein Formular.
* Für kleinere, kurze Interaktionen (z.B. Bestätigungen) ist stattdessen der [Dialog](https://digital.sbb.ch/de/design-system/lyne/components/dialog/) zu verwenden.

### Regeln.
* Das Overlay hat immer eine Möglichkeit zum Schliessen: Schliessen-Button, Esc oder eine Aktion im Inhalt.
* Der Inhalt braucht einen verständlichen Titel.
* Beim Schliessen kehrt der Fokus zum auslösenden Element zurück.

## Implementation (Web Components, Englisch)

The `<sbb-overlay>` component provides a way to present content on top of the app's content,
and it's similar to the [sbb-dialog](https://lyne-elements.app.sbb.ch/?path=/docs/elements-dialog--docs).
It offers the following features:

- disables scrolling of the page content while open;
- manages focus properly by setting it on the first focusable element;
- has a close button, which is always visible;
- adds the appropriate ARIA roles automatically.

```html
<sbb-overlay id="my-overlay">
  <p>Overlay content.</p>
</sbb-overlay>
```

### Slots

There is only one unnamed slot to provide the overlay content.

### Style

Setting the `expanded` property will cause the `<sbb-overlay>` component to take up the full width of the page.

It's possible to display the component in `negative` variant using the self-named property.

```html
<sbb-overlay negative>
  <p>Overlay content.</p>
</sbb-overlay>
```

### Interactions

In order to show the overlay, you need to provide a trigger or call the `open()` method on the `<sbb-overlay>` component.

```html
<sbb-button id="overlay-trigger">Open overlay</sbb-button>

<sbb-overlay trigger="overlay-trigger">
  <p>Overlay content.</p>
</sbb-overlay>
```

#### Closing the overlay

The overlay can be closed in several ways:

1. **Close button**: The overlay has a built-in close button that is always visible.

2. **sbb-overlay-close attribute**: Add the `sbb-overlay-close` attribute to any element within the overlay
   to close it when clicked. You can optionally provide a result value:

   ```html
   <sbb-overlay>
     <p>Overlay content.</p>
     <sbb-button sbb-overlay-close="cancel">Cancel</sbb-button>
     <sbb-button sbb-overlay-close="confirm">Confirm</sbb-button>
   </sbb-overlay>
   ```

   Alternatively, you can use the `assignOverlayResult()` helper to programmatically assign a complex result to an element:

   ```js
   import { assignOverlayResult } from '@sbb-esta/lyne-elements/overlay.js';

   const confirmButton = document.querySelector('sbb-button');
   assignOverlayResult(confirmButton, { action: 'confirm', otherProp: 'any value' });
   ```

3. **Escape key**: Pressing the `Esc` key will close the overlay.

4. **Programmatically**: Call the `close(result?: any)` method on the `<sbb-overlay>` element.
   This method closes the overlay and emits `beforeclose` and `close` events with the provided result as a payload.

   ```js
   const overlay = document.querySelector('sbb-overlay');
   overlay.close({ confirmed: true });
   ```

#### Handling close events

When the overlay closes, it emits two events:

- `beforeclose`: Emitted before the closing transition begins. This event is cancelable by calling `event.preventDefault()`.
- `close`: Emitted after the overlay has fully closed.

Both events are of type `SbbOverlayCloseEvent` and provide access to:

- `result`: The result value passed to `close()`, assigned via `assignOverlayResult()`,
  or the value of the `sbb-overlay-close` attribute. This is `null` if the dialog
  was closed via backdrop click or Escape key.
- `closeTarget`: The element that triggered the close action (e.g., the clicked button),
  or `null` if closed programmatically or via Escape key

```js
overlay.addEventListener('close', (event) => {
  console.log('Result:', event.result);
  console.log('Close target:', event.closeTarget);
});
```

### Accessibility

#### Controlling initial focus

The first element with the attribute `sbb-focus-initial` will receive focus on opening.
If the attribute is not used, the first focusable element receives focus.

#### Focus restoration

When closed, the overlay restores focus to the element that previously held focus when the
overlay opened by default. However, focus restoration can be disabled
by setting the `skipFocusRestoration` property to `true`.
As this is an accessibility feature, it is recommended to focus
an alternative element by listening to the `didClose` event.

## API (Web Components, Englisch)

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