<div class="dialog-wrapper" ref:node> <div class="close-dialog-button-wrapper"> <button class="close-dialog-button" aria-label="Close dialog" on:click="close()"> <span aria-hidden="true">×</span> </button> </div> <slot></slot> </div> <style> :global(.modal-dialog) { position: fixed; top: 50%; transform: translate(0, -50%); padding: 0; border: 3px solid var(--main-border); } :global(.modal-dialog-wrapper) { display: flex; flex-direction: column; align-items: center; justify-content: center; max-width: calc(100vw - 40px); } .close-dialog-button-wrapper { text-align: right; width: 100%; background: var(--nav-bg) } .close-dialog-button { padding: 0 0 7px; background: none; border: none; } .close-dialog-button span { padding: 0 15px; font-size: 48px; color: var(--button-primary-text); } :global(dialog::backdrop, .backdrop) { background: rgba(51, 51, 51, 0.9) !important; /* TODO: hack for Safari */ } @media (max-width: 767px) { .close-dialog-button span { padding: 0 10px 4px; font-size: 32px; } } </style> <script> import { importDialogPolyfill } from '../_utils/asyncModules' import { registerFocusRestoreDialog } from '../_utils/dialogs' export default { oncreate() { this.getDialogElement().style.background = this.get('background') || '#000' this.observe('shown', shown => { if (shown) { this.show() } }) this.registration = this.register() this.onDocumentClick = (e) => { let dialog = this.getDialogElement() if (!dialog.open) { return; } if (e.target !== dialog) { return; } this.close() // close when clicked outside of dialog } document.body.addEventListener('click', this.onDocumentClick); }, methods: { async register() { if (typeof HTMLDialogElement === 'undefined') { let dialogPolyfill = await importDialogPolyfill() dialogPolyfill.registerDialog(this.getDialogElement()) } registerFocusRestoreDialog(this.getDialogElement()) }, async show() { await this.registration this.getDialogElement().showModal() }, close() { this.getDialogElement().close() document.body.removeChild(this.getDialogElement()) document.body.removeEventListener('click', this.onDocumentClick); }, getDialogElement() { return this.refs.node.parentElement } } } </script>