Skip to content

Commit 27f475f

Browse files
committed
v1.6.0
1 parent 242a21f commit 27f475f

File tree

13 files changed

+218
-58
lines changed

13 files changed

+218
-58
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ export default function Example() {
4343
| weekDays | Array | undefined | both |
4444
| months | Array | undefined | both |
4545
| showOtherDays | Boolean | true | both |
46+
| minDate | Date, DateObject, String or Number | undefined | both |
47+
| maxDate | Date, DateObject, String or Number | undefined | both |
4648
| inputClass | String | "" | DatePicker |
4749
| name | String | "" | DatePicker |
4850
| style | Object | {} | DatePicker |

build/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-multi-date-picker",
3-
"version": "1.5.0",
3+
"version": "1.6.0",
44
"description": "a simple React datepicker component for work with gregorian, persian, arabic and indian calendars",
55
"main": "./build/index.js",
66
"scripts": {
@@ -51,6 +51,6 @@
5151
},
5252
"dependencies": {
5353
"react": "^16.13.1",
54-
"react-date-object": "^1.1.1"
54+
"react-date-object": "^1.1.2"
5555
}
5656
}

src/components/calendar/calendar.css

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@
122122
color: white;
123123
}
124124

125-
.rmdp-day.rmdp-deactive {
125+
.rmdp-day.rmdp-deactive,
126+
.rmdp-day.rmdp-disabled {
126127
color: #8798ad;
127128
}
128129

@@ -159,7 +160,7 @@
159160
border-bottom-right-radius: 50%;
160161
}
161162

162-
.rmdp-day:hover span {
163+
.rmdp-day:hover:not(.rmdp-disabled) span {
163164
background-color: rgb(126, 166, 240);
164165
color: white;
165166
}
@@ -377,7 +378,8 @@
377378
border-radius: 50%;
378379
}
379380

