From 6550e93d50fddd6ff5f64d306e110595db956b4b Mon Sep 17 00:00:00 2001 From: "John P. rouillard" Date: Sun, 12 Feb 2023 23:05:50 -0500 Subject: [PATCH] Set focus visible when returning to some elements, add types. After command-pal gets focus, it will return focus to the element that had it prior to command-pal activation. When the focused element was an input, textarea or select control, browsers set a focus ring. If you were on a hyperlink ('a' tag) or summary/detail element, you see nothing after command-pal exits. Your focus is on the hyperlink or summary element but there is no indicator. This patch passes the standard 'focusVisible: true' option to focus() for these elements. This forces an outline around the A or summary element allowing the user to re-orient and understand what happens if they hit a space or return. Also if we implemnt the ability for a command-pal command to control where the user's focus is placed when command-pal exits, identifying the new focused element will be even more important. Ref: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#parameters Only firefox has this implemented currently. --- src/App.svelte | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index daf8b7c..0d8459c 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -33,7 +33,8 @@ let items = inputData; let itemsFiltered = inputData; let fuse = new Fuse(items, optionsFuse); - let focusedElement; + let focusedElement: HTMLElement | null = null; + let focusedElementFocusVisible = { visible: false }; onMount(() => { initShortCuts(hotkeysGlobal); @@ -41,14 +42,14 @@ if (showModal) { onClosed() } else { - focusedElement = document.activeElement + focusedElement = document.activeElement showModal = true; selectedIndex = 0; dispatch("opened"); } }); setAllShortCuts(inputData, async command => { - focusedElement = document.activeElement + focusedElement = document.activeElement showModal = true; dispatch("opened"); await asyncTimeout(200); @@ -138,7 +139,17 @@ if ( ! focusedElement ) { console.error("focusedElement not set") } else { - focusedElement.focus() + if ( ['A', 'SUMMARY'].includes(focusedElement.tagName)) { + /* If focusedElement is one of these, they do not get focus rings + by default like inputs, selects etc. We want user to know + where focus is when we return so try to activate :focus-visible + styling. So use this standard. + Only implemented in Firefox currently. + */ + focusedElementFocusVisible.visible = true; + } + focusedElement.focus( + {focusVisible: focusedElementFocusVisible.visible}) } }