fix(utils): update focus visible to remove keydown approach

This commit is contained in:
Brandy Carney
2025-01-07 13:47:50 -05:00
committed by Brandy Smith
parent 42c9db52a7
commit b09caeb053

View File

@@ -1,19 +1,5 @@
const ION_FOCUSED = 'ion-focused';
const ION_FOCUSABLE = 'ion-focusable';
const FOCUS_KEYS = [
'Tab',
'ArrowDown',
'Space',
'Escape',
' ',
'Shift',
'Enter',
'ArrowLeft',
'ArrowRight',
'ArrowUp',
'Home',
'End',
];
export interface FocusVisibleUtility {
destroy: () => void;
@@ -22,7 +8,6 @@ export interface FocusVisibleUtility {
export const startFocusVisible = (rootEl?: HTMLElement): FocusVisibleUtility => {
let currentFocus: Element[] = [];
let keyboardMode = true;
const ref = rootEl ? rootEl.shadowRoot! : document;
const root = rootEl ? rootEl : document.body;
@@ -32,43 +17,31 @@ export const startFocusVisible = (rootEl?: HTMLElement): FocusVisibleUtility =>
elements.forEach((el) => el.classList.add(ION_FOCUSED));
currentFocus = elements;
};
const pointerDown = () => {
keyboardMode = false;
setFocus([]);
};
const onKeydown = (ev: Event) => {
keyboardMode = FOCUS_KEYS.includes((ev as KeyboardEvent).key);
if (!keyboardMode) {
setFocus([]);
}
};
const onFocusin = (ev: Event) => {
if (keyboardMode && ev.composedPath !== undefined) {
const toFocus = ev.composedPath().filter((el: any) => {
// TODO(FW-2832): type
if (el.classList) {
return el.classList.contains(ION_FOCUSABLE);
}
return false;
}) as Element[];
setFocus(toFocus);
}
const toFocus = ev.composedPath().filter((el): el is HTMLElement => {
return el instanceof HTMLElement && el.classList.contains(ION_FOCUSABLE);
});
setFocus(toFocus);
};
const onFocusout = () => {
if (ref.activeElement === root) {
setFocus([]);
}
};
ref.addEventListener('keydown', onKeydown);
ref.addEventListener('focusin', onFocusin);
ref.addEventListener('focusout', onFocusout);
ref.addEventListener('touchstart', pointerDown, { passive: true });
ref.addEventListener('mousedown', pointerDown);
const destroy = () => {
ref.removeEventListener('keydown', onKeydown);
ref.removeEventListener('focusin', onFocusin);
ref.removeEventListener('focusout', onFocusout);
ref.removeEventListener('touchstart', pointerDown);