@@ -4,7 +4,11 @@ import IgcCalendarComponent from '../calendar/calendar.js';
44import { getCalendarDOM , getDOMDate } from '../calendar/helpers.spec.js' ;
55import { CalendarDay } from '../calendar/model.js' ;
66import { defineComponents } from '../common/definitions/defineComponents.js' ;
7- import { simulateClick } from '../common/utils.spec.js' ;
7+ import {
8+ isFocused ,
9+ simulateClick ,
10+ simulateKeyboard ,
11+ } from '../common/utils.spec.js' ;
812import IgcDateTimeInputComponent from '../date-time-input/date-time-input.js' ;
913import { DateTimeUtil } from '../date-time-input/date-util.js' ;
1014import IgcInputComponent from '../input/input.js' ;
@@ -14,7 +18,7 @@ describe('Date range picker', () => {
1418 before ( ( ) => defineComponents ( IgcDateRangePickerComponent ) ) ;
1519
1620 let picker : IgcDateRangePickerComponent ;
17- let _dateTimeInput : IgcDateTimeInputComponent ;
21+ let dateTimeInputs : Array < IgcDateTimeInputComponent > ;
1822 let calendar : IgcCalendarComponent ;
1923
2024 const today = CalendarDay . from ( new Date ( ) ) ;
@@ -24,9 +28,9 @@ describe('Date range picker', () => {
2428 picker = await fixture < IgcDateRangePickerComponent > (
2529 html `< igc-date-range-picker > </ igc-date-range-picker > `
2630 ) ;
27- _dateTimeInput = picker . renderRoot . querySelector (
28- IgcDateTimeInputComponent . tagName
29- ) ! ;
31+ dateTimeInputs = Array . from (
32+ picker . renderRoot . querySelectorAll ( IgcDateTimeInputComponent . tagName )
33+ ) ;
3034
3135 calendar = picker . renderRoot . querySelector ( IgcCalendarComponent . tagName ) ! ;
3236 } ) ;
@@ -146,6 +150,19 @@ describe('Date range picker', () => {
146150 } ) ;
147151 } ) ;
148152 describe ( 'Properties' , ( ) => {
153+ it ( 'should set value through attribute correctly in case the date values are valid ISO 8601 strings' , async ( ) => {
154+ const expectedValue = [ today . native , tomorrow . native ] ;
155+ const attributeValue = `${ today . native . toISOString ( ) } , ${ tomorrow . native . toISOString ( ) } ` ;
156+ picker = await fixture < IgcDateRangePickerComponent > (
157+ html `< igc-date-range-picker
158+ value ="${ attributeValue } "
159+ > </ igc-date-range-picker > `
160+ ) ;
161+ await elementUpdated ( picker ) ;
162+
163+ checkSelectedRange ( picker , expectedValue ) ;
164+ } ) ;
165+
149166 it ( 'should keep the calendar selection and input values on changing the mode' , async ( ) => {
150167 const expectedValue = [ today . native , tomorrow . native ] ;
151168 picker = await fixture < IgcDateRangePickerComponent > (
@@ -178,6 +195,149 @@ describe('Date range picker', () => {
178195 await elementUpdated ( picker ) ;
179196 checkSelectedRange ( picker , expectedValue ) ;
180197 } ) ;
198+
199+ it ( 'should not close calendar on clicking outside of it when keepOpenOnOutsideClick is true' , async ( ) => {
200+ expect ( picker . open ) . to . equal ( false ) ;
201+ picker . keepOpenOnOutsideClick = true ;
202+ await elementUpdated ( picker ) ;
203+
204+ await picker . show ( ) ;
205+
206+ expect ( picker . open ) . to . equal ( true ) ;
207+
208+ simulateClick ( document . body ) ;
209+ await elementUpdated ( picker ) ;
210+
211+ expect ( picker . open ) . to . equal ( true ) ;
212+
213+ await picker . hide ( ) ;
214+
215+ picker . mode = 'dialog' ;
216+ picker . keepOpenOnOutsideClick = true ;
217+ await elementUpdated ( picker ) ;
218+
219+ await picker . show ( ) ;
220+
221+ expect ( picker . open ) . to . equal ( true ) ;
222+ simulateClick ( document . body ) ;
223+ await elementUpdated ( picker ) ;
224+
225+ expect ( picker . open ) . to . equal ( true ) ;
226+ } ) ;
227+
228+ it ( 'should close calendar on clicking outside of it when keepOpenOnOutsideClick is false (default)' , async ( ) => {
229+ expect ( picker . open ) . to . equal ( false ) ;
230+ await elementUpdated ( picker ) ;
231+
232+ await picker . show ( ) ;
233+
234+ expect ( picker . open ) . to . equal ( true ) ;
235+
236+ simulateClick ( document . body ) ;
237+ await elementUpdated ( picker ) ;
238+
239+ expect ( picker . open ) . to . equal ( false ) ;
240+
241+ picker . mode = 'dialog' ;
242+ await elementUpdated ( picker ) ;
243+
244+ await picker . show ( ) ;
245+
246+ expect ( picker . open ) . to . equal ( true ) ;
247+ simulateClick ( document . body ) ;
248+ await elementUpdated ( picker ) ;
249+
250+ expect ( picker . open ) . to . equal ( false ) ;
251+ } ) ;
252+
253+ it ( 'should keep the picker open when keepOpenOnSelect is enabled and a selection is made in the calendar picker' , async ( ) => {
254+ const eventSpy = spy ( picker , 'emitEvent' ) ;
255+ picker . keepOpenOnSelect = true ;
256+ await elementUpdated ( picker ) ;
257+
258+ await picker . show ( ) ;
259+
260+ await selectDates ( today , tomorrow , calendar ) ;
261+
262+ expect ( eventSpy ) . calledWith ( 'igcChange' ) ;
263+ checkSelectedRange ( picker , [ today . native , tomorrow . native ] ) ;
264+ expect ( picker . open ) . to . equal ( true ) ;
265+
266+ await picker . hide ( ) ;
267+ picker . mode = 'dialog' ;
268+ await elementUpdated ( picker ) ;
269+
270+ expect ( picker . open ) . to . equal ( false ) ;
271+
272+ await picker . show ( ) ;
273+ await selectDates ( today . add ( 'day' , 2 ) , tomorrow . add ( 'day' , 2 ) , calendar ) ;
274+
275+ checkSelectedRange ( picker , [
276+ today . add ( 'day' , 2 ) . native ,
277+ tomorrow . add ( 'day' , 2 ) . native ,
278+ ] ) ;
279+ expect ( picker . open ) . to . equal ( true ) ;
280+ } ) ;
281+
282+ it ( 'should not modify value through selection or typing when readOnly is true' , async ( ) => {
283+ const eventSpy = spy ( picker , 'emitEvent' ) ;
284+ picker . readOnly = true ;
285+ await elementUpdated ( picker ) ;
286+ expect ( picker . value ) . to . deep . equal ( [ null , null ] ) ; //TODO: refactor
287+
288+ await picker . show ( ) ;
289+ await selectDates ( today , tomorrow , calendar ) ;
290+
291+ expect ( picker . value ) . to . deep . equal ( [ null , null ] ) ;
292+ expect ( calendar . values ) . to . deep . equal ( [ ] ) ;
293+ expect ( eventSpy ) . not . to . be . called ;
294+
295+ await picker . hide ( ) ;
296+
297+ dateTimeInputs [ 0 ] . focus ( ) ;
298+ simulateKeyboard ( dateTimeInputs [ 0 ] , 'ArrowDown' ) ;
299+ await elementUpdated ( picker ) ;
300+
301+ expect ( isFocused ( dateTimeInputs [ 0 ] ) ) . to . be . true ;
302+ expect ( dateTimeInputs [ 0 ] . value ) . to . equal ( null ) ;
303+ expect ( picker . value ) . to . deep . equal ( [ null , null ] ) ;
304+ expect ( calendar . values ) . to . deep . equal ( [ ] ) ;
305+ expect ( eventSpy ) . not . to . be . called ;
306+
307+ picker . singleInput = true ;
308+ await elementUpdated ( picker ) ;
309+
310+ await picker . show ( ) ;
311+
312+ calendar = picker . renderRoot . querySelector ( IgcCalendarComponent . tagName ) ! ;
313+ await selectDates ( today , tomorrow , calendar ) ;
314+
315+ expect ( picker . value ) . to . deep . equal ( [ null , null ] ) ;
316+ expect ( calendar . values ) . to . deep . equal ( [ ] ) ;
317+ expect ( eventSpy ) . not . to . be . called ;
318+ } ) ;
319+
320+ it ( 'should modify value only through calendar selection and not input when nonEditable is true (two inputs)' , async ( ) => {
321+ const eventSpy = spy ( picker , 'emitEvent' ) ;
322+ picker . nonEditable = true ;
323+ await elementUpdated ( picker ) ;
324+
325+ dateTimeInputs [ 0 ] . focus ( ) ;
326+ simulateKeyboard ( dateTimeInputs [ 0 ] , 'ArrowDown' ) ;
327+ await elementUpdated ( picker ) ;
328+
329+ expect ( isFocused ( dateTimeInputs [ 0 ] ) ) . to . be . true ;
330+ expect ( dateTimeInputs [ 0 ] . value ) . to . equal ( null ) ;
331+ expect ( picker . value ) . to . deep . equal ( [ null , null ] ) ;
332+ expect ( calendar . values ) . to . deep . equal ( [ ] ) ;
333+ expect ( eventSpy ) . not . to . be . called ;
334+
335+ await picker . show ( ) ;
336+ await selectDates ( today , tomorrow , calendar ) ;
337+
338+ checkSelectedRange ( picker , [ today . native , tomorrow . native ] ) ;
339+ expect ( eventSpy ) . calledWith ( 'igcChange' ) ;
340+ } ) ;
181341 } ) ;
182342 describe ( 'Interactions' , ( ) => {
183343 describe ( 'Selection via the calendar' , ( ) => {
0 commit comments