Auto focus modals so that escape and enter keys work without mouse intervention

This commit is contained in:
Andrew Kingston 2022-07-28 14:38:50 +01:00
parent 4b500eb26f
commit 99010ad770
1 changed files with 17 additions and 4 deletions

View File

@ -11,6 +11,8 @@
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let visible = fixed || inline let visible = fixed || inline
let modal
$: dispatch(visible ? "show" : "hide") $: dispatch(visible ? "show" : "hide")
export function show() { export function show() {
@ -41,12 +43,22 @@
} }
} }
async function focusFirstInput(node) { async function focusModal(node) {
await tick()
// Try to focus first input
const inputs = node.querySelectorAll("input") const inputs = node.querySelectorAll("input")
if (inputs?.length) { if (inputs?.length) {
await tick()
inputs[0].focus() inputs[0].focus()
} }
// Otherwise try to focus confirmation button
else if (modal) {
const confirm = modal.querySelector(".confirm-wrap .spectrum-Button")
if (confirm) {
confirm.focus()
}
}
} }
setContext(Context.Modal, { show, hide, cancel }) setContext(Context.Modal, { show, hide, cancel })
@ -56,7 +68,7 @@
{#if inline} {#if inline}
{#if visible} {#if visible}
<div use:focusFirstInput class="spectrum-Modal inline is-open"> <div use:focusModal bind:this={modal} class="spectrum-Modal inline is-open">
<slot /> <slot />
</div> </div>
{/if} {/if}
@ -80,7 +92,8 @@
<div class="modal-inner-wrapper" on:mousedown|self={cancel}> <div class="modal-inner-wrapper" on:mousedown|self={cancel}>
<slot name="outside" /> <slot name="outside" />
<div <div
use:focusFirstInput use:focusModal
bind:this={modal}
class="spectrum-Modal is-open" class="spectrum-Modal is-open"
in:fly={{ y: 30, duration: 200 }} in:fly={{ y: 30, duration: 200 }}
out:fly|local={{ y: 30, duration: 200 }} out:fly|local={{ y: 30, duration: 200 }}