feat: improve command palette focus management and aria
This commit is contained in:
@@ -29,6 +29,7 @@ let lastQuery = "";
|
|||||||
let continueExpanded = false;
|
let continueExpanded = false;
|
||||||
let activeRequestController: AbortController | undefined;
|
let activeRequestController: AbortController | undefined;
|
||||||
const responseCache = new Map<string, CommandPaletteItem[]>();
|
const responseCache = new Map<string, CommandPaletteItem[]>();
|
||||||
|
let lastFocusedPaletteOpener: HTMLElement | null = null;
|
||||||
|
|
||||||
const iconPaths: Record<string, string> = {
|
const iconPaths: Record<string, string> = {
|
||||||
bookmark: "M19 21l-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z",
|
bookmark: "M19 21l-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z",
|
||||||
@@ -62,6 +63,13 @@ const isTypingTarget = (target: EventTarget | null): boolean =>
|
|||||||
|
|
||||||
const isOpen = (): boolean => paletteDialog?.classList.contains("flex") ?? false;
|
const isOpen = (): boolean => paletteDialog?.classList.contains("flex") ?? false;
|
||||||
|
|
||||||
|
const setDialogState = (open: boolean): void => {
|
||||||
|
if (!paletteDialog) return;
|
||||||
|
paletteDialog.classList.toggle("hidden", !open);
|
||||||
|
paletteDialog.classList.toggle("flex", open);
|
||||||
|
paletteDialog.setAttribute("aria-hidden", open ? "false" : "true");
|
||||||
|
};
|
||||||
|
|
||||||
const setShortcutHints = (): void => {
|
const setShortcutHints = (): void => {
|
||||||
shortcutHints.forEach((hint) => {
|
shortcutHints.forEach((hint) => {
|
||||||
hint.textContent = isMac() ? "⌘P" : "Ctrl P";
|
hint.textContent = isMac() ? "⌘P" : "Ctrl P";
|
||||||
@@ -391,9 +399,9 @@ const openPalette = (): void => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
paletteDialog.classList.remove("hidden");
|
lastFocusedPaletteOpener =
|
||||||
paletteDialog.classList.add("flex");
|
document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
||||||
paletteDialog.setAttribute("aria-hidden", "false");
|
setDialogState(true);
|
||||||
paletteInput.value = "";
|
paletteInput.value = "";
|
||||||
paletteInput.focus();
|
paletteInput.focus();
|
||||||
continueExpanded = false;
|
continueExpanded = false;
|
||||||
@@ -405,9 +413,7 @@ const closePalette = (): void => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
paletteDialog.classList.add("hidden");
|
setDialogState(false);
|
||||||
paletteDialog.classList.remove("flex");
|
|
||||||
paletteDialog.setAttribute("aria-hidden", "true");
|
|
||||||
if (activeRequestController) {
|
if (activeRequestController) {
|
||||||
activeRequestController.abort();
|
activeRequestController.abort();
|
||||||
activeRequestController = undefined;
|
activeRequestController = undefined;
|
||||||
@@ -417,6 +423,7 @@ const closePalette = (): void => {
|
|||||||
paletteItems = [];
|
paletteItems = [];
|
||||||
continueExpanded = false;
|
continueExpanded = false;
|
||||||
clearResults();
|
clearResults();
|
||||||
|
lastFocusedPaletteOpener?.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDocumentClick = (event: MouseEvent): void => {
|
const onDocumentClick = (event: MouseEvent): void => {
|
||||||
@@ -490,6 +497,9 @@ const initCommandPalette = (): void => {
|
|||||||
paletteInput.addEventListener("keydown", onInputKeydown);
|
paletteInput.addEventListener("keydown", onInputKeydown);
|
||||||
document.addEventListener("click", onDocumentClick);
|
document.addEventListener("click", onDocumentClick);
|
||||||
document.addEventListener("keydown", onDocumentKeydown);
|
document.addEventListener("keydown", onDocumentKeydown);
|
||||||
|
paletteDialog?.setAttribute("aria-hidden", "true");
|
||||||
|
closestFocusable(paletteRoot ?? document.body);
|
||||||
};
|
};
|
||||||
|
|
||||||
initCommandPalette();
|
initCommandPalette();
|
||||||
|
import { closestFocusable } from "./utils";
|
||||||
|
|||||||
Reference in New Issue
Block a user