380-
.rmdp-day-hidden {
381+
.rmdp-day-hidden,
382+
.rmdp-day.rmdp-disabled {
381383
cursor: unset;
382384
}
383385

src/components/calendar/calendar.js

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ export default function Calendar({
1717
onlyTimePicker,
1818
onlyMonthPicker,
1919
onlyYearPicker,
20-
onChange,
2120
range = false,
2221
multiple = false,
2322
mustShowDates = true,
2423
className,
2524
weekDays,
2625
months,
2726
children,
28-
showOtherDays = true
27+
onChange,
28+
showOtherDays,
29+
minDate,
30+
maxDate
2931
}) {
3032
let [state, setState] = useState({})
3133

@@ -35,10 +37,11 @@ export default function Calendar({
3537

3638
function getFormat() {
3739
if (format) return format
38-
if (timePicker) return "YYYY/MM/DD HH:mm:ss"
40+
if (timePicker && !range && !multiple) return "YYYY/MM/DD HH:mm:ss"
3941
if (onlyTimePicker) return "HH:mm:ss"
4042
if (onlyMonthPicker) return "MM/YYYY"
4143
if (onlyYearPicker) return "YYYY"
44+
if (range || multiple) return "YYYY/MM/DD"
4245
}
4346

4447
function getSelectedDate(value) {
@@ -183,6 +186,26 @@ export default function Calendar({
183186
months
184187
])
185188

189+
useEffect(() => {
190+
if (!minDate && !maxDate) return
191+
192+
setState(state => {
193+
let [selectedDate, $minDate, $maxDate] = getDateInRangeOfMinAndMaxDate(
194+
state.selectedDate,
195+
minDate,
196+
maxDate,
197+
state.calendar
198+
)
199+
200+
return {
201+
...state,
202+
selectedDate,
203+
minDate: $minDate,
204+
maxDate: $maxDate
205+
}
206+
})
207+
}, [minDate, maxDate])
208+
186209
return (state.date ?
187210
<div
188211
className={`rmdp-wrapper ${state.ready ? "active" : ""} ${["fa", "ar"].includes(state.local) ? "rmdp-rtl" : ""} ${className || ""} ${state.range || state.multiple ? "" : "rmdp-single"}`}
@@ -226,4 +249,34 @@ function isSame(arg1, arg2) {
226249

227250
function isValidDate(date) {
228251
return Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date.getTime())
252+
}
253+
254+
export function getDateInRangeOfMinAndMaxDate(date, minDate, maxDate, calendar) {
255+
if (minDate) minDate = toDateObject(minDate, calendar).set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
256+
if (maxDate) maxDate = toDateObject(maxDate, calendar).set({ hour: 23, minute: 59, second: 59, millisecond: 999 })
257+
258+
if (Array.isArray(date)) {
259+
date = date.filter(dateObject => {
260+
if (minDate && dateObject < minDate) return false
261+
if (maxDate && dateObject > maxDate) return false
262+
263+
return true
264+
})
265+
} else {
266+
if ((minDate && date < minDate) || (maxDate && date > maxDate)) date = undefined
267+
}
268+
269+
return [date, minDate, maxDate]
270+
}
271+
272+
function toDateObject(date, calendar) {
273+
if (typeof date === "number" && date > 9999999999) date = new Date(date)
274+
275+
if (date instanceof DateObject) {
276+
if (date.calendar !== calendar) date.setCalendar(calendar)
277+
} else {
278+
date = new DateObject({ date, calendar })
279+
}
280+
281+
return date
229282
}

src/components/date_picker/date_picker.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
.rmdp-calendar-container:not(.rmdp-calendar-container-mobile) {
66
position: absolute;
77
margin-top: 1px;
8-
margin-left: 2px;
8+
left: 5px;
99
}
1010

1111
.rmdp-input {

src/components/date_picker/date_picker.js

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState, useEffect, useRef, useMemo } from "react"
2-
import Calendar from "../calendar/calendar"
2+
import Calendar, { getDateInRangeOfMinAndMaxDate } from "../calendar/calendar"
33
import DateObject from "react-date-object"
44
import { ReactComponent as Icon } from "./calendar.svg"
55
import "./date_picker.css"
@@ -31,7 +31,9 @@ export default function DatePicker({
3131
children,
3232
inputMode,
3333
scrollSensitive = true,
34-
hideOnScroll
34+
hideOnScroll,
35+
minDate,
36+
maxDate
3537
}) {
3638
let [date, setDate] = useState(value),
3739
[stringDate, setStringDate] = useState(""),
@@ -76,7 +78,8 @@ export default function DatePicker({
7678
setDate(date => {
7779
if (!date) return
7880

79-
let { _calendar, _format, _local } = ref.current
81+
let { _calendar, _format, _local, _range, _multiple } = ref.current,
82+
getLastDate = () => date[date.length - 1]
8083

8184
function checkDate(date) {
8285
if (!(date instanceof DateObject)) date = new DateObject({ date, calendar: _calendar, local: _local, format: _format })
@@ -87,32 +90,30 @@ export default function DatePicker({
8790
if (isValidMonths(months)) date.months = months
8891
if (isValidWeekDays(weekDays)) date.weekDays = weekDays
8992

90-
date.setFormat(getFormat(timePicker, onlyTimePicker, onlyMonthPicker, onlyYearPicker, format))
93+
date.setFormat(getFormat(timePicker, onlyTimePicker, onlyMonthPicker, onlyYearPicker, format, range, multiple))
9194

9295
return date
9396
}
9497

98+
if (!range && !multiple && (_range || _multiple) && Array.isArray(date)) date = getLastDate()
99+
95100
if (range || multiple || Array.isArray(date)) {
96101
if (!Array.isArray(date)) date = [date]
97102

98103
date = date.map(checkDate)
99104

100-
if (range && date.length > 2) date = [date[0], date[date.length - 1]]
105+
if (range && date.length > 2) date = [date[0], getLastDate()]
101106

102-
setStringDate(type === "button" && date.length > 1 ?
103-
[date[0], date[1]].join(separator)
104-
:
105-
date.join(separator)
106-
)
107+
setStringDate(getStringDate(date, type, separator))
107108
} else {
108-
if (Array.isArray(date)) date = date[date.length - 1]
109+
if (Array.isArray(date)) date = getLastDate()
109110

110111
date = checkDate(date)
111112

112113
setStringDate(date.format())
113114
}
114115

115-
ref.current = { ...ref.current, date, _calendar: calendar, _local: local, _format: format, separator }
116+
ref.current = { ...ref.current, date, _calendar: calendar, _local: local, _format: format, separator, _range: range, _multiple: multiple }
116117

117118
return date
118119
})
@@ -138,6 +139,22 @@ export default function DatePicker({
138139
inputRef.current.selectionStart = inputRef.current.selectionEnd = ref.current.start
139140
}, [stringDate, type])
140141

142+
useEffect(() => {
143+
if (!minDate && !maxDate) return
144+
145+
setDate(date => {
146+
let [$date] = getDateInRangeOfMinAndMaxDate(date, minDate, maxDate, calendar)
147+
148+
if (Array.isArray($date)) {
149+
setStringDate(getStringDate($date, type, separator))
150+
} else {
151+
setStringDate($date ? $date.format() : "")
152+
}
153+
154+
return $date
155+
})
156+
}, [minDate, maxDate, calendar, type, separator])
157+
141158
useEffect(() => {
142159
const calendar = calendarRef.current
143160

@@ -223,10 +240,12 @@ export default function DatePicker({
223240
weekDays={weekDays}
224241
months={months}
225242
showOtherDays={showOtherDays}
243+
minDate={minDate}
244+
maxDate={maxDate}
226245
>
227246
{children}
228247
{isMobileMode() &&
229-
<div className="rmdp-action-buttons">
248+
<div className={`rmdp-action-buttons ${["fa", "ar"].includes(local) ? "rmdp-rtl" : ""}`} >
230249
<button
231250
type="button"
232251
className="rmdp-button rmdp-action-button"
@@ -286,7 +305,7 @@ export default function DatePicker({
286305

287306
handleChange(date, isMobile)
288307

289-
ref.current.value = date
308+
ref.current.date = date
290309
}
291310

292311
if (isMobile) {
@@ -322,16 +341,11 @@ export default function DatePicker({
322341
if (Array.isArray(date)) {
323342
date.map(setCustomNames)
324343

325-
setStringDate(
326-
type === "button" && date.length > 1 ?
327-
[date[0], date[1]].join(separator)
328-
:
329-
date.join(separator)
330-
)
344+
setStringDate(getStringDate(date, type, separator))
331345
} else {
332346
setCustomNames(date)
333347

334-
setStringDate(date.format(getFormat(timePicker, onlyTimePicker, onlyMonthPicker, onlyYearPicker, format)))
348+
setStringDate(date.format(getFormat(timePicker, onlyTimePicker, onlyMonthPicker, onlyYearPicker, format, range, multiple)))
335349
}
336350
}
337351
}
@@ -447,12 +461,13 @@ export default function DatePicker({
447461
}
448462
}
449463

450-
function getFormat(timePicker, onlyTimePicker, onlyMonthPicker, onlyYearPicker, format) {
464+
function getFormat(timePicker, onlyTimePicker, onlyMonthPicker, onlyYearPicker, format, range, multiple) {
451465
if (format) return format
452-
if (timePicker) return "YYYY/MM/DD HH:mm:ss"
466+
if (timePicker && !range && !multiple) return "YYYY/MM/DD HH:mm:ss"
453467
if (onlyTimePicker) return "HH:mm:ss"
454468
if (onlyMonthPicker) return "MM/YYYY"
455469
if (onlyYearPicker) return "YYYY"
470+
if (range || multiple) return "YYYY/MM/DD"
456471
}
457472

458473
function isValidMonths(value) {
@@ -465,4 +480,13 @@ function isValidWeekDays(value) {
465480
return Array.isArray(value) && value.length === 7 && value.every(array => {
466481
return Array.isArray(array) && array.length === 2 && array.every(string => typeof string === "string")
467482
})
483+
}
484+
485+
function getStringDate(date, type, separator) {
486+
if (!date) return ""
487+
488+
return type === "button" && date.length > 1 ?
489+
[date[0], date[1]].join(separator)
490+
:
491+
date.join(separator)
468492
}

0 commit comments

Comments
 (0)