@@ -3,7 +3,13 @@ import React, { useCallback, useContext } from "react";
33
44import  {  BG_COLOR  }  from  "../../constants" ; 
55import  DatepickerContext  from  "../../contexts/DatepickerContext" ; 
6- import  {  formatDate ,  getTextColorByPrimaryColor ,  nextMonth ,  previousMonth  }  from  "../../helpers" ; 
6+ import  { 
7+     formatDate , 
8+     getTextColorByPrimaryColor , 
9+     nextMonth , 
10+     previousMonth , 
11+     classNames  as  cn 
12+ }  from  "../../helpers" ; 
713
814const  isBetween  =  require ( "dayjs/plugin/isBetween" ) ; 
915dayjs . extend ( isBetween ) ; 
@@ -29,8 +35,16 @@ const Days: React.FC<Props> = ({
2935    onClickNextDays
3036} )  =>  { 
3137    // Contexts 
32-     const  {  primaryColor,  period,  changePeriod,  dayHover,  changeDayHover }  = 
33-         useContext ( DatepickerContext ) ; 
38+     const  { 
39+         primaryColor, 
40+         period, 
41+         changePeriod, 
42+         dayHover, 
43+         changeDayHover, 
44+         minDate, 
45+         maxDate, 
46+         disabledDates
47+     }  =  useContext ( DatepickerContext ) ; 
3448
3549    // Functions 
3650    const  currentDateClass  =  useCallback ( 
@@ -139,16 +153,97 @@ const Days: React.FC<Props> = ({
139153        [ calendarData . date ,  currentDateClass ,  dayHover ,  period . end ,  period . start ,  primaryColor ] 
140154    ) ; 
141155
142-     const  buttonCass  =  useCallback ( 
143-         ( day : number )  =>  { 
144-             const  baseClass  =  "flex items-center justify-center w-12 h-12 lg:w-10 lg:h-10" ; 
145-             return  `${ baseClass } ${  
146-                 ! activeDateData ( day ) . active  
147-                     ? ` ${ hoverClassByDay ( day ) }   
148-                     : activeDateData ( day ) . className  
156+     const  isDateTooEarly  =  useCallback ( 
157+         ( day : number ,  type : string )  =>  { 
158+             if  ( ! minDate )  { 
159+                 return  false ; 
160+             } 
161+             const  object  =  { 
162+                 previous : previousMonth ( calendarData . date ) , 
163+                 current : calendarData . date , 
164+                 next : nextMonth ( calendarData . date ) 
165+             } ; 
166+             const  newDate  =  object [ type  as  keyof  typeof  object ] ; 
167+             const  formattedDate  =  `${ newDate . year ( ) } ${ newDate . month ( )  +  1 } ${  
168+                 day  >=  10  ? day  : "0"  +  day  
169+             }  `; 
170+             return  dayjs ( formattedDate ) . isSame ( dayjs ( minDate ) ) 
171+                 ? false 
172+                 : dayjs ( formattedDate ) . isBefore ( dayjs ( minDate ) ) ; 
173+         } , 
174+         [ calendarData . date ,  minDate ] 
175+     ) ; 
176+ 
177+     const  isDateTooLate  =  useCallback ( 
178+         ( day : number ,  type : string )  =>  { 
179+             if  ( ! maxDate )  { 
180+                 return  false ; 
181+             } 
182+             const  object  =  { 
183+                 previous : previousMonth ( calendarData . date ) , 
184+                 current : calendarData . date , 
185+                 next : nextMonth ( calendarData . date ) 
186+             } ; 
187+             const  newDate  =  object [ type  as  keyof  typeof  object ] ; 
188+             const  formattedDate  =  `${ newDate . year ( ) } ${ newDate . month ( )  +  1 } ${  
189+                 day  >=  10  ? day  : "0"  +  day  
149190            }  `; 
191+             return  dayjs ( formattedDate ) . isSame ( maxDate ) 
192+                 ? false 
193+                 : dayjs ( formattedDate ) . isAfter ( dayjs ( maxDate ) ) ; 
194+         } , 
195+         [ calendarData . date ,  maxDate ] 
196+     ) ; 
197+ 
198+     const  isDateDisabled  =  useCallback ( 
199+         ( day : number ,  type : string )  =>  { 
200+             if  ( isDateTooEarly ( day ,  type )  ||  isDateTooLate ( day ,  type ) )  { 
201+                 return  true ; 
202+             } 
203+             const  object  =  { 
204+                 previous : previousMonth ( calendarData . date ) , 
205+                 current : calendarData . date , 
206+                 next : nextMonth ( calendarData . date ) 
207+             } ; 
208+             const  newDate  =  object [ type  as  keyof  typeof  object ] ; 
209+             const  formattedDate  =  `${ newDate . year ( ) } ${ newDate . month ( )  +  1 } ${  
210+                 day  >=  10  ? day  : "0"  +  day  
211+             }  `; 
212+ 
213+             if  ( ! disabledDates  ||  disabledDates ?. length  <=  0 )  { 
214+                 return  false ; 
215+             } 
216+ 
217+             let  matchingCount  =  0 ; 
218+             disabledDates ?. forEach ( dateRange  =>  { 
219+                 if  ( 
220+                     dayjs ( formattedDate ) . isAfter ( dateRange . startDate )  && 
221+                     dayjs ( formattedDate ) . isBefore ( dateRange . endDate ) 
222+                 )  { 
223+                     matchingCount ++ ; 
224+                 } 
225+                 if  ( 
226+                     dayjs ( formattedDate ) . isSame ( dateRange . startDate )  || 
227+                     dayjs ( formattedDate ) . isSame ( dateRange . endDate ) 
228+                 )  { 
229+                     matchingCount ++ ; 
230+                 } 
231+             } ) ; 
232+             return  matchingCount  >  0 ; 
233+         } , 
234+         [ calendarData . date ,  isDateTooEarly ,  isDateTooLate ] 
235+     ) ; 
236+ 
237+     const  buttonClass  =  useCallback ( 
238+         ( day : number ,  type : string )  =>  { 
239+             const  baseClass  =  "flex items-center justify-center w-12 h-12 lg:w-10 lg:h-10" ; 
240+             return  cn ( 
241+                 baseClass , 
242+                 ! activeDateData ( day ) . active  ? hoverClassByDay ( day )  : activeDateData ( day ) . className , 
243+                 isDateDisabled ( day ,  type )  &&  "line-through" 
244+             ) ; 
150245        } , 
151-         [ activeDateData ,  hoverClassByDay ] 
246+         [ activeDateData ,  hoverClassByDay ,   isDateDisabled ] 
152247    ) ; 
153248
154249    const  hoverDay  =  useCallback ( 
@@ -192,6 +287,7 @@ const Days: React.FC<Props> = ({
192287                < button 
193288                    type = "button" 
194289                    key = { index } 
290+                     disabled = { isDateDisabled ( item ,  "previous" ) } 
195291                    className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10" 
196292                    onClick = { ( )  =>  onClickPreviousDays ( item ) } 
197293                    onMouseOver = { ( )  =>  { 
@@ -206,7 +302,8 @@ const Days: React.FC<Props> = ({
206302                < button 
207303                    type = "button" 
208304                    key = { index } 
209-                     className = { buttonCass ( item ) } 
305+                     disabled = { isDateDisabled ( item ,  "current" ) } 
306+                     className = { `${ buttonClass ( item ,  "current" ) }  } 
210307                    onClick = { ( )  =>  { 
211308                        onClickDay ( item ) ; 
212309                    } } 
@@ -222,6 +319,7 @@ const Days: React.FC<Props> = ({
222319                < button 
223320                    type = "button" 
224321                    key = { index } 
322+                     disabled = { isDateDisabled ( index ,  "previous" ) } 
225323                    className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10" 
226324                    onClick = { ( )  =>  { 
227325                        onClickNextDays ( item ) ; 
0 commit comments