@@ -3,7 +3,13 @@ import React, { useCallback, useContext } from "react";
3
3
4
4
import { BG_COLOR } from "../../constants" ;
5
5
import 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" ;
7
13
8
14
const isBetween = require ( "dayjs/plugin/isBetween" ) ;
9
15
dayjs . extend ( isBetween ) ;
@@ -29,7 +35,7 @@ const Days: React.FC<Props> = ({
29
35
onClickNextDays
30
36
} ) => {
31
37
// Contexts
32
- const { primaryColor, period, changePeriod, dayHover, changeDayHover } =
38
+ const { primaryColor, period, changePeriod, dayHover, changeDayHover, minDate , maxDate } =
33
39
useContext ( DatepickerContext ) ;
34
40
35
41
// Functions
@@ -139,16 +145,55 @@ const Days: React.FC<Props> = ({
139
145
[ calendarData . date , currentDateClass , dayHover , period . end , period . start , primaryColor ]
140
146
) ;
141
147
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
149
181
} `;
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
+ ) ;
150
195
} ,
151
- [ activeDateData , hoverClassByDay ]
196
+ [ activeDateData , hoverClassByDay , isDateTooEarly , isDateTooLate ]
152
197
) ;
153
198
154
199
const hoverDay = useCallback (
@@ -163,27 +208,36 @@ const Days: React.FC<Props> = ({
163
208
day >= 10 ? day : "0" + day
164
209
} `;
165
210
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
+ }
172
219
}
173
- changeDayHover ( newHover ) ;
174
- }
175
220
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
+ }
182
228
}
183
229
changeDayHover ( newHover ) ;
184
230
}
185
231
} ,
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
+ ]
187
241
) ;
188
242
189
243
return (
@@ -192,6 +246,7 @@ const Days: React.FC<Props> = ({
192
246
< button
193
247
type = "button"
194
248
key = { index }
249
+ disabled = { isDateTooEarly ( item , "previous" ) || isDateTooLate ( item , "previous" ) }
195
250
className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
196
251
onClick = { ( ) => onClickPreviousDays ( item ) }
197
252
onMouseOver = { ( ) => {
@@ -206,7 +261,8 @@ const Days: React.FC<Props> = ({
206
261
< button
207
262
type = "button"
208
263
key = { index }
209
- className = { buttonCass ( item ) }
264
+ disabled = { isDateTooEarly ( item , "current" ) || isDateTooLate ( item , "current" ) }
265
+ className = { `${ buttonClass ( item , "current" ) } ` }
210
266
onClick = { ( ) => {
211
267
onClickDay ( item ) ;
212
268
} }
@@ -222,6 +278,7 @@ const Days: React.FC<Props> = ({
222
278
< button
223
279
type = "button"
224
280
key = { index }
281
+ disabled = { isDateTooEarly ( item , "next" ) || isDateTooLate ( item , "next" ) }
225
282
className = "flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
226
283
onClick = { ( ) => {
227
284
onClickNextDays ( item ) ;
0 commit comments