fix(frontend): blur active element on every tab switch path (B21 follow-up)

The previous B21 patch only blurred on user-initiated tab clicks via
onTabChange. Two other paths still set activeKey while a JSON-tab
input retained focus:

- importLink: after a successful share-link parse, setActiveKey('1')
  switched to the form tab while the user's focus was still on the
  Input.Search they just pressed Enter in. Chrome logged the same
  "Blocked aria-hidden" warning because the panel they were leaving
  became aria-hidden synchronously, with their input still focused.

- onTabChange entering the JSON tab: also did a bare setActiveKey
  with no blur, so going from a focused form input INTO the JSON
  tab could trip the warning in reverse.

Fix: centralized switchTab(key) that blurs document.activeElement
sync before calling setActiveKey. Every internal tab transition
(importLink, onTabChange both directions) now routes through it.
The single setActiveKey('1') in the open-modal useEffect is left as
a plain setter because there's no focused input at modal-open time.
This commit is contained in:
MHSanaei
2026-05-26 20:32:03 +02:00
parent d2f5f530e0
commit bb20cf506b

View File

@@ -204,7 +204,7 @@ export default function OutboundFormModal({
setJsonDirty(false);
setLinkInput('');
messageApi.success('Link imported successfully');
setActiveKey('1');
switchTab('1');
}
const isEdit = outboundProp != null;
@@ -358,28 +358,32 @@ export default function OutboundFormModal({
return true;
}
function onTabChange(key: string) {
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
// Wrap every tab switch with a blur of the active element. AntD marks
// the outgoing panel `aria-hidden="true"` synchronously when the
// controlled activeKey flips; if a focused input is still inside that
// panel (e.g. Input.Search on the JSON tab after user hits Enter to
// import), Chrome logs a WAI-ARIA warning. Doing the blur right
// before setActiveKey ensures the panel is unfocused by the time
// AntD applies the attribute.
function switchTab(key: string) {
if (typeof document !== 'undefined') {
(document.activeElement as HTMLElement | null)?.blur?.();
}
setActiveKey(key);
}
function onTabChange(key: string) {
if (key === '2') {
const values = form.getFieldsValue(true) as OutboundFormValues;
setJsonText(JSON.stringify(formValuesToWirePayload(values), null, 2));
setJsonDirty(false);
setActiveKey(key);
switchTab(key);
return;
}
if (key === '1' && activeKey === '2') {
if (!applyJsonToForm()) return;
}
// Blur the currently focused element before AntD marks the outgoing
// tab panel aria-hidden. Without this, a focused input inside the
// hidden panel triggers a Chrome a11y warning ("Blocked aria-hidden
// on an element because its descendant retained focus").
if (typeof document !== 'undefined') {
(document.activeElement as HTMLElement | null)?.blur?.();
}
setActiveKey(key);
switchTab(key);
}
async function onOk() {