Skip to content

Commit 91b436a

Browse files
authored
Allow to click on elements inside a Dialog Overlay (#816)
* allow to click on elements inside a Dialog Overlay * update changelog
1 parent 33c5c6e commit 91b436a

File tree

5 files changed

+86
-0
lines changed

5 files changed

+86
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Fixes
1111

1212
- Stop the event from propagating in the `Popover` component ([#798](https://github.com/tailwindlabs/headlessui/pull/798))
13+
- Allow to click on elements inside a `Dialog.Overlay` ([#816](https://github.com/tailwindlabs/headlessui/pull/816))
1314

1415
## [Unreleased - Vue]
1516

1617
### Fixes
1718

1819
- Stop the event from propagating in the `Popover` component ([#798](https://github.com/tailwindlabs/headlessui/pull/798))
20+
- Allow to click on elements inside a `DialogOverlay` ([#816](https://github.com/tailwindlabs/headlessui/pull/816))
1921

2022
## [@headlessui/react@v1.4.1] - 2021-08-30
2123

packages/@headlessui-react/src/components/dialog/dialog.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,42 @@ describe('Mouse interactions', () => {
552552
})
553553
)
554554

555+
it(
556+
'should not close the Dialog when clicking on contents of the Dialog.Overlay',
557+
suppressConsoleLogs(async () => {
558+
function Example() {
559+
let [isOpen, setIsOpen] = useState(false)
560+
return (
561+
<>
562+
<button id="trigger" onClick={() => setIsOpen(v => !v)}>
563+
Trigger
564+
</button>
565+
<Dialog open={isOpen} onClose={setIsOpen}>
566+
<Dialog.Overlay>
567+
<button>hi</button>
568+
</Dialog.Overlay>
569+
Contents
570+
<TabSentinel />
571+
</Dialog>
572+
</>
573+
)
574+
}
575+
render(<Example />)
576+
577+
// Open dialog
578+
await click(document.getElementById('trigger'))
579+
580+
// Verify it is open
581+
assertDialog({ state: DialogState.Visible })
582+
583+
// Click on an element inside the overlay
584+
await click(getByText('hi'))
585+
586+
// Verify it is still open
587+
assertDialog({ state: DialogState.Visible })
588+
})
589+
)
590+
555591
it(
556592
'should be possible to close the dialog, and re-focus the button when we click outside on the body element',
557593
suppressConsoleLogs(async () => {

packages/@headlessui-react/src/components/dialog/dialog.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ let Overlay = forwardRefWithAs(function Overlay<
355355

356356
let handleClick = useCallback(
357357
(event: ReactMouseEvent) => {
358+
if (event.target !== event.currentTarget) return
358359
if (isDisabledReactIssue7711(event.currentTarget)) return event.preventDefault()
359360
event.preventDefault()
360361
event.stopPropagation()

packages/@headlessui-vue/src/components/dialog/dialog.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,52 @@ describe('Mouse interactions', () => {
679679
})
680680
)
681681

682+
it(
683+
'should not close the Dialog when clicking on contents of the Dialog.Overlay',
684+
suppressConsoleLogs(async () => {
685+
renderTemplate({
686+
template: `
687+
<div>
688+
<button id="trigger" @click="toggleOpen">
689+
Trigger
690+
</button>
691+
<Dialog :open="isOpen" @close="setIsOpen">
692+
<DialogOverlay>
693+
<button>hi</button>
694+
</DialogOverlay>
695+
Contents
696+
<TabSentinel />
697+
</Dialog>
698+
</div>
699+
`,
700+
setup() {
701+
let isOpen = ref(false)
702+
return {
703+
isOpen,
704+
setIsOpen(value: boolean) {
705+
isOpen.value = value
706+
},
707+
toggleOpen() {
708+
isOpen.value = !isOpen.value
709+
},
710+
}
711+
},
712+
})
713+
714+
// Open dialog
715+
await click(document.getElementById('trigger'))
716+
717+
// Verify it is open
718+
assertDialog({ state: DialogState.Visible })
719+
720+
// Click on an element inside the overlay
721+
await click(getByText('hi'))
722+
723+
// Verify it is still open
724+
assertDialog({ state: DialogState.Visible })
725+
})
726+
)
727+
682728
it(
683729
'should be possible to close the dialog, and re-focus the button when we click outside on the body element',
684730
suppressConsoleLogs(async () => {

packages/@headlessui-vue/src/components/dialog/dialog.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ export let DialogOverlay = defineComponent({
305305
return {
306306
id,
307307
handleClick(event: MouseEvent) {
308+
if (event.target !== event.currentTarget) return
308309
event.preventDefault()
309310
event.stopPropagation()
310311
api.close()

0 commit comments

Comments
 (0)