[fix] Correct timing of <Modal> onDismiss callback

Close #2558
This commit is contained in:
Bernhard Owen Josephus
2023-07-17 16:57:33 +08:00
committed by Nicolas Gallagher
parent ef95fc0c2b
commit d8f1b5892d
2 changed files with 35 additions and 4 deletions
@@ -37,6 +37,7 @@ function ModalAnimation(props: ModalAnimationProps): React.Node {
const [isRendering, setIsRendering] = React.useState(false);
const wasVisible = React.useRef(false);
const wasRendering = React.useRef(false);
const isAnimated = animationType && animationType !== 'none';
@@ -54,14 +55,18 @@ function ModalAnimation(props: ModalAnimationProps): React.Node {
}
} else {
setIsRendering(false);
if (onDismiss) {
onDismiss();
}
}
},
[onDismiss, onShow, visible]
[onShow, visible]
);
React.useEffect(() => {
if (wasRendering.current && !isRendering && onDismiss) {
onDismiss();
}
wasRendering.current = isRendering;
}, [isRendering, onDismiss]);
React.useEffect(() => {
if (visible) {
setIsRendering(true);
@@ -309,6 +309,32 @@ describe('components/Modal', () => {
expect(document.activeElement).toBe(insideElement);
});
test('focus is not trapped after closing modal', () => {
const { rerender } = render(
<>
<a data-testid={'outside'} href={'#outside'}>
Outside
</a>
<Modal visible={true} />
</>
);
const outsideElement = document.querySelector('[data-testid="outside"]');
const onDismissCallback = jest.fn(() => outsideElement.focus());
rerender(
<>
<a data-testid={'outside'} href={'#outside'}>
Outside
</a>
<Modal onDismiss={onDismissCallback} visible={false} />
</>
);
expect(onDismissCallback).toBeCalledTimes(1);
expect(document.activeElement).toBe(outsideElement);
});
test('focus is brought back to the element that triggered modal after closing', () => {
const { rerender } = render(
<>