# Build a modal popup

**Within the LokiComponents library, there is the option to display a given HTML element in a modal popup. This is directly based on the native HTML element `<dialog>`, driven by Alpine logic. Building a new modal simply means calling upon the right Alpine.js diretives from within the template. And depending upon your scenario, you can opt for a plain Alpine.js component or a component partial to mix into your custom Loki Component.**

## A simple modal component
First, there is a simple Alpine component data definition `LokiModal`, that could be used quickly in any PHTML template. By using the `x-data` HTML attribute with a value `LokiModal` (which is part of the `Loki_Components` module), the modal behaviour comes to life.

```php
<div class="<?= $css('card my-2') ?>" x-data="LokiModal">
    <button @click="toggleModal" :disabled="isModalOpen">Pop up</button>

    <dialog x-ref="modal" class="border border-zinc-200 rounded-lg shadow-lg">
        <div>
            <button @click="toggleModal" class="float-right m-4 cursor-pointer w-4">Close</button>
            <p>Hello World</p>
        </div>
    </dialog>
</div>
```

The `LokiModal` definition includes the methods `toggleModal`, `isModalOpen` and `isModalClosed` so that you don't need to implement themselves. The actual `<dialog>` is reached by these methods via `x-ref="modal"` (so `this.$refs.modal` in the JavaScript code).

> Besides the `LokiModal` definition (which is actually a simple plain Alpine component), there is also a `LokiComponentModal` definition (which is a true Loki Component), allowing you to send data to Magento via AJAX.

## Adding modal behaviour to your own custom component
But what if you would like to add the same Alpine.js methods to your own existing component? The good news is that the `LokiModal` (and its Loki Component version `LokiComponentModal`) is based on a component partial `LokiModalComponentPartial`.

Imagine for instance that you already have an existing component `ExampleLokiModalComponent` (which is a Loki Component). To add modal behaviour, the component definition could be extended by destructuring the `LokiModalComponentPartial` object: 

```js
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('ExampleLokiModalComponent', () => ({
            ...LokiComponentType,
            ...LokiModalComponentPartial,
        }));
    });
</script>
```

## Using nested components
An alternative to merging the `LokiModalComponentPartial` object into your own Alpine component could be to make use of nested components: 

```html
<div x-data="ExampleLokiModalComponent">
    <div x-data="LokiModal">
        ...
    </div>
</div>
```

As long as the component properties and methods do not overlap, there is no harm in this.
