<!--
Source: https://www.theui.dev/docs/modal
Part of the theui-svelte documentation. Index: https://www.theui.dev/llms.txt
-->

# Modal

The Modal component shows content in an overlay above the page, with focus trapped inside it and the page behind it locked from scrolling.

## About

Escape closes the topmost modal only, so stacked modals close one at a time. The size, the animation and the backdrop are props, and you can drive the whole thing from your own state with `bind:open` instead of passing a trigger.

## Example

To use the Modal component, you need to import it into your Svelte file. This setup allows you to easily integrate the Modal component into your project.

```html
<script>
  import { Modal } from "theui-svelte";
</script>

<Modal label="Modal Button">
  Hello Modal!
</Modal>
```

## Modal Trigger

The Modal trigger is the element that opens the Modal when clicked. You can create this trigger using either the `label` prop or the `label` snippet. The label prop generates a default button with the provided text, making it simple to open the Modal. Alternatively, the label snippet lets you customize the trigger with any element or component, giving you more flexibility.

### Trigger with the label prop

```html
<Modal label="Modal Trigger"> ... </Modal>
```

### Trigger with the label snippet

```html
<Modal>
  {#snippet label()}
    <Button>Modal Trigger</Button>
  {/snippet}
  ...
</Modal>
```

### Trigger From Outside

To control the `Modal` from outside, bind a reactive variable to its `open` prop. This is helpful when the open button is not placed inside the Modal.

```html
<script>
    let openModal: boolean = $state(false)
</script>

<Button onclick={() => openModal = true}>Open Modal</Button>

<Modal bind:open={openModal}>
    <!-- Modal content -->
</Modal>
```

## Modal Content

The content placed directly inside the `<Modal>` tag will be displayed as the main body of the Modal. The Modal also takes two snippets, for the header and the footer: `header` and `footer`.

- The `header` snippet is used to define the header section of the Modal.

- The `footer` snippet is used to define the footer section of the Modal.

```html
<Modal label="Modal Content">
  {#snippet header()}
    <h4 class="font-bold text-lg">THIS IS HEADER!</h4>
  {/snippet}

  Modal content!

  {#snippet footer()}
    <p class="text-muted">This is footer</p>
  {/snippet}
</Modal>
```

## Positioning

The `position` prop in the Modal component determines where the modal is displayed vertically on the screen. It can be set to `'top'`, `'center'`, or `'bottom'`, with the default being `'center'`. This allows you to align the modal according to your design needs, whether you want it at the top for quick alerts, in the center for standard dialogs, or at the bottom for additional content.

```html
<!-- Top-aligned Modal -->
<Modal position="top"> ... </Modal>

<!-- Centered Modal (Default) -->
<Modal position="center"> ... </Modal>

<!-- Bottom-aligned Modal -->
<Modal position="bottom"> ... </Modal>
```

## Sizing

The `size` prop controls the width of the Modal. Options include `'sm'` for small, `'md'` for medium (default), `'lg'` for large, and `'full'` for full-screen. This allows you to adjust the modal size based on your content needs.

```html
<!-- Small Modal -->
<Modal size="sm"> ... </Modal>

<!-- Medium-sized Modal (default) -->
<Modal size="md"> ... </Modal>

<!-- Large Modal -->
<Modal size="lg"> ... </Modal>

<!-- Full-width Modal -->
<Modal size="full"> ... </Modal>
```

## Animation

### Animation Type

The `animation` prop defines the type of animation used when the Modal opens or closes. Available options include `'slide-down'`, `'slide-up'`, `'fade'`, `'zoom-in'`, and `'zoom-out'`. Each option provides a different visual effect for how the Modal appears or disappears.

```html
<!-- Modal with slide-down animation -->
<Modal animation="slide-down"> ... </Modal>

<!-- Modal with slide-up animation -->
<Modal animation="slide-up"> ... </Modal>

<!-- Modal with fade (default) animation -->
<Modal animation="fade"> ... </Modal>

<!-- Modal with zoom-in animation -->
<Modal animation="zoom-in"> ... </Modal>

<!-- Modal with zoom-out animation -->
<Modal animation="zoom-out"> ... </Modal>
```

### Animation Speed

The `animationSpeed` prop controls the speed of the Modal's animation. It accepts the following values: `'none'`, `'slower'`, `'slow'`, `'normal'`, `'fast'`, and `'faster'`. The default is `'fast'`. Setting this prop to `'none'` will disable the animation, while the other values adjust the animation speed accordingly.

```html
<Modal animationSpeed="slower"> ... </Modal>
<Modal animationSpeed="slow"> ... </Modal>
<Modal animationSpeed="normal"> ... </Modal>
<Modal animationSpeed="fast"> ... </Modal>
<Modal animationSpeed="faster"> ... </Modal>
<Modal animationSpeed="none"> ... </Modal>
```

## Modal Backdrop

### Static Backdrop

The `staticBackdrop` prop controls whether the Modal closes when clicking on the backdrop. By default, the backdrop is clickable, and clicking it will close the Modal. Setting `staticBackdrop` to `true` makes the backdrop static, meaning the Modal will remain open even when the backdrop is clicked.

```html
<Modal staticBackdrop={true}> ... </Modal>
```

### Backdrop Customization

The `backdrop` prop manages the visibility and style of the Modal's backdrop. When set to `true` (default), the backdrop is visible. If set to `false`, the backdrop will be hidden. You can also customize the backdrop by passing custom CSS classes, which will apply directly to the backdrop.

