File tree Expand file tree Collapse file tree 5 files changed +88
-0
lines changed Expand file tree Collapse file tree 5 files changed +88
-0
lines changed Original file line number Diff line number Diff line change @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
20
20
- Reset Combobox Input when the value gets reset ([ #1181 ] ( https://github.com/tailwindlabs/headlessui/pull/1181 ) )
21
21
- Fix double ` beforeEnter ` due to SSR ([ #1183 ] ( https://github.com/tailwindlabs/headlessui/pull/1183 ) )
22
22
- Adjust active {item,option} index ([ #1184 ] ( https://github.com/tailwindlabs/headlessui/pull/1184 ) )
23
+ - Only activate the ` Tab ` on mouseup ([ #1192 ] ( https://github.com/tailwindlabs/headlessui/pull/1192 ) )
24
+ - Ignore "outside click" on removed elements ([ #1193 ] ( https://github.com/tailwindlabs/headlessui/pull/1193 ) )
23
25
24
26
## [ Unreleased - @headlessui/vue ]
25
27
@@ -36,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
36
38
- Adjust active {item,option} index ([ #1184 ] ( https://github.com/tailwindlabs/headlessui/pull/1184 ) )
37
39
- Fix re-focusing element after close ([ #1186 ] ( https://github.com/tailwindlabs/headlessui/pull/1186 ) )
38
40
- Fix ` Dialog ` cycling ([ #553 ] ( https://github.com/tailwindlabs/headlessui/pull/553 ) )
41
+ - Only activate the ` Tab ` on mouseup ([ #1192 ] ( https://github.com/tailwindlabs/headlessui/pull/1192 ) )
42
+ - Ignore "outside click" on removed elements ([ #1193 ] ( https://github.com/tailwindlabs/headlessui/pull/1193 ) )
39
43
40
44
## [ @headlessui/react @v1.5.0] - 2022-02-17
41
45
Original file line number Diff line number Diff line change @@ -806,6 +806,43 @@ describe('Mouse interactions', () => {
806
806
expect ( wrapperFn ) . toHaveBeenCalledTimes ( 0 )
807
807
} )
808
808
)
809
+
810
+ it (
811
+ 'should should be possible to click on removed elements without closing the Dialog' ,
812
+ suppressConsoleLogs ( async ( ) => {
813
+ function Example ( ) {
814
+ let [ isOpen , setIsOpen ] = useState ( true )
815
+ let wrapper = useRef < HTMLDivElement | null > ( null )
816
+
817
+ return (
818
+ < Dialog open = { isOpen } onClose = { setIsOpen } >
819
+ < div ref = { wrapper } >
820
+ Contents
821
+ < button
822
+ onMouseDown = { ( ) => {
823
+ // Remove this button before the Dialog's mousedown listener fires:
824
+ wrapper . current ?. remove ( )
825
+ } }
826
+ >
827
+ Inside
828
+ </ button >
829
+ < TabSentinel />
830
+ </ div >
831
+ </ Dialog >
832
+ )
833
+ }
834
+ render ( < Example /> )
835
+
836
+ // Verify it is open
837
+ assertDialog ( { state : DialogState . Visible } )
838
+
839
+ // Click the button inside the the Dialog
840
+ await click ( getByText ( 'Inside' ) )
841
+
842
+ // Verify it is still open
843
+ assertDialog ( { state : DialogState . Visible } )
844
+ } )
845
+ )
809
846
} )
810
847
811
848
describe ( 'Nesting' , ( ) => {
Original file line number Diff line number Diff line change @@ -47,6 +47,10 @@ export function useOutsideClick(
47
47
48
48
let target = event . target as HTMLElement
49
49
50
+ // Ignore if the target doesn't exist in the DOM anymore
51
+ if ( ! target . ownerDocument . documentElement . contains ( target ) ) return
52
+
53
+ // Ignore if the target exists in one of the containers
50
54
for ( let container of _containers ) {
51
55
if ( container === null ) continue
52
56
let domNode = container instanceof HTMLElement ? container : container . current
Original file line number Diff line number Diff line change @@ -997,6 +997,44 @@ describe('Mouse interactions', () => {
997
997
expect ( wrapperFn ) . toHaveBeenCalledTimes ( 0 )
998
998
} )
999
999
)
1000
+
1001
+ it (
1002
+ 'should should be possible to click on removed elements without closing the Dialog' ,
1003
+ suppressConsoleLogs ( async ( ) => {
1004
+ renderTemplate ( {
1005
+ template : `
1006
+ <Dialog :open="isOpen" @close="setIsOpen">
1007
+ <div ref="wrapper">
1008
+ Contents
1009
+ <!-- Remove this button before the Dialog's mousedown listener fires: -->
1010
+ <button @mousedown="wrapper.remove()">Inside</button>
1011
+ <TabSentinel />
1012
+ </div>
1013
+ </Dialog>
1014
+ ` ,
1015
+ setup ( ) {
1016
+ let isOpen = ref ( true )
1017
+ let wrapper = ref < HTMLDivElement | null > ( null )
1018
+ return {
1019
+ isOpen,
1020
+ wrapper,
1021
+ setIsOpen ( value : boolean ) {
1022
+ isOpen . value = value
1023
+ } ,
1024
+ }
1025
+ } ,
1026
+ } )
1027
+
1028
+ // Verify it is open
1029
+ assertDialog ( { state : DialogState . Visible } )
1030
+
1031
+ // Click the button inside the the Dialog
1032
+ await click ( getByText ( 'Inside' ) )
1033
+
1034
+ // Verify it is still open
1035
+ assertDialog ( { state : DialogState . Visible } )
1036
+ } )
1037
+ )
1000
1038
} )
1001
1039
1002
1040
describe ( 'Nesting' , ( ) => {
Original file line number Diff line number Diff line change @@ -34,6 +34,10 @@ export function useOutsideClick(
34
34
} )
35
35
36
36
let target = event . target as HTMLElement
37
+
38
+ // Ignore if the target doesn't exist in the DOM anymore
39
+ if ( ! target . ownerDocument . documentElement . contains ( target ) ) return
40
+
37
41
let _containers = ( ( ) => {
38
42
if ( Array . isArray ( containers ) ) {
39
43
return containers
@@ -46,6 +50,7 @@ export function useOutsideClick(
46
50
return [ containers ]
47
51
} ) ( )
48
52
53
+ // Ignore if the target exists in one of the containers
49
54
for ( let container of _containers ) {
50
55
if ( container === null ) continue
51
56
let domNode = container instanceof HTMLElement ? container : dom ( container )
You can’t perform that action at this time.
0 commit comments