@@ -5,6 +5,7 @@ import React, { useCallback, useContext } from "react";
5
5
import { BG_COLOR , TEXT_COLOR } from "../../constants" ;
6
6
import DatepickerContext from "../../contexts/DatepickerContext" ;
7
7
import { formatDate , nextMonth , previousMonth , classNames as cn } from "../../helpers" ;
8
+ import { Period } from "../../types" ;
8
9
9
10
dayjs . extend ( isBetween ) ;
10
11
@@ -240,39 +241,127 @@ const Days: React.FC<Props> = ({
240
241
[ activeDateData , hoverClassByDay , isDateDisabled ]
241
242
) ;
242
243
244
+ const checkIfHoverPeriodContainsDisabledPeriod = useCallback (
245
+ ( hoverPeriod : Period ) => {
246
+ if ( ! Array . isArray ( disabledDates ) ) {
247
+ return false ;
248
+ }
249
+ for ( let i = 0 ; i < disabledDates . length ; i ++ ) {
250
+ if (
251
+ dayjs ( hoverPeriod . start ) . isBefore ( disabledDates [ i ] . startDate ) &&
252
+ dayjs ( hoverPeriod . end ) . isAfter ( disabledDates [ i ] . endDate )
253
+ ) {
254
+ return true ;
255
+ }
256
+ }
257
+ return false ;
258
+ } ,
259
+ [ disabledDates ]
260
+ ) ;
261
+
262
+ const getMetaData = useCallback ( ( ) => {
263
+ return {
264
+ previous : previousMonth ( calendarData . date ) ,
265
+ current : calendarData . date ,
266
+ next : nextMonth ( calendarData . date )
267
+ } ;
268
+ } , [ calendarData . date ] ) ;
269
+
243
270
const hoverDay = useCallback (
244
271
( day : number , type : string ) => {
245
- const object = {
246
- previous : previousMonth ( calendarData . date ) ,
247
- current : calendarData . date ,
248
- next : nextMonth ( calendarData . date )
249
- } ;
272
+ const object = getMetaData ( ) ;
250
273
const newDate = object [ type as keyof typeof object ] ;
251
274
const newHover = `${ newDate . year ( ) } -${ newDate . month ( ) + 1 } -${
252
275
day >= 10 ? day : "0" + day
253
276
} `;
254
277
255
278
if ( period . start && ! period . end ) {
279
+ const hoverPeriod = { ...period , end : newHover } ;
256
280
if ( dayjs ( newHover ) . isBefore ( dayjs ( period . start ) ) ) {
257
- changePeriod ( {
258
- start : null ,
259
- end : period . start
260
- } ) ;
281
+ hoverPeriod . start = newHover ;
282
+ hoverPeriod . end = period . start ;
283
+ if ( ! checkIfHoverPeriodContainsDisabledPeriod ( hoverPeriod ) ) {
284
+ changePeriod ( {
285
+ start : null ,
286
+ end : period . start
287
+ } ) ;
288
+ }
289
+ }
290
+ if ( ! checkIfHoverPeriodContainsDisabledPeriod ( hoverPeriod ) ) {
291
+ changeDayHover ( newHover ) ;
261
292
}
262
- changeDayHover ( newHover ) ;
263
293
}
264
294
265
295
if ( ! period . start && period . end ) {
296
+ const hoverPeriod = { ...period , start : newHover } ;
266
297
if ( dayjs ( newHover ) . isAfter ( dayjs ( period . end ) ) ) {
267
- changePeriod ( {
268
- start : period . end ,
269
- end : null
270
- } ) ;
298
+ hoverPeriod . start = period . end ;
299
+ hoverPeriod . end = newHover ;
300
+ if ( ! checkIfHoverPeriodContainsDisabledPeriod ( hoverPeriod ) ) {
301
+ changePeriod ( {
302
+ start : period . end ,
303
+ end : null
304
+ } ) ;
305
+ }
306
+ }
307
+ if ( ! checkIfHoverPeriodContainsDisabledPeriod ( hoverPeriod ) ) {
308
+ changeDayHover ( newHover ) ;
271
309
}
272
- changeDayHover ( newHover ) ;
273
310
}
274
311
} ,
275
- [ calendarData . date , changeDayHover , changePeriod , period . end , period . start ]
312
+ [
313
+ changeDayHover ,
314
+ changePeriod ,
315
+ checkIfHoverPeriodContainsDisabledPeriod ,
316
+ getMetaData ,
317
+ period
318
+ ]
319
+ ) ;
320
+
321
+ const handleClickDay = useCallback (
322
+ ( day : number , type : "previous" | "current" | "next" ) => {
323
+ function continueClick ( ) {
324
+ if ( type === "previous" ) {
325
+ onClickPreviousDays ( day ) ;
326
+ }
327
+
328
+ if ( type === "current" ) {
329
+ onClickDay ( day ) ;
330
+ }
331
+
332
+ if ( type === "next" ) {
333
+ onClickNextDays ( day ) ;
334
+ }
335
+ }
336
+
337
+ if ( disabledDates ?. length ) {
338
+ const object = getMetaData ( ) ;
339
+ const newDate = object [ type as keyof typeof object ] ;
340
+ const clickDay = `${ newDate . year ( ) } -${ newDate . month ( ) + 1 } -${
341
+ day >= 10 ? day : "0" + day
342
+ } `;
343
+
344
+ if ( period . start && ! period . end ) {
345
+ dayjs ( clickDay ) . isSame ( dayHover ) && continueClick ( ) ;
346
+ } else if ( ! period . start && period . end ) {
347
+ dayjs ( clickDay ) . isSame ( dayHover ) && continueClick ( ) ;
348
+ } else {
349
+ continueClick ( ) ;
350
+ }
351
+ } else {
352
+ continueClick ( ) ;
353
+ }
354
+ } ,
355
+ [
356
+ dayHover ,
357
+ disabledDates ?. length ,
358
+ getMetaData ,
359
+ onClickDay ,
360
+ onClickNextDays ,
361
+ onClickPreviousDays ,
362
+ period . end ,
363
+ period . start
364
+ ]
276
365
) ;
277
366
278
367
return (
@@ -283,7 +372,7 @@ const Days: React.FC<Props> = ({
283
372
key = { index }
284
373
disabled = { isDateDisabled ( item , "previous" ) }
285
374
className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
286
- onClick = { ( ) => onClickPreviousDays ( item ) }
375
+ onClick = { ( ) => handleClickDay ( item , "previous" ) }
287
376
onMouseOver = { ( ) => {
288
377
hoverDay ( item , "previous" ) ;
289
378
} }
@@ -298,9 +387,7 @@ const Days: React.FC<Props> = ({
298
387
key = { index }
299
388
disabled = { isDateDisabled ( item , "current" ) }
300
389
className = { `${ buttonClass ( item , "current" ) } ` }
301
- onClick = { ( ) => {
302
- onClickDay ( item ) ;
303
- } }
390
+ onClick = { ( ) => handleClickDay ( item , "current" ) }
304
391
onMouseOver = { ( ) => {
305
392
hoverDay ( item , "current" ) ;
306
393
} }
@@ -315,9 +402,7 @@ const Days: React.FC<Props> = ({
315
402
key = { index }
316
403
disabled = { isDateDisabled ( index , "next" ) }
317
404
className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
318
- onClick = { ( ) => {
319
- onClickNextDays ( item ) ;
320
- } }
405
+ onClick = { ( ) => handleClickDay ( item , "next" ) }
321
406
onMouseOver = { ( ) => {
322
407
hoverDay ( item , "next" ) ;
323
408
} }
0 commit comments