fix(accounts): release row focus after Escape
Blur the focused account row only when Escape clears an active account selection. This prevents Chromium focus-visible styling from leaving a thick clipped blue outline while retaining accessible focus indicators during normal keyboard navigation.
This commit is contained in:
@@ -39,7 +39,7 @@ import {
|
||||
getProviderUsageDayKey
|
||||
} from "../shared/provider-daily-limits";
|
||||
import { preservePackageOrderForDisplay, sortPackageOrderByName } from "./package-order";
|
||||
import { pruneSelection, resolveEscapeSelectionScope, shouldClearDownloadSelection } from "./selection";
|
||||
import { pruneSelection, releaseAccountSelectionFocus, resolveEscapeSelectionScope, shouldClearDownloadSelection } from "./selection";
|
||||
import { buildConfiguredProviderOrder, buildScopedAccountEnabledState, getAccountDialogSelectableOptions, matchesAccountModeFilter, pruneAccountRowSelections, resolveAccountStatusState, resolveAccountUsername, resolveVisibleAccountKind, runOptimisticAccountUpdate, updateAccountRowSelection } from "./account-ui";
|
||||
import type { AccountModeFilter } from "./account-ui";
|
||||
import { buildAccountDeleteCommand, buildAccountReplaceCommand, buildAccountSecretRequest, createAccountEditState, validateAccountEdit } from "./account-edit";
|
||||
@@ -4161,7 +4161,10 @@ export function App(): ReactElement {
|
||||
if (document.querySelector(".ctx-menu") || document.querySelector(".modal-backdrop")) return;
|
||||
if (selectionScope === "downloads") setSelectedIds(new Set());
|
||||
else if (selectionScope === "history") setSelectedHistoryIds(new Set());
|
||||
else setSelectedAccountRowKeys(new Set());
|
||||
else if (selectedAccountRowKeys.size > 0) {
|
||||
setSelectedAccountRowKeys(new Set());
|
||||
releaseAccountSelectionFocus(document.activeElement instanceof HTMLElement ? document.activeElement : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e.key === "Delete" && tabRef.current === "downloads" && selectedIds.size > 0) {
|
||||
@@ -4179,7 +4182,7 @@ export function App(): ReactElement {
|
||||
window.addEventListener("keydown", onKey);
|
||||
window.addEventListener("mousedown", onDown);
|
||||
return () => { window.removeEventListener("keydown", onKey); window.removeEventListener("mousedown", onDown); };
|
||||
}, [requestDeleteSelection, selectedIds, settingsSubTab]);
|
||||
}, [requestDeleteSelection, selectedAccountRowKeys, selectedIds, settingsSubTab]);
|
||||
|
||||
const onExportBackup = async (): Promise<void> => {
|
||||
closeMenus();
|
||||
|
||||
@@ -28,6 +28,16 @@ export function resolveEscapeSelectionScope(
|
||||
return view === "settings" && settingsSection === "accounts" ? "accounts" : null;
|
||||
}
|
||||
|
||||
export function releaseAccountSelectionFocus(
|
||||
activeElement: { closest: (selector: string) => unknown; blur: () => void } | null
|
||||
): boolean {
|
||||
if (!activeElement?.closest(".settings-account-row")) {
|
||||
return false;
|
||||
}
|
||||
activeElement.blur();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop selected ids whose package OR item no longer exists in the session.
|
||||
* The selection set mixes package and item ids; when entries vanish (delta
|
||||
|
||||
@@ -76,4 +76,21 @@ describe("global Escape selection routing", () => {
|
||||
expect(api.resolveEscapeSelectionScope?.("downloads", "allgemein", "DIV")).toBe("downloads");
|
||||
expect(api.resolveEscapeSelectionScope?.("history", "accounts", "DIV")).toBe("history");
|
||||
});
|
||||
|
||||
it("releases the focused account row when Escape leaves account selection", () => {
|
||||
const api = selection as typeof selection & {
|
||||
releaseAccountSelectionFocus?: (activeElement: { closest: (selector: string) => unknown; blur: () => void } | null) => boolean;
|
||||
};
|
||||
let blurred = false;
|
||||
const accountRow = {
|
||||
closest: (selector: string) => selector === ".settings-account-row" ? {} : null,
|
||||
blur: () => { blurred = true; }
|
||||
};
|
||||
|
||||
expect(api.releaseAccountSelectionFocus).toBeTypeOf("function");
|
||||
expect(api.releaseAccountSelectionFocus?.(accountRow)).toBe(true);
|
||||
expect(blurred).toBe(true);
|
||||
expect(api.releaseAccountSelectionFocus?.({ closest: () => null, blur: () => {} })).toBe(false);
|
||||
expect(api.releaseAccountSelectionFocus?.(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user