Skip to content

Commit a4c818f

Browse files
committed
fix: focusTriggerAfterClose not working
close #280 ant-design/ant-design#32923
1 parent d8e2732 commit a4c818f

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

src/Dialog/index.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,23 @@ export default function Dialog(props: IDialogPropTypes) {
5151
// ========================== Init ==========================
5252
const ariaId = useId();
5353

54+
function saveLastOutSideActiveElementRef() {
55+
if (!contains(wrapperRef.current, document.activeElement)) {
56+
lastOutSideActiveElementRef.current = document.activeElement as HTMLElement;
57+
}
58+
}
59+
60+
function focusDialogContent() {
61+
if (contains(wrapperRef.current, document.activeElement)) {
62+
contentRef.current?.focus();
63+
}
64+
}
65+
5466
// ========================= Events =========================
5567
function onDialogVisibleChanged(newVisible: boolean) {
68+
// Try to focus
5669
if (newVisible) {
57-
// Try to focus
58-
if (!contains(wrapperRef.current, document.activeElement)) {
59-
lastOutSideActiveElementRef.current = document.activeElement as HTMLElement;
60-
contentRef.current?.focus();
61-
}
70+
focusDialogContent();
6271
} else {
6372
// Clean up scroll bar & focus back
6473
setAnimatedVisible(false);
@@ -131,6 +140,7 @@ export default function Dialog(props: IDialogPropTypes) {
131140
useEffect(() => {
132141
if (visible) {
133142
setAnimatedVisible(true);
143+
saveLastOutSideActiveElementRef();
134144
}
135145
}, [visible]);
136146

tests/index.spec.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable react/no-render-return-value, max-classes-per-file, func-names, no-console */
2-
import React, { cloneElement } from 'react';
2+
import React, { cloneElement, useEffect } from 'react';
33
import { act } from 'react-dom/test-utils';
44
import { render } from '@testing-library/react';
55
import type { ReactWrapper } from 'enzyme';
@@ -362,6 +362,56 @@ describe('dialog', () => {
362362
expect(modalRender.find('.rc-dialog-content').props().style.background).toEqual('#1890ff');
363363
});
364364

365+
it('should focus trigger after close dialog', () => {
366+
const Demo = () => {
367+
const [visible, setVisible] = React.useState(false);
368+
return (
369+
<>
370+
<button onClick={() => setVisible(true)}>trigger</button>
371+
<Dialog visible={visible} onClose={() => setVisible(false)}>
372+
content
373+
</Dialog>
374+
</>
375+
);
376+
};
377+
const wrapper = mount(<Demo />);
378+
const trigger = wrapper.find('button').at(0);
379+
(trigger.getDOMNode() as any).focus();
380+
trigger.simulate('click');
381+
jest.runAllTimers();
382+
const closeButton = wrapper.find('.rc-dialog-close');
383+
closeButton.simulate('click');
384+
jest.runAllTimers();
385+
expect(document.activeElement).toBe(trigger.getDOMNode());
386+
});
387+
388+
it('should focus trigger after close dialog when contains focusable element', () => {
389+
const Demo = () => {
390+
const [visible, setVisible] = React.useState(false);
391+
const inputRef = React.useRef(null);
392+
useEffect(() => {
393+
inputRef.current?.focus();
394+
}, []);
395+
return (
396+
<>
397+
<button onClick={() => setVisible(true)}>trigger</button>
398+
<Dialog visible={visible} onClose={() => setVisible(false)}>
399+
<input ref={inputRef} />
400+
</Dialog>
401+
</>
402+
);
403+
};
404+
const wrapper = mount(<Demo />);
405+
const trigger = wrapper.find('button').at(0);
406+
(trigger.getDOMNode() as any).focus();
407+
trigger.simulate('click');
408+
jest.runAllTimers();
409+
const closeButton = wrapper.find('.rc-dialog-close');
410+
closeButton.simulate('click');
411+
jest.runAllTimers();
412+
expect(document.activeElement).toBe(trigger.getDOMNode());
413+
});
414+
365415
describe('size should work', () => {
366416
it('width', () => {
367417
const wrapper = mount(<Dialog visible width={1128} />);

0 commit comments

Comments
 (0)