# Overlay

Component of the SBB design system Lyne.

- Package: `@sbb-esta/lyne-elements` (Angular: `@sbb-esta/lyne-angular`)
- Structure: one element
- Categories: Container
- Status: Design guidelines complete

## Links

- Page on digital.sbb.ch: https://digital.sbb.ch/en/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

## Elements

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

## Related components

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

## Overview

### What does the component do?
An overlay shows content on top of the application, e.g. a form or a detail view. The page behind it cannot be operated and does not scroll. It has an always-visible close button and can take up the full page width (expanded).

### When should the component be used?
* To focus attention on extensive content or a task, e.g. a form.
* For smaller, short interactions (e.g. confirmations), use the [dialog](https://digital.sbb.ch/en/design-system/lyne/components/dialog/) instead.

### Rules.
* The overlay always offers a way to close: close button, Esc or an action in the content.
* The content needs a clear title.
* When closed, focus returns to the triggering element.

## Implementation (web components)

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)

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