mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 12:44:22 +00:00
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:
parent
d2f5f530e0
commit
bb20cf506b
1 changed files with 17 additions and 13 deletions
|
|
@ -204,7 +204,7 @@ export default function OutboundFormModal({
|
||||||
setJsonDirty(false);
|
setJsonDirty(false);
|
||||||
setLinkInput('');
|
setLinkInput('');
|
||||||
messageApi.success('Link imported successfully');
|
messageApi.success('Link imported successfully');
|
||||||
setActiveKey('1');
|
switchTab('1');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isEdit = outboundProp != null;
|
const isEdit = outboundProp != null;
|
||||||
|
|
@ -358,28 +358,32 @@ export default function OutboundFormModal({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTabChange(key: string) {
|
// Wrap every tab switch with a blur of the active element. AntD marks
|
||||||
if (document.activeElement instanceof HTMLElement) {
|
// the outgoing panel `aria-hidden="true"` synchronously when the
|
||||||
document.activeElement.blur();
|
// 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') {
|
if (key === '2') {
|
||||||
const values = form.getFieldsValue(true) as OutboundFormValues;
|
const values = form.getFieldsValue(true) as OutboundFormValues;
|
||||||
setJsonText(JSON.stringify(formValuesToWirePayload(values), null, 2));
|
setJsonText(JSON.stringify(formValuesToWirePayload(values), null, 2));
|
||||||
setJsonDirty(false);
|
setJsonDirty(false);
|
||||||
setActiveKey(key);
|
switchTab(key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (key === '1' && activeKey === '2') {
|
if (key === '1' && activeKey === '2') {
|
||||||
if (!applyJsonToForm()) return;
|
if (!applyJsonToForm()) return;
|
||||||
}
|
}
|
||||||
// Blur the currently focused element before AntD marks the outgoing
|
switchTab(key);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onOk() {
|
async function onOk() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue