Skip to content

Commit

Permalink
fix: modal arrow keys (themesberg#369)
Browse files Browse the repository at this point in the history
Correction to keys handling and tabindex setting.
  • Loading branch information
jjagielka authored Oct 13, 2022
1 parent d1bef15 commit 2a8bc1c
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions src/lib/modals/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@
const dispatch = createEventDispatcher();
$: dispatch(open ? 'open' : 'hide');
function grabFocus(node: HTMLElement) {
function prepareFocus(node: HTMLElement) {
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT);
let n: Node | null;
while ((n = walker.nextNode())) {
if (n instanceof HTMLElement) {
const el = n as HTMLElement;
const [x, y] = isScrollable(el);
if (x || y) el.tabIndex = 0;
}
}
node.focus();
}
Expand Down Expand Up @@ -91,24 +100,14 @@
e.scrollHeight > e.clientHeight && ['scroll', 'auto'].indexOf(getComputedStyle(e).overflowY) >= 0
];
const isArrowKey = (e: KeyboardEvent, x: boolean, y: boolean) =>
(x && ['ArrowLeft', 'ArrowRight'].includes(e.key)) || (y && ['ArrowDown', 'ArrowUp'].includes(e.key));
function preventWheelDefault(e: Event) {
// @ts-ignore
const [x, y] = isScrollable(this);
return x || y || e.preventDefault();
}
function stopArrowsPropagation(e: KeyboardEvent) {
// @ts-ignore
const [x, y] = isScrollable(this);
if (isArrowKey(e, x, y)) e.stopPropagation();
}
function handleKeys(e: KeyboardEvent) {
if (e.key === 'Escape' && !permanent) return hide();
return isArrowKey(e, true, true) ? e.preventDefault() : true;
}
</script>

Expand All @@ -118,9 +117,9 @@
class={mainClass}
aria-modal="true"
role="dialog"
on:keydown={handleKeys}
on:keydown|preventDefault={handleKeys}
on:wheel|preventDefault
use:grabFocus
use:prepareFocus
use:focusTrap
on:click={autoclose ? onAutoClose : null}>
<div class="flex p-4 w-full {sizes[size]} h-full md:h-auto max-h-screen">
Expand All @@ -141,8 +140,9 @@
{/if}
<!-- Modal body -->
<div
id="modal"
class="p-6 space-y-6 flex-1 overflow-y-auto overscroll-contain"
on:keydown={stopArrowsPropagation}
on:keydown|stopPropagation={handleKeys}
on:wheel|stopPropagation={preventWheelDefault}>
<slot />
</div>
Expand Down

0 comments on commit 2a8bc1c

Please sign in to comment.