diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md
index 0c748df..3e94bf5 100644
--- a/packages/@headlessui-react/CHANGELOG.md
+++ b/packages/@headlessui-react/CHANGELOG.md
@@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Fixed SSR support on Deno ([#1671](https://github.com/tailwindlabs/headlessui/pull/1671))
+- Don’t close dialog when opened during mouse up event ([#1667](https://github.com/tailwindlabs/headlessui/pull/1667))
+- Don’t close dialog when drag ends outside dialog ([#1667](https://github.com/tailwindlabs/headlessui/pull/1667))
+- Fix outside clicks to close dialog when nested, unopened dialogs are present ([#1667](https://github.com/tailwindlabs/headlessui/pull/1667))
## [1.6.6] - 2022-07-07
diff --git a/packages/@headlessui-react/src/components/dialog/dialog.test.tsx b/packages/@headlessui-react/src/components/dialog/dialog.test.tsx
index 21971b8..fe12492 100644
--- a/packages/@headlessui-react/src/components/dialog/dialog.test.tsx
+++ b/packages/@headlessui-react/src/components/dialog/dialog.test.tsx
@@ -17,7 +17,7 @@ import {
getDialogs,
getDialogOverlays,
} from '../../test-utils/accessibility-assertions'
-import { click, press, Keys } from '../../test-utils/interactions'
+import { click, mouseDrag, press, Keys } from '../../test-utils/interactions'
import { PropsOf } from '../../types'
import { Transition } from '../transitions/transition'
import { createPortal } from 'react-dom'
@@ -1066,14 +1066,101 @@ describe('Mouse interactions', () => {
assertDialog({ state: DialogState.Visible })
})
)
+
+ it(
+ 'should not close the dialog if opened during mouse up',
+ suppressConsoleLogs(async () => {
+ function Example() {
+ let [isOpen, setIsOpen] = useState(false)
+ return (
+ <>
+
+
+ >
+ )
+ }
+
+ render()
+
+ await click(document.getElementById('trigger'))
+
+ assertDialog({ state: DialogState.Visible })
+
+ await click(document.getElementById('inside'))
+
+ assertDialog({ state: DialogState.Visible })
+ })
+ )
+
+ it(
+ 'should not close the dialog if click starts inside the dialog but ends outside',
+ suppressConsoleLogs(async () => {
+ function Example() {
+ let [isOpen, setIsOpen] = useState(false)
+ return (
+ <>
+
+
this thing
+
+ >
+ )
+ }
+
+ render()
+
+ // Open the dialog
+ await click(document.getElementById('trigger'))
+
+ assertDialog({ state: DialogState.Visible })
+
+ // Start a click inside the dialog and end it outside
+ await mouseDrag(document.getElementById('inside'), document.getElementById('imoutside'))
+
+ // It should not have hidden
+ assertDialog({ state: DialogState.Visible })
+
+ await click(document.getElementById('imoutside'))
+
+ // It's gone
+ assertDialog({ state: DialogState.InvisibleUnmounted })
+ })
+ )
})
describe('Nesting', () => {
- function Nested({ onClose, level = 1 }: { onClose: (value: boolean) => void; level?: number }) {
+ type RenderStrategy = 'mounted' | 'always'
+
+ function Nested({
+ onClose,
+ open = true,
+ level = 1,
+ renderWhen = 'mounted',
+ }: {
+ onClose: (value: boolean) => void
+ open?: boolean
+ level?: number
+ renderWhen?: RenderStrategy
+ }) {
let [showChild, setShowChild] = useState(false)
return (
-