diff --git a/packages/core/src/components/overlay/overlay.tsx b/packages/core/src/components/overlay/overlay.tsx index 5622f9adfe..cc33cba708 100644 --- a/packages/core/src/components/overlay/overlay.tsx +++ b/packages/core/src/components/overlay/overlay.tsx @@ -309,10 +309,15 @@ export class Overlay extends React.Component { } private handleBackdropMouseDown = (e: React.MouseEvent) => { - if (this.props.canOutsideClickClose) { - safeInvoke(this.props.onClose, e); + const { backdropProps, canOutsideClickClose, enforceFocus, onClose } = this.props; + if (canOutsideClickClose) { + safeInvoke(onClose, e); + } + if (enforceFocus) { + // make sure document.activeElement is updated before bringing the focus back + requestAnimationFrame(() => this.bringFocusInsideOverlay()); } - safeInvoke(this.props.backdropProps.onMouseDown, e); + safeInvoke(backdropProps.onMouseDown, e); } private handleDocumentClick = (e: MouseEvent) => { diff --git a/packages/core/test/overlay/overlayTests.tsx b/packages/core/test/overlay/overlayTests.tsx index e485b30141..d3afc6ba0a 100644 --- a/packages/core/test/overlay/overlayTests.tsx +++ b/packages/core/test/overlay/overlayTests.tsx @@ -207,6 +207,20 @@ describe("", () => { ); }); + it("returns focus to overlay after clicking the backdrop if enforceFocus=true", (done) => { + wrapper = mount( + + {createOverlayContents()} + , + { attachTo: testsContainerElement }, + ); + wrapper.find(BACKDROP_SELECTOR).simulate("mousedown"); + setTimeout(() => { + assert.equal(document.querySelector(`.${Classes.OVERLAY_CONTENT}`), document.activeElement); + done(); + }); + }); + it("does not result in maximum call stack if two overlays open with enforceFocus=true", () => { const anotherContainer = document.createElement("div"); document.documentElement.appendChild(anotherContainer);