Skip to content

Commit

Permalink
Fix Dialog cleanup when the Dialog becomes hidden (#2303)
Browse files Browse the repository at this point in the history
* use the Dialog's parent as the root for the Intersection observer

We have some code that allows us to auto-close the dialog the moment it
gets hidden. This is useful if you use a dialog for a mobile menu and
you resizet he browser. If you wrap the dialog in a `md:hidden` then it
auto closes. If we don't do this, then the dialog is still locking the
scrolling, keeping the focus in the dialog, ... but it is not visible.

To solve this we use an `IntersectionObserver` to verify that the
`boundingClientRect` is "gone" (x = 0, y = 0, width = 0 and height = 0).

However, the intersection observer is not always triggered. This happens
if the main content is scrollable.

Setting the `root` of the `IntersectionObserver` to the parent of the
`Dialog` does seem to solve it.

Not 100% sure what causes this behaviour exactly.

* use a `ResizeObserver` instead of `IntersectionObserver`

* implement a `ResizeObserver` for the tests

* update changelog
  • Loading branch information
RobinMalfait authored Feb 24, 2023
1 parent d1ca3a9 commit 9ecd8dd
Show file tree
Hide file tree
Showing 6 changed files with 10 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/@headlessui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ensure the main tree and parent `Dialog` components are marked as `inert` ([#2290](https://github.com/tailwindlabs/headlessui/pull/2290))
- Fix nested `Popover` components not opening ([#2293](https://github.com/tailwindlabs/headlessui/pull/2293))
- Make React types more compatible with other libraries ([#2282](https://github.com/tailwindlabs/headlessui/pull/2282))
- Fix `Dialog` cleanup when the `Dialog` becomes hidden ([#2303](https://github.com/tailwindlabs/headlessui/pull/2303))

## [1.7.11] - 2023-02-15

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { OpenClosedProvider, State } from '../../internal/open-closed'
jest.mock('../../hooks/use-id')

// @ts-expect-error
global.IntersectionObserver = class FakeIntersectionObserver {
global.ResizeObserver = class FakeResizeObserver {
observe() {}
disconnect() {}
}
Expand Down
10 changes: 3 additions & 7 deletions packages/@headlessui-react/src/components/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,10 @@ function DialogFn<TTag extends ElementType = typeof DEFAULT_DIALOG_TAG>(
if (dialogState !== DialogStates.Open) return
if (!internalDialogRef.current) return

let observer = new IntersectionObserver((entries) => {
let observer = new ResizeObserver((entries) => {
for (let entry of entries) {
if (
entry.boundingClientRect.x === 0 &&
entry.boundingClientRect.y === 0 &&
entry.boundingClientRect.width === 0 &&
entry.boundingClientRect.height === 0
) {
let rect = entry.target.getBoundingClientRect()
if (rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0) {
close()
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/@headlessui-vue/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ensure the main tree and parent `Dialog` components are marked as `inert` ([#2290](https://github.com/tailwindlabs/headlessui/pull/2290))
- Fix nested `Popover` components not opening ([#2293](https://github.com/tailwindlabs/headlessui/pull/2293))
- Fix `change` event incorrectly getting called on `blur` ([#2296](https://github.com/tailwindlabs/headlessui/pull/2296))
- Fix `Dialog` cleanup when the `Dialog` becomes hidden ([#2303](https://github.com/tailwindlabs/headlessui/pull/2303))

## [1.7.10] - 2023-02-15

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { html } from '../../test-utils/html'
import { useOpenClosedProvider, State } from '../../internal/open-closed'

// @ts-expect-error
global.IntersectionObserver = class FakeIntersectionObserver {
global.ResizeObserver = class FakeResizeObserver {
observe() {}
disconnect() {}
}
Expand Down
10 changes: 3 additions & 7 deletions packages/@headlessui-vue/src/components/dialog/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,10 @@ export let Dialog = defineComponent({
let container = dom(internalDialogRef)
if (!container) return

let observer = new IntersectionObserver((entries) => {
let observer = new ResizeObserver((entries) => {
for (let entry of entries) {
if (
entry.boundingClientRect.x === 0 &&
entry.boundingClientRect.y === 0 &&
entry.boundingClientRect.width === 0 &&
entry.boundingClientRect.height === 0
) {
let rect = entry.target.getBoundingClientRect()
if (rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0) {
api.close()
}
}
Expand Down

0 comments on commit 9ecd8dd

Please sign in to comment.