docs: update dialog example (#8200)

* feat: update dialog example

* button always autofocusses, allows us to simplify

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
pull/8314/head
Hyunbin 2 years ago committed by GitHub
parent 7a6eee51e0
commit 213049cc2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,12 +4,11 @@
let showModal = false; let showModal = false;
</script> </script>
<button on:click="{() => showModal = true}"> <button on:click={() => (showModal = true)}>
show modal show modal
</button> </button>
{#if showModal} <Modal bind:showModal>
<Modal on:close="{() => showModal = false}">
<h2 slot="header"> <h2 slot="header">
modal modal
<small><em>adjective</em> mod·al \ˈmō-dəl\</small> <small><em>adjective</em> mod·al \ˈmō-dəl\</small>
@ -17,7 +16,9 @@
<ol class="definition-list"> <ol class="definition-list">
<li>of or relating to modality in logic</li> <li>of or relating to modality in logic</li>
<li>containing provisions as to the mode of procedure or the manner of taking effect —used of a contract or legacy</li> <li>
containing provisions as to the mode of procedure or the manner of taking effect —used of a contract or legacy
</li>
<li>of or relating to a musical mode</li> <li>of or relating to a musical mode</li>
<li>of or relating to structure as opposed to substance</li> <li>of or relating to structure as opposed to substance</li>
<li>of, relating to, or constituting a grammatical form or category characteristically indicating predication</li> <li>of, relating to, or constituting a grammatical form or category characteristically indicating predication</li>
@ -26,4 +27,3 @@
<a href="https://www.merriam-webster.com/dictionary/modal">merriam-webster.com</a> <a href="https://www.merriam-webster.com/dictionary/modal">merriam-webster.com</a>
</Modal> </Modal>
{/if}

@ -1,80 +1,62 @@
<script> <script>
import { createEventDispatcher, onDestroy } from 'svelte'; export let showModal; // boolean
const dispatch = createEventDispatcher(); let dialog; // HTMLDialogElement
const close = () => dispatch('close');
let modal; $: if (dialog && showModal) dialog.showModal();
const handle_keydown = e => {
if (e.key === 'Escape') {
close();
return;
}
if (e.key === 'Tab') {
// trap focus
const nodes = modal.querySelectorAll('*');
const tabbable = Array.from(nodes).filter(n => n.tabIndex >= 0);
let index = tabbable.indexOf(document.activeElement);
if (index === -1 && e.shiftKey) index = 0;
index += tabbable.length + (e.shiftKey ? -1 : 1);
index %= tabbable.length;
tabbable[index].focus();
e.preventDefault();
}
};
const previously_focused = typeof document !== 'undefined' && document.activeElement;
if (previously_focused) {
onDestroy(() => {
previously_focused.focus();
});
}
</script> </script>
<svelte:window on:keydown={handle_keydown}/> <!-- svelte-ignore a11y-click-events-have-key-events -->
<dialog
<div class="modal-background" on:click={close}></div> bind:this={dialog}
on:close={() => (showModal = false)}
<div class="modal" role="dialog" aria-modal="true" bind:this={modal}> on:click|self={() => dialog.close()}
<slot name="header"></slot> >
<hr> <div on:click|stopPropagation>
<slot></slot> <slot name="header" />
<hr> <hr />
<slot />
<hr />
<!-- svelte-ignore a11y-autofocus --> <!-- svelte-ignore a11y-autofocus -->
<button autofocus on:click={close}>close modal</button> <button autofocus on:click={() => dialog.close()}>close modal</button>
</div> </div>
</dialog>
<style> <style>
.modal-background { dialog {
position: fixed; max-width: 32em;
top: 0; border-radius: 0.2em;
left: 0; border: none;
width: 100%; padding: 0;
height: 100%; }
dialog::backdrop {
background: rgba(0, 0, 0, 0.3); background: rgba(0, 0, 0, 0.3);
} }
dialog > div {
.modal {
position: absolute;
left: 50%;
top: 50%;
width: calc(100vw - 4em);
max-width: 32em;
max-height: calc(100vh - 4em);
overflow: auto;
transform: translate(-50%,-50%);
padding: 1em; padding: 1em;
border-radius: 0.2em;
background: white;
} }
dialog[open] {
animation: zoom 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes zoom {
from {
transform: scale(0.95);
}
to {
transform: scale(1);
}
}
dialog[open]::backdrop {
animation: fade 0.2s ease-out;
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
button { button {
display: block; display: block;
} }

Loading…
Cancel
Save