@@ -4,15 +4,13 @@ import Sinon from 'sinon';
44import FloatingPanelElement from '../floating_panel' ;
55import PopoverElement from './index' ;
66
7- function assertPopoverShown ( el : PopoverElement , trigger : HTMLButtonElement , panel : Element ) {
8- expect ( el ) . to . have . attribute ( 'open' ) ;
7+ function assertPopoverShown ( trigger : HTMLButtonElement , panel : Element ) {
98 expect ( trigger ) . to . have . attribute ( 'data-headlessui-state' , 'open' ) ;
109 expect ( trigger ) . to . have . attribute ( 'aria-expanded' , 'true' ) ;
1110 expect ( panel ) . to . have . attribute ( 'data-headlessui-state' , 'open' ) ;
1211}
1312
14- function assertPopoverHidden ( el : PopoverElement , trigger : HTMLButtonElement , panel : Element ) {
15- expect ( el ) . not . to . have . attribute ( 'open' ) ;
13+ function assertPopoverHidden ( trigger : HTMLButtonElement , panel : Element ) {
1614 expect ( trigger ) . to . have . attribute ( 'data-headlessui-state' , '' ) ;
1715 expect ( trigger ) . to . have . attribute ( 'aria-expanded' , 'false' ) ;
1816 expect ( panel ) . to . have . attribute ( 'data-headlessui-state' , '' ) ;
@@ -27,8 +25,6 @@ describe('Popover', () => {
2725 </ twc-popover >
2826 ` ) ;
2927
30- expect ( el ) . not . to . have . attribute ( 'open' ) ;
31-
3228 const trigger = el . querySelector ( 'button' ) ! ;
3329 const panel = el . querySelector ( 'div' ) ! ;
3430
@@ -61,12 +57,12 @@ describe('Popover', () => {
6157 const panel = el . querySelector ( 'div' ) ! ;
6258
6359 trigger . click ( ) ;
64- assertPopoverShown ( el , trigger , panel ) ;
60+ assertPopoverShown ( trigger , panel ) ;
6561 expect ( document . activeElement ) . to . eq ( panel ) ;
6662 expect ( shownHandler . calledOnce ) . to . be . true ;
6763
6864 trigger . click ( ) ;
69- assertPopoverHidden ( el , trigger , panel ) ;
65+ assertPopoverHidden ( trigger , panel ) ;
7066 expect ( document . activeElement ) . to . eq ( trigger ) ;
7167 expect ( hiddenHandler . calledOnce ) . to . be . true ;
7268 } ) ;
@@ -86,11 +82,11 @@ describe('Popover', () => {
8682 const panel = el . querySelector ( 'div' ) ! ;
8783
8884 trigger . click ( ) ;
89- assertPopoverShown ( el , trigger , panel ) ;
85+ assertPopoverShown ( trigger , panel ) ;
9086 expect ( document . activeElement ) . to . eq ( panel ) ;
9187
9288 await sendKeys ( { press : 'Escape' } ) ;
93- assertPopoverHidden ( el , trigger , panel ) ;
89+ assertPopoverHidden ( trigger , panel ) ;
9490 expect ( document . activeElement ) . to . eq ( trigger ) ;
9591 expect ( hiddenHandler . calledOnce ) . to . be . true ;
9692 } ) ;
@@ -112,11 +108,11 @@ describe('Popover', () => {
112108 const closeButton = el . querySelector < HTMLButtonElement > ( '[data-test-id="close-btn"]' ) ! ;
113109
114110 trigger . click ( ) ;
115- assertPopoverShown ( el , trigger , panel ) ;
111+ assertPopoverShown ( trigger , panel ) ;
116112 expect ( document . activeElement ) . to . eq ( closeButton ) ;
117113
118114 closeButton . click ( ) ;
119- assertPopoverHidden ( el , trigger , panel ) ;
115+ assertPopoverHidden ( trigger , panel ) ;
120116 expect ( document . activeElement ) . to . eq ( trigger ) ;
121117 expect ( hiddenHandler . calledOnce ) . to . be . true ;
122118 } ) ;
@@ -136,36 +132,10 @@ describe('Popover', () => {
136132 const panel = el . querySelector ( 'div' ) ! ;
137133
138134 trigger . click ( ) ;
139- assertPopoverShown ( el , trigger , panel ) ;
135+ assertPopoverShown ( trigger , panel ) ;
140136
141137 el . hide ( ) ;
142- assertPopoverHidden ( el , trigger , panel ) ;
143- expect ( hiddenHandler . called ) . to . be . false ;
144- } ) ;
145-
146- it ( 'toggles the popover when setting the open attribute' , async ( ) => {
147- const el = await fixture < PopoverElement > ( html `
148- < twc-popover >
149- < button type ="button " data-target ="twc-popover.trigger "> Toggle</ button >
150- < div data-target ="twc-popover.panel "> </ div >
151- </ twc-popover >
152- ` ) ;
153-
154- const shownHandler = Sinon . spy ( ) ;
155- el . addEventListener ( `${ el . identifier } :shown` , shownHandler ) ;
156-
157- const hiddenHandler = Sinon . spy ( ) ;
158- el . addEventListener ( `${ el . identifier } :hidden` , hiddenHandler ) ;
159-
160- const trigger = el . querySelector ( 'button' ) ! ;
161- const panel = el . querySelector ( 'div' ) ! ;
162-
163- el . open = true ;
164- assertPopoverShown ( el , trigger , panel ) ;
165- expect ( shownHandler . called ) . to . be . false ;
166-
167- el . open = false ;
168- assertPopoverHidden ( el , trigger , panel ) ;
138+ assertPopoverHidden ( trigger , panel ) ;
169139 expect ( hiddenHandler . called ) . to . be . false ;
170140 } ) ;
171141
@@ -184,33 +154,48 @@ describe('Popover', () => {
184154 const panel = el . querySelector ( 'div' ) ! ;
185155
186156 trigger . click ( ) ;
187- assertPopoverShown ( el , trigger , panel ) ;
157+ assertPopoverShown ( trigger , panel ) ;
188158
189159 await sendMouse ( { type : 'click' , position : [ 0 , 0 ] } ) ;
190- assertPopoverHidden ( el , trigger , panel ) ;
160+ assertPopoverHidden ( trigger , panel ) ;
191161 expect ( hiddenHandler . calledOnce ) . to . be . true ;
192162 } ) ;
193163
194- it ( 'shows the popover initially if the open attribute is set to true ' , async ( ) => {
164+ it ( 'closes all the nested popovers and the parent popover when parent trigger button is clicked ' , async ( ) => {
195165 const el = await fixture < PopoverElement > ( html `
196- < twc-popover open >
197- < button type ="button " data-target ="twc-popover.trigger "> Toggle</ button >
198- < div data-target ="twc-popover.panel "> </ div >
166+ < twc-popover >
167+ < button type ="button " data-target ="twc-popover.trigger " data-test-id ="parent-trigger "> Toggle</ button >
168+ < div data-target ="twc-popover.panel " data-test-id ="parent-panel ">
169+ < twc-popover >
170+ < button type ="button " data-target ="twc-popover.trigger "> Toggle</ button >
171+ < div data-target ="twc-popover.panel "> </ div >
172+ </ twc-popover >
173+ </ div >
199174 </ twc-popover >
200175 ` ) ;
201176
202- const shownHandler = Sinon . spy ( ) ;
203- el . addEventListener ( `${ el . identifier } :shown` , shownHandler ) ;
177+ const trigger = el . querySelector < HTMLButtonElement > ( '[data-test-id="parent-trigger"]' ) ! ;
178+ const panel = el . querySelector ( '[data-test-id="parent-panel"]' ) ! ;
179+ const nestedEl = el . querySelector ( 'twc-popover' ) ! ;
180+ const nestedTrigger = nestedEl . querySelector ( 'button' ) ! ;
181+ const nestedPanel = nestedEl . querySelector ( 'div' ) ! ;
204182
205- const trigger = el . querySelector ( 'button' ) ! ;
206- const panel = el . querySelector ( 'div' ) ! ;
183+ trigger . click ( ) ;
184+ assertPopoverShown ( trigger , panel ) ;
185+
186+ nestedTrigger . click ( ) ;
187+ assertPopoverShown ( nestedTrigger , nestedPanel ) ;
188+ assertPopoverShown ( trigger , panel ) ;
207189
208- assertPopoverShown ( el , trigger , panel ) ;
209- expect ( shownHandler . called ) . to . be . false ;
210- expect ( document . activeElement ) . to . eq ( document . body ) ;
190+ await sendMouse ( {
191+ type : 'click' ,
192+ position : [ trigger . getBoundingClientRect ( ) . x , trigger . getBoundingClientRect ( ) . y ] ,
193+ } ) ;
194+ assertPopoverHidden ( trigger , panel ) ;
195+ assertPopoverHidden ( nestedTrigger , nestedPanel ) ;
211196 } ) ;
212197
213- it ( 'closes all the nested popovers and the parent popover when parent trigger button is clicked' , async ( ) => {
198+ it ( 'closes popover in order when clicked outside ' , async ( ) => {
214199 const el = await fixture < PopoverElement > ( html `
215200 < twc-popover >
216201 < button type ="button " data-target ="twc-popover.trigger " data-test-id ="parent-trigger "> Toggle</ button >
@@ -230,18 +215,51 @@ describe('Popover', () => {
230215 const nestedPanel = nestedEl . querySelector ( 'div' ) ! ;
231216
232217 trigger . click ( ) ;
233- assertPopoverShown ( el , trigger , panel ) ;
218+ nestedTrigger . click ( ) ;
219+
220+ await sendMouse ( { type : 'click' , position : [ 0 , 0 ] } ) ;
221+ assertPopoverHidden ( nestedTrigger , nestedPanel ) ;
222+ assertPopoverShown ( trigger , panel ) ;
234223
224+ await sendMouse ( { type : 'click' , position : [ 0 , 0 ] } ) ;
225+ assertPopoverHidden ( trigger , panel ) ;
226+ } ) ;
227+
228+ it ( 'closes all open popovers when opening a non-related popover' , async ( ) => {
229+ const el = await fixture < PopoverElement > ( html `
230+ < div >
231+ < twc-popover >
232+ < button type ="button " data-target ="twc-popover.trigger " data-test-id ="diff-trigger "> Toggle</ button >
233+ < div data-target ="twc-popover.panel " data-test-id ="diff-panel "> </ div >
234+ </ twc-popover >
235+ < twc-popover >
236+ < button type ="button " data-target ="twc-popover.trigger " data-test-id ="parent-trigger "> Toggle</ button >
237+ < div data-target ="twc-popover.panel " data-test-id ="parent-panel ">
238+ < twc-popover data-test-id ="nested-popover ">
239+ < button type ="button " data-target ="twc-popover.trigger "> Toggle</ button >
240+ < div data-target ="twc-popover.panel "> </ div >
241+ </ twc-popover >
242+ </ div >
243+ </ twc-popover >
244+ </ div >
245+ ` ) ;
246+
247+ const diffTrigger = el . querySelector < HTMLButtonElement > ( '[data-test-id="diff-trigger"]' ) ! ;
248+ const diffPanel = el . querySelector ( '[data-test-id="diff-panel"]' ) ! ;
249+
250+ const trigger = el . querySelector < HTMLButtonElement > ( '[data-test-id="parent-trigger"]' ) ! ;
251+ const panel = el . querySelector ( '[data-test-id="parent-panel"]' ) ! ;
252+ const nestedEl = el . querySelector < PopoverElement > ( '[data-test-id="nested-popover"]' ) ! ;
253+ const nestedTrigger = nestedEl . querySelector ( 'button' ) ! ;
254+ const nestedPanel = nestedEl . querySelector ( 'div' ) ! ;
255+
256+ trigger . click ( ) ;
235257 nestedTrigger . click ( ) ;
236- assertPopoverShown ( nestedEl , nestedTrigger , nestedPanel ) ;
237- assertPopoverShown ( el , trigger , panel ) ;
238258
239- await sendMouse ( {
240- type : 'click' ,
241- position : [ trigger . getBoundingClientRect ( ) . x , trigger . getBoundingClientRect ( ) . y ] ,
242- } ) ;
243- assertPopoverHidden ( el , trigger , panel ) ;
244- assertPopoverHidden ( nestedEl , nestedTrigger , nestedPanel ) ;
259+ diffTrigger . click ( ) ;
260+ assertPopoverHidden ( trigger , panel ) ;
261+ assertPopoverHidden ( nestedTrigger , nestedPanel ) ;
262+ assertPopoverShown ( diffTrigger , diffPanel ) ;
245263 } ) ;
246264
247265 it ( 'starts and stops the positioning logic' , async ( ) => {
@@ -256,10 +274,10 @@ describe('Popover', () => {
256274
257275 const floatingPanel = el . querySelector ( 'twc-floating-panel' ) ! as FloatingPanelElement ;
258276
259- el . open = true ;
277+ el . show ( ) ;
260278 expect ( floatingPanel ) . to . have . attribute ( 'active' ) ;
261279
262- el . open = false ;
280+ el . hide ( ) ;
263281 expect ( floatingPanel ) . not . to . have . attribute ( 'active' ) ;
264282 } ) ;
265283} ) ;
0 commit comments