import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="Layout/Modals/Documentation" />

# Modals

The modal system will handle the rendering of modals. It will also handle the stacking of multiple modals. It uses the native browser `dialog` element, which includes focus trapping and showing a backdrop.

## Usage

To use the modal system, simply add the `uui-modal-container` element to your page. This element will then handle the rendering of modals (extensions of `UUIModalElement`) that are appended as children. It is recommended to add this element to the root of your application.

There are two built in modals; `uui-modal-dialog` and `uui-modal-sidebar`. They work as wrappers for your content and should cover most usecases. However you can also extend the `UUIModalElement` to create your own custom modal.

Heres a simple example of how to use the modal system:

```html
<uui-modal-container>
  <uui-modal-dialog>
    <h1>My Modal</h1>
    <p>My modal content</p>
  </uui-modal-dialog>
</uui-modal-container>
```

## UUIModalElement

This is the base modal component. It is not meant to be used directly, but rather as a base for other modals. It has the following properties, functions, events and CSS-variables that can be used for styling and other purposes:

### Functions

---

#### `open`

opens the modal. This will happen automaticly on first render, but can be interupted and called manually if you want to open the modal at a later time. (see open event for more info)

#### `close`

closes the modal

### Properties

---

#### `isOpen`

Whether or not the modal is open.

#### `isClosing`

True when the modal is in the process of closing

#### `transitionDuration`

The duration of the transition in milliseconds. This will be provided by the `uui-modal-container`, but can be overridden if you desire.

#### `index`

The index of the modal in comparison to all other modals from front to back. This will be provided by the `uui-modal-container`.

This is used to fade out all modals except the one in front. But can be used for other purposes as well.

#### `unique-index`

The index of the modal in comparison to only modals of the same type from front to back. This will be provided by the `uui-modal-container`

This is useful for modals that are stackable, such as the sidebar. If you have two sidebars open, the first one will have a `unique-index` of 0,
and the second one will have a `unique-index` of 1. This enables you to style the first sidebar differently than the second,
regardless of how many other modals that are in between them.
Example from the sidebar:

```css
:host([unique-index='0']) dialog {
  box-shadow: var(--uui-shadow-depth-5);
}
```

### Events

---

All events from the modal base can be cancelled, thus preventing them from executing code, which enables you to customize the behavior.

#### `uui:modal-open`

Dispatched on first render. This will set open to true and show the modal. Can be cancelled if you want to prevent the modal from opening. But then you'll have to manually call `_openModal()` when you want to open the modal.

#### `uui:modal-close`

Dispatched when the modal is closed. Can be cancelled if you want to prevent the modal from closing. But then you'll have to manually call `forceClose()` when you want to close the modal.
This is used in the `uui-modal-sidebar` to wait for the animation to finish before removing the modal from the DOM.

#### `uui:modal-close-end`

This event is triggered before removing the component from the DOM, either after animations or delays or when `forceClose()` is manually invoked.

### CSS Variables

---

#### `--uui-modal-color-backdrop`

The color of the backdrop behind the modal. Defaults to `rgba(0, 0, 0, 0.5)`. This will be provided by the `uui-modal-container`, but can be overridden if you desire.

#### `--uui-modal-transition-duration`

The duration of transitions. Defaults to `250ms`. This will be provided by the `uui-modal-container`, but can be overridden if you desire.

## Pre-made modals

#### UUIModalDialogElement (uui-modal-dialog)

The dialog renders a simple styled modal container for your content. It is not a full dialog component, but rather a container for your dialog content.

#### UUIModalSidebarElement (uui-modal-sidebar)

The sidebar renders a stackable sidebar container for your content. It will place the sidebar on the right side of the screen, and will stack multiple sidebars on top of each other. It cancels the `close` event to allow for the animation to finish before removing the modal from the DOM. It also uses the open and close attributes to fade in/out the content of the modal.

## Making a custom modal

All you need to make a custom modal is to extend the `UUIModalElement` and add a dialog element as a child. From here you can use all the properties and events from the base modal, and you can add your own custom styling. The dialog and sidebar modals are good examples of how to do this.
Here's an example int Lit. Note that we also need to import the styles from the base modal, and add them to the static styles array.

```ts
export class MyModalElement extends UUIModalElement {
  render() {
    return html`
      <dialog>
        <slot></slot>
      </dialog>
    `;
  }

  static styles = [...UUIModalElement.styles, css``];
}
```