```html
<!-- Modal with no backdrop -->
<Modal  backdrop={false}> ... </Modal>

<!-- Modal with custom styled backdrop -->
<Modal backdrop="bg-brand-500/30"> ... </Modal>
```

## Disable Close Button

The `closeButton` prop allows you to control the visibility of the close button in the Modal. By default, the close button is visible (`true`). Set this prop to `false` to hide the close button. You can also pass a string of custom classes to style the close button.

```html
<Modal closeButton={false}> ... </Modal>
```

## Modal Open State

The `open` prop controls whether the Modal is visible when the page loads. By default, `open` is set to `false`, meaning the Modal is hidden initially. If you set `open` to `true`, the Modal will be open and visible as soon as the page loads.

```html
<Modal open={true}> ... </Modal>
```

## Customization

To create a custom-styled modal, you can use the following props to apply custom classes to the modal's header, body, footer, and outer container:

- `headerClasses`: Customize the header section of the modal.

- `bodyClasses`: Customize the body section of the modal.

- `footerClasses`: Customize the footer section of the modal.

- `containerClasses`: Customize the outer container of the modal.

- `buttonClasses`: Customize the modal trigger created by the `label` prop.

These props allow you to apply your own styles or use TailwindCSS classes to control the layout and appearance of different parts of the modal.

```html
<Modal
  bodyClasses="bg-blue-100 dark:bg-blue-950 text-blue-800 dark:text-blue-300 border-blue-500/50 border-4 py-8"
  headerClasses="bg-blue-400/50 text-blue-600 dark:text-blue-100 shadow-blue-500/50 rounded-md p-4 border-0 shadow-md text-lg font-bold"
  footerClasses="border-blue-300/50 border rounded-xl p-2"
>
  {#snippet label()}
    <Button>Modal Button</Button>
  {/snippet}

  {#snippet header()}
    <h4>Custom Modal Header</h4>
  {/snippet}

  .....

  {#snippet footer()}
    <Button class="bg-warning-500 hover:bg-warning-600 text-warning-900" size="sm">Close</Button>
  {/snippet}
</Modal>
```

## Accessibility

The Modal carries the ARIA attributes it needs and answers to the keyboard out of the box.

- **ARIA Attributes**: The Modal uses `role="dialog"` and `aria-modal="true"` to indicate its purpose to assistive technologies. `aria-labelledby` and `aria-describedby` are added automatically to associate the header and content with the Modal. If the Modal has no header, it is labelled by the `ariaLabel` prop instead, which also labels a custom `label` snippet trigger.

- **Keyboard Navigation** Focus is automatically moved to the Modal when it opens.

- Users can navigate through focusable elements using the tab key.

- Pressing the Esc key closes the Modal. When modals are stacked, only the topmost one closes.

- A custom `label` snippet trigger can be activated with the Enter or Space key.

- **Focus Management**: focus is trapped inside the Modal while it is open, so nothing behind it can be reached. On close, focus returns to the element that opened it. Page scrolling is locked while the Modal is open, and the closed Modal is marked `inert`.

- **Screen Reader Announcements**: The Modal is announced as a dialog to screen readers, helping users understand its purpose.

- **Color Contrast**: Ensure that text and background colors inside the Modal meet WCAG contrast ratio standards.

## Configuration

### Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | string \| Snippet | `undefined` | Content or element that triggers the modal. |
| `header` | string \| Snippet | `undefined` | Content for the modal header. A string renders as plain text; use a snippet for markup. |
| `footer` | Snippet | `undefined` | Content for the modal footer. |
| `position` | 'top' \| 'center' \| 'bottom' | `center` | Position of the modal on the screen. |
| `size` | 'sm' \| 'md' \| 'lg' \| 'full' | `md` | Size of the modal. |
| `animation` | 'slide-down' \| 'slide-up' \| 'fade' \| 'zoom-in' \| 'zoom-out' | `fade` | Type of animation for the modal. |
| `animationSpeed` | [ANIMATE_SPEED](https://www.theui.dev/docs/types#animation-speed-type) | `fast` | Speed of the animation. |
| `backdrop` | boolean\|string | `true` | Controls the modal backdrop. Can be boolean or a string for custom backdrop. |
| `staticBackdrop` | boolean | `false` | Disables closing the modal by clicking on the backdrop. |
| `closeButton` | boolean \| string | `true` | Shows or hides the close button. Pass a string to add custom classes to the close button. |
| `ariaLabel` | string | `Modal` | Accessible label for the modal dialog when no header is set, and for a custom label snippet trigger. |
| `rounded` | [ROUNDED](https://www.theui.dev/docs/types#rounded-type) | `md` | Border-radius of the modal. |
| `open` | boolean | `false` | Tracks the visibility status of the modal. Bindable: use bind:open to open or close the modal from outside. |
| `buttonClasses` | string | `undefined` | Classes for the modal trigger button. |
| `containerClasses` | string | `undefined` | Classes for the modal container. |
| `bodyClasses` | string | `undefined` | CSS classes for the modal body. |
| `headerClasses` | string | `undefined` | CSS classes for the modal header. |
| `footerClasses` | string | `undefined` | CSS classes for the modal footer. |

### Snippets

| Name | Description |
| --- | --- |
| `children` | Main content of the component. |
| `label` | Content or element that triggers the modal. |
| `header` | Content for the modal header. |
| `footer` | Content for the modal footer. |

---

Category: Components
Keywords: modal, dialog, popup, overlay, component, svelte, svelte-5, theui-svelte, component-library, ui, tailwindcss
Full documentation set: https://www.theui.dev/llms-full.txt
