@@ -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,7 +35,7 @@ const Days: React.FC<Props> = ({
2935 onClickNextDays
3036} ) => {
3137 // Contexts
32- const { primaryColor, period, changePeriod, dayHover, changeDayHover } =
38+ const { primaryColor, period, changePeriod, dayHover, changeDayHover, minDate , maxDate } =
3339 useContext ( DatepickerContext ) ;
3440
3541 // Functions
@@ -139,16 +145,55 @@ const Days: React.FC<Props> = ({
139145 [ calendarData . date , currentDateClass , dayHover , period . end , period . start , primaryColor ]
140146 ) ;
141147
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
148+ const isDateTooEarly = useCallback (
149+ ( day : number , type : string ) => {
150+ if ( ! minDate ) {
151+ return false ;
152+ }
153+ const object = {
154+ previous : previousMonth ( calendarData . date ) ,
155+ current : calendarData . date ,
156+ next : nextMonth ( calendarData . date )
157+ } ;
158+ const newDate = object [ type as keyof typeof object ] ;
159+ const newHover = `${ newDate . year ( ) } -${ newDate . month ( ) + 1 } -${
160+ day >= 10 ? day : "0" + day
161+ } `;
162+
163+ return dayjs ( newHover ) . isBefore ( dayjs ( minDate ) . subtract ( 1 , "day" ) ) ;
164+ } ,
165+ [ calendarData . date , minDate ]
166+ ) ;
167+
168+ const isDateTooLate = useCallback (
169+ ( day : number , type : string ) => {
170+ if ( ! maxDate ) {
171+ return false ;
172+ }
173+ const object = {
174+ previous : previousMonth ( calendarData . date ) ,
175+ current : calendarData . date ,
176+ next : nextMonth ( calendarData . date )
177+ } ;
178+ const newDate = object [ type as keyof typeof object ] ;
179+ const newHover = `${ newDate . year ( ) } -${ newDate . month ( ) + 1 } -${
180+ day >= 10 ? day : "0" + day
149181 } `;
182+
183+ return dayjs ( newHover ) . isAfter ( dayjs ( maxDate ) ) ;
184+ } ,
185+ [ calendarData . date , maxDate ]
186+ ) ;
187+ const buttonClass = useCallback (
188+ ( day : number , type : string ) => {
189+ const baseClass = "flex items-center justify-center w-12 h-12 lg:w-10 lg:h-10" ;
190+ return cn (
191+ baseClass ,
192+ ! activeDateData ( day ) . active ? hoverClassByDay ( day ) : activeDateData ( day ) . className ,
193+ ( isDateTooEarly ( day , type ) || isDateTooLate ( day , type ) ) && "text-red-500"
194+ ) ;
150195 } ,
151- [ activeDateData , hoverClassByDay ]
196+ [ activeDateData , hoverClassByDay , isDateTooEarly , isDateTooLate ]
152197 ) ;
153198
154199 const hoverDay = useCallback (
@@ -163,27 +208,36 @@ const Days: React.FC<Props> = ({
163208 day >= 10 ? day : "0" + day
164209 } `;
165210
166- if ( period . start && ! period . end ) {
167- if ( dayjs ( newHover ) . isBefore ( dayjs ( period . start ) ) ) {
168- changePeriod ( {
169- start : null ,
170- end : period . start
171- } ) ;
211+ if ( ! isDateTooEarly ( day , type ) && ! isDateTooLate ( day , type ) ) {
212+ if ( period . start && ! period . end ) {
213+ if ( dayjs ( newHover ) . isBefore ( dayjs ( period . start ) ) ) {
214+ changePeriod ( {
215+ start : null ,
216+ end : period . start
217+ } ) ;
218+ }
172219 }
173- changeDayHover ( newHover ) ;
174- }
175220
176- if ( ! period . start && period . end ) {
177- if ( dayjs ( newHover ) . isAfter ( dayjs ( period . end ) ) ) {
178- changePeriod ( {
179- start : period . end ,
180- end : null
181- } ) ;
221+ if ( ! period . start && period . end ) {
222+ if ( dayjs ( newHover ) . isAfter ( dayjs ( period . end ) ) ) {
223+ changePeriod ( {
224+ start : period . end ,
225+ end : null
226+ } ) ;
227+ }
182228 }
183229 changeDayHover ( newHover ) ;
184230 }
185231 } ,
186- [ calendarData . date , changeDayHover , changePeriod , period . end , period . start ]
232+ [
233+ calendarData . date ,
234+ changeDayHover ,
235+ changePeriod ,
236+ isDateTooEarly ,
237+ isDateTooLate ,
238+ period . end ,
239+ period . start
240+ ]
187241 ) ;
188242
189243 return (
@@ -192,6 +246,7 @@ const Days: React.FC<Props> = ({
192246 < button
193247 type = "button"
194248 key = { index }
249+ disabled = { isDateTooEarly ( item , "previous" ) || isDateTooLate ( item , "previous" ) }
195250 className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
196251 onClick = { ( ) => onClickPreviousDays ( item ) }
197252 onMouseOver = { ( ) => {
@@ -206,7 +261,8 @@ const Days: React.FC<Props> = ({
206261 < button
207262 type = "button"
208263 key = { index }
209- className = { buttonCass ( item ) }
264+ disabled = { isDateTooEarly ( item , "current" ) || isDateTooLate ( item , "current" ) }
265+ className = { `${ buttonClass ( item , "current" ) } ` }
210266 onClick = { ( ) => {
211267 onClickDay ( item ) ;
212268 } }
@@ -222,6 +278,7 @@ const Days: React.FC<Props> = ({
222278 < button
223279 type = "button"
224280 key = { index }
281+ disabled = { isDateTooEarly ( item , "next" ) || isDateTooLate ( item , "next" ) }
225282 className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
226283 onClick = { ( ) => {
227284 onClickNextDays ( item ) ;
0 commit comments