# @soleil/svelte-modal

> **DEPRECATED**
>
> This package won’t recieve any further updates.\
> Implement a modal using the built in dialog element or Envision instead.

An accessible modal component based on\
<https://www.w3.org/TR/wai-aria-practices-1.1/examples/dialog-modal/dialog.html>

## Install

```sh
npm i @soleil/svelte-modal
```

## Demo

Demo on [svelte.dev/repl](https://svelte.dev/repl/086bdc6a9de7470ba8dd3fcdc170bec5?version=3.44.2)

## Usage

```svelte
<script>
  import Modal from '@soleil/svelte-modal';


  let modalEl;
  const id = 'my_modal';


  const openModal = () => {
    modalEl.open();
  };
</script>


<div class="modal-example">
  <Modal id={`modal_${id}`} bind:this={modalEl} labelledBy={`heading_${id}`}>
    <h1 id={`heading_${id}`}>Heading</h1>
    <p tabindex="-1">
      Content.
    </p>
  </Modal>


  <button on:click={openModal}>Open</button>
</div>
```

## Props

```js
export let id; // ID of modal.
export let role = 'dialog'; // Role dialog or alert, most often dialog is correct.
export let label; // Label if no heading element inside modal targeted by labelledBy
export let labelledBy; // ID of element labelling the modal.
export let duration = 200; // Base duration of transition.
export let buttonOutside = false; // If close button should be outside or inside of the modal content.
export let prefix; // CSS prefix if styling are done outside of Svelte.
export let transition = scale; // Svelte transition of modal content, mask is always faded.
export let disableHash = false; // If manipulation of hash should be disabled.
```

## Events

* **open** - When modal is opened.
* **close** - When modal is closed.
* **afterOpen** - After modal is opened.
* **afterClose** - After modal is closed.
* **closeClick** - When close button is clicked.

## Custom events

It’s sometimes needed to do different things depending on what element was interacted with in the modal when closing the modal.\
One common example is having a save button and something should only occur when pressing that button.

```svelte
<script>
  import Modal from '@soleil/svelte-modal';
  import { getFromServer, saveToServer } from './api/dummy';


  export let name = '';


  let modalElement;
  const id = 'my_modal';


  const openModal = () => {
    modalElement.open();
  };


  const onClose = async () => {
    // Reset value with the saved value on the server when closing the modal.
    name = await getFromServer();
  }


  const onSave = () => {
    // Run code saving the value to server and then close.
    saveToServer(name);
  }
</script>


<div class="modal-example">
  <Modal id={`modal_${id}`} bind:this={modalElement} labelledBy={`heading_${id}`} on:close={onClose} on:save={onSave}>
    <h1 id={`heading_${id}`}>Heading</h1>
    <label for="input">Name</label>
    <input id="input" type="text" bind:value={name}>
    <!-- Close the modal with a different event -->
    <button on:click={() => (modalElement.close({ event: 'save' }))}>Save</button>
  </Modal>


  <button on:click={openModal}>Open</button>
</div>
```

## Styling

Only bare minimum for a modal is included, such as sizing of mask, wrapper and so on. You can import a basic appearance if needed, if you need a more specific appearance copy this styling to your project and change it as you see fit.

```svelte
<style lang="scss">
  .modal-example:global {
    @import '../node_modules/@soleil/svelte-modal/src/style/modal.scss';
  }
</style>
```

Also avaliable as less.