@react-stately/calendar 3.5.1 → 3.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types.d.ts +6 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/useCalendarState.main.js +17 -14
- package/dist/useCalendarState.main.js.map +1 -1
- package/dist/useCalendarState.mjs +17 -14
- package/dist/useCalendarState.module.js +17 -14
- package/dist/useCalendarState.module.js.map +1 -1
- package/dist/useRangeCalendarState.main.js +11 -10
- package/dist/useRangeCalendarState.main.js.map +1 -1
- package/dist/useRangeCalendarState.mjs +11 -10
- package/dist/useRangeCalendarState.module.js +11 -10
- package/dist/useRangeCalendarState.module.js.map +1 -1
- package/dist/utils.main.js +21 -8
- package/dist/utils.main.js.map +1 -1
- package/dist/utils.mjs +21 -8
- package/dist/utils.module.js +21 -8
- package/dist/utils.module.js.map +1 -1
- package/package.json +7 -7
- package/src/types.ts +6 -6
- package/src/useCalendarState.ts +18 -18
- package/src/useRangeCalendarState.ts +28 -25
- package/src/utils.ts +29 -16
package/src/useCalendarState.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
toCalendarDate,
|
|
28
28
|
today
|
|
29
29
|
} from '@internationalized/date';
|
|
30
|
-
import {CalendarProps, DateValue} from '@react-types/calendar';
|
|
30
|
+
import {CalendarProps, DateValue, MappedDateValue} from '@react-types/calendar';
|
|
31
31
|
import {CalendarState} from './types';
|
|
32
32
|
import {useControlledState} from '@react-stately/utils';
|
|
33
33
|
import {useMemo, useState} from 'react';
|
|
@@ -51,7 +51,6 @@ export interface CalendarStateOptions<T extends DateValue = DateValue> extends C
|
|
|
51
51
|
/** Determines how to align the initial selection relative to the visible date range. */
|
|
52
52
|
selectionAlignment?: 'start' | 'center' | 'end'
|
|
53
53
|
}
|
|
54
|
-
|
|
55
54
|
/**
|
|
56
55
|
* Provides state management for a calendar component.
|
|
57
56
|
* A calendar displays one or more date grids and allows users to select a single date.
|
|
@@ -71,7 +70,7 @@ export function useCalendarState<T extends DateValue = DateValue>(props: Calenda
|
|
|
71
70
|
} = props;
|
|
72
71
|
let calendar = useMemo(() => createCalendar(resolvedOptions.calendar), [createCalendar, resolvedOptions.calendar]);
|
|
73
72
|
|
|
74
|
-
let [value, setControlledValue] = useControlledState<DateValue
|
|
73
|
+
let [value, setControlledValue] = useControlledState<DateValue | null, MappedDateValue<T>>(props.value!, props.defaultValue ?? null!, props.onChange);
|
|
75
74
|
let calendarDateValue = useMemo(() => value ? toCalendar(toCalendarDate(value), calendar) : null, [value, calendar]);
|
|
76
75
|
let timeZone = useMemo(() => value && 'timeZone' in value ? value.timeZone : resolvedOptions.timeZone, [value, resolvedOptions.timeZone]);
|
|
77
76
|
let focusedCalendarDate = useMemo(() => (
|
|
@@ -138,25 +137,26 @@ export function useCalendarState<T extends DateValue = DateValue>(props: Calenda
|
|
|
138
137
|
|
|
139
138
|
function setValue(newValue: CalendarDate | null) {
|
|
140
139
|
if (!props.isDisabled && !props.isReadOnly) {
|
|
141
|
-
|
|
140
|
+
let localValue = newValue;
|
|
141
|
+
if (localValue === null) {
|
|
142
142
|
setControlledValue(null);
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (!
|
|
145
|
+
localValue = constrainValue(localValue, minValue, maxValue);
|
|
146
|
+
localValue = previousAvailableDate(localValue, startDate, isDateUnavailable);
|
|
147
|
+
if (!localValue) {
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
// The display calendar should not have any effect on the emitted value.
|
|
152
152
|
// Emit dates in the same calendar as the original value, if any, otherwise gregorian.
|
|
153
|
-
|
|
153
|
+
localValue = toCalendar(localValue, value?.calendar || new GregorianCalendar());
|
|
154
154
|
|
|
155
155
|
// Preserve time if the input value had one.
|
|
156
156
|
if (value && 'hour' in value) {
|
|
157
|
-
setControlledValue(value.set(
|
|
157
|
+
setControlledValue(value.set(localValue));
|
|
158
158
|
} else {
|
|
159
|
-
setControlledValue(
|
|
159
|
+
setControlledValue(localValue);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -173,7 +173,7 @@ export function useCalendarState<T extends DateValue = DateValue>(props: Calenda
|
|
|
173
173
|
return isInvalid(calendarDateValue, minValue, maxValue);
|
|
174
174
|
}, [calendarDateValue, isDateUnavailable, minValue, maxValue]);
|
|
175
175
|
let isValueInvalid = props.isInvalid || props.validationState === 'invalid' || isUnavailable;
|
|
176
|
-
let validationState: ValidationState = isValueInvalid ? 'invalid' : null;
|
|
176
|
+
let validationState: ValidationState | null = isValueInvalid ? 'invalid' : null;
|
|
177
177
|
|
|
178
178
|
let pageDuration = useMemo(() => {
|
|
179
179
|
if (pageBehavior === 'visible') {
|
|
@@ -184,8 +184,8 @@ export function useCalendarState<T extends DateValue = DateValue>(props: Calenda
|
|
|
184
184
|
}, [pageBehavior, visibleDuration]);
|
|
185
185
|
|
|
186
186
|
return {
|
|
187
|
-
isDisabled: props.isDisabled,
|
|
188
|
-
isReadOnly: props.isReadOnly,
|
|
187
|
+
isDisabled: props.isDisabled ?? false,
|
|
188
|
+
isReadOnly: props.isReadOnly ?? false,
|
|
189
189
|
value: calendarDateValue,
|
|
190
190
|
setValue,
|
|
191
191
|
visibleRange: {
|
|
@@ -308,25 +308,25 @@ export function useCalendarState<T extends DateValue = DateValue>(props: Calenda
|
|
|
308
308
|
return isFocused && focusedDate && isSameDay(date, focusedDate);
|
|
309
309
|
},
|
|
310
310
|
isCellDisabled(date) {
|
|
311
|
-
return props.isDisabled || date.compare(startDate) < 0 || date.compare(endDate) > 0 || this.isInvalid(date
|
|
311
|
+
return props.isDisabled || date.compare(startDate) < 0 || date.compare(endDate) > 0 || this.isInvalid(date);
|
|
312
312
|
},
|
|
313
313
|
isCellUnavailable(date) {
|
|
314
|
-
return props.isDateUnavailable
|
|
314
|
+
return props.isDateUnavailable ? props.isDateUnavailable(date) : false;
|
|
315
315
|
},
|
|
316
316
|
isPreviousVisibleRangeInvalid() {
|
|
317
317
|
let prev = startDate.subtract({days: 1});
|
|
318
|
-
return isSameDay(prev, startDate) || this.isInvalid(prev
|
|
318
|
+
return isSameDay(prev, startDate) || this.isInvalid(prev);
|
|
319
319
|
},
|
|
320
320
|
isNextVisibleRangeInvalid() {
|
|
321
321
|
// Adding may return the same date if we reached the end of time
|
|
322
322
|
// according to the calendar system (e.g. 9999-12-31).
|
|
323
323
|
let next = endDate.add({days: 1});
|
|
324
|
-
return isSameDay(next, endDate) || this.isInvalid(next
|
|
324
|
+
return isSameDay(next, endDate) || this.isInvalid(next);
|
|
325
325
|
},
|
|
326
326
|
getDatesInWeek(weekIndex, from = startDate) {
|
|
327
327
|
// let date = startOfWeek(from, locale);
|
|
328
328
|
let date = from.add({weeks: weekIndex});
|
|
329
|
-
let dates = [];
|
|
329
|
+
let dates: (CalendarDate | null)[] = [];
|
|
330
330
|
|
|
331
331
|
date = startOfWeek(date, locale);
|
|
332
332
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import {alignCenter, constrainValue, isInvalid, previousAvailableDate} from './utils';
|
|
14
14
|
import {Calendar, CalendarDate, DateDuration, GregorianCalendar, isEqualDay, maxDate, minDate, toCalendar, toCalendarDate} from '@internationalized/date';
|
|
15
15
|
import {CalendarState, RangeCalendarState} from './types';
|
|
16
|
-
import {
|
|
16
|
+
import {DateValue, RangeCalendarProps} from '@react-types/calendar';
|
|
17
17
|
import {RangeValue, ValidationState} from '@react-types/shared';
|
|
18
18
|
import {useCalendarState} from './useCalendarState';
|
|
19
19
|
import {useControlledState} from '@react-stately/utils';
|
|
@@ -42,13 +42,13 @@ export interface RangeCalendarStateOptions<T extends DateValue = DateValue> exte
|
|
|
42
42
|
*/
|
|
43
43
|
export function useRangeCalendarState<T extends DateValue = DateValue>(props: RangeCalendarStateOptions<T>): RangeCalendarState {
|
|
44
44
|
let {value: valueProp, defaultValue, onChange, createCalendar, locale, visibleDuration = {months: 1}, minValue, maxValue, ...calendarProps} = props;
|
|
45
|
-
let [value, setValue] = useControlledState<
|
|
46
|
-
valueProp
|
|
47
|
-
defaultValue || null
|
|
45
|
+
let [value, setValue] = useControlledState<RangeValue<T> | null, RangeValue<T>>(
|
|
46
|
+
valueProp!,
|
|
47
|
+
defaultValue || null!,
|
|
48
48
|
onChange
|
|
49
49
|
);
|
|
50
50
|
|
|
51
|
-
let [anchorDate, setAnchorDateState] = useState(null);
|
|
51
|
+
let [anchorDate, setAnchorDateState] = useState<CalendarDate | null>(null);
|
|
52
52
|
let alignment: 'center' | 'start' = 'center';
|
|
53
53
|
if (value && value.start && value.end) {
|
|
54
54
|
let start = alignCenter(toCalendarDate(value.start), visibleDuration, locale, minValue, maxValue);
|
|
@@ -60,8 +60,8 @@ export function useRangeCalendarState<T extends DateValue = DateValue>(props: Ra
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
// Available range must be stored in a ref so we have access to the updated version immediately in `isInvalid`.
|
|
63
|
-
let availableRangeRef = useRef<RangeValue<DateValue>>(null);
|
|
64
|
-
let [availableRange, setAvailableRange] = useState<RangeValue<DateValue
|
|
63
|
+
let availableRangeRef = useRef<Partial<RangeValue<DateValue>> | null>(null);
|
|
64
|
+
let [availableRange, setAvailableRange] = useState<Partial<RangeValue<DateValue>>|null>(null);
|
|
65
65
|
let min = useMemo(() => maxDate(minValue, availableRange?.start), [minValue, availableRange]);
|
|
66
66
|
let max = useMemo(() => minDate(maxValue, availableRange?.end), [maxValue, availableRange]);
|
|
67
67
|
|
|
@@ -78,9 +78,11 @@ export function useRangeCalendarState<T extends DateValue = DateValue>(props: Ra
|
|
|
78
78
|
|
|
79
79
|
let updateAvailableRange = (date) => {
|
|
80
80
|
if (date && props.isDateUnavailable && !props.allowsNonContiguousRanges) {
|
|
81
|
+
const nextAvailableStartDate = nextUnavailableDate(date, calendar, -1);
|
|
82
|
+
const nextAvailableEndDate = nextUnavailableDate(date, calendar, 1);
|
|
81
83
|
availableRangeRef.current = {
|
|
82
|
-
start:
|
|
83
|
-
end:
|
|
84
|
+
start: nextAvailableStartDate,
|
|
85
|
+
end: nextAvailableEndDate
|
|
84
86
|
};
|
|
85
87
|
setAvailableRange(availableRangeRef.current);
|
|
86
88
|
} else {
|
|
@@ -96,7 +98,7 @@ export function useRangeCalendarState<T extends DateValue = DateValue>(props: Ra
|
|
|
96
98
|
setLastVisibleRange(calendar.visibleRange);
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
let setAnchorDate = (date: CalendarDate) => {
|
|
101
|
+
let setAnchorDate = (date: CalendarDate | null) => {
|
|
100
102
|
if (date) {
|
|
101
103
|
setAnchorDateState(date);
|
|
102
104
|
updateAvailableRange(date);
|
|
@@ -112,20 +114,22 @@ export function useRangeCalendarState<T extends DateValue = DateValue>(props: Ra
|
|
|
112
114
|
return;
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (!
|
|
117
|
+
const constrainedDate = constrainValue(date, min, max);
|
|
118
|
+
const previousAvailableConstrainedDate = previousAvailableDate(constrainedDate, calendar.visibleRange.start, props.isDateUnavailable);
|
|
119
|
+
if (!previousAvailableConstrainedDate) {
|
|
118
120
|
return;
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
if (!anchorDate) {
|
|
122
|
-
setAnchorDate(
|
|
124
|
+
setAnchorDate(previousAvailableConstrainedDate);
|
|
123
125
|
} else {
|
|
124
|
-
let range = makeRange(anchorDate,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
let range = makeRange(anchorDate, previousAvailableConstrainedDate);
|
|
127
|
+
if (range) {
|
|
128
|
+
setValue({
|
|
129
|
+
start: convertValue(range.start, value?.start) as T,
|
|
130
|
+
end: convertValue(range.end, value?.end) as T
|
|
131
|
+
});
|
|
132
|
+
}
|
|
129
133
|
setAnchorDate(null);
|
|
130
134
|
}
|
|
131
135
|
};
|
|
@@ -146,7 +150,7 @@ export function useRangeCalendarState<T extends DateValue = DateValue>(props: Ra
|
|
|
146
150
|
}, [isDateUnavailable, value, anchorDate, minValue, maxValue]);
|
|
147
151
|
|
|
148
152
|
let isValueInvalid = props.isInvalid || props.validationState === 'invalid' || isInvalidSelection;
|
|
149
|
-
let validationState: ValidationState = isValueInvalid ? 'invalid' : null;
|
|
153
|
+
let validationState: ValidationState | null = isValueInvalid ? 'invalid' : null;
|
|
150
154
|
|
|
151
155
|
return {
|
|
152
156
|
...calendar,
|
|
@@ -167,7 +171,7 @@ export function useRangeCalendarState<T extends DateValue = DateValue>(props: Ra
|
|
|
167
171
|
}
|
|
168
172
|
},
|
|
169
173
|
isSelected(date) {
|
|
170
|
-
return highlightedRange && date.compare(highlightedRange.start) >= 0 && date.compare(highlightedRange.end) <= 0 && !calendar.isCellDisabled(date) && !calendar.isCellUnavailable(date);
|
|
174
|
+
return Boolean(highlightedRange && date.compare(highlightedRange.start) >= 0 && date.compare(highlightedRange.end) <= 0 && !calendar.isCellDisabled(date) && !calendar.isCellUnavailable(date));
|
|
171
175
|
},
|
|
172
176
|
isInvalid(date) {
|
|
173
177
|
return calendar.isInvalid(date) || isInvalid(date, availableRangeRef.current?.start, availableRangeRef.current?.end);
|
|
@@ -177,7 +181,7 @@ export function useRangeCalendarState<T extends DateValue = DateValue>(props: Ra
|
|
|
177
181
|
};
|
|
178
182
|
}
|
|
179
183
|
|
|
180
|
-
function makeRange(start: DateValue, end: DateValue): RangeValue<CalendarDate> {
|
|
184
|
+
function makeRange(start: DateValue, end: DateValue): RangeValue<CalendarDate> | null {
|
|
181
185
|
if (!start || !end) {
|
|
182
186
|
return null;
|
|
183
187
|
}
|
|
@@ -189,7 +193,7 @@ function makeRange(start: DateValue, end: DateValue): RangeValue<CalendarDate> {
|
|
|
189
193
|
return {start: toCalendarDate(start), end: toCalendarDate(end)};
|
|
190
194
|
}
|
|
191
195
|
|
|
192
|
-
function convertValue(newValue: CalendarDate, oldValue
|
|
196
|
+
function convertValue(newValue: CalendarDate, oldValue?: DateValue): DateValue {
|
|
193
197
|
// The display calendar should not have any effect on the emitted value.
|
|
194
198
|
// Emit dates in the same calendar as the original value, if any, otherwise gregorian.
|
|
195
199
|
newValue = toCalendar(newValue, oldValue?.calendar || new GregorianCalendar());
|
|
@@ -202,7 +206,7 @@ function convertValue(newValue: CalendarDate, oldValue: DateValue) {
|
|
|
202
206
|
return newValue;
|
|
203
207
|
}
|
|
204
208
|
|
|
205
|
-
function nextUnavailableDate(anchorDate: CalendarDate, state: CalendarState, dir: number) {
|
|
209
|
+
function nextUnavailableDate(anchorDate: CalendarDate, state: CalendarState, dir: number): CalendarDate | undefined {
|
|
206
210
|
let nextDate = anchorDate.add({days: dir});
|
|
207
211
|
while (
|
|
208
212
|
(dir < 0 ? nextDate.compare(state.visibleRange.start) >= 0 : nextDate.compare(state.visibleRange.end) <= 0) &&
|
|
@@ -215,5 +219,4 @@ function nextUnavailableDate(anchorDate: CalendarDate, state: CalendarState, dir
|
|
|
215
219
|
return nextDate.add({days: -dir});
|
|
216
220
|
}
|
|
217
221
|
|
|
218
|
-
return null;
|
|
219
222
|
}
|
package/src/utils.ts
CHANGED
|
@@ -21,12 +21,12 @@ import {
|
|
|
21
21
|
} from '@internationalized/date';
|
|
22
22
|
import {DateValue} from '@react-types/calendar';
|
|
23
23
|
|
|
24
|
-
export function isInvalid(date: DateValue, minValue
|
|
24
|
+
export function isInvalid(date: DateValue, minValue?: DateValue | null, maxValue?: DateValue | null) {
|
|
25
25
|
return (minValue != null && date.compare(minValue) < 0) ||
|
|
26
26
|
(maxValue != null && date.compare(maxValue) > 0);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export function alignCenter(date: CalendarDate, duration: DateDuration, locale: string, minValue?: DateValue, maxValue?: DateValue) {
|
|
29
|
+
export function alignCenter(date: CalendarDate, duration: DateDuration, locale: string, minValue?: DateValue | null, maxValue?: DateValue | null) {
|
|
30
30
|
let halfDuration: DateDuration = {};
|
|
31
31
|
for (let key in duration) {
|
|
32
32
|
halfDuration[key] = Math.floor(duration[key] / 2);
|
|
@@ -39,7 +39,7 @@ export function alignCenter(date: CalendarDate, duration: DateDuration, locale:
|
|
|
39
39
|
return constrainStart(date, aligned, duration, locale, minValue, maxValue);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export function alignStart(date: CalendarDate, duration: DateDuration, locale: string, minValue?: DateValue, maxValue?: DateValue) {
|
|
42
|
+
export function alignStart(date: CalendarDate, duration: DateDuration, locale: string, minValue?: DateValue | null, maxValue?: DateValue | null) {
|
|
43
43
|
// align to the start of the largest unit
|
|
44
44
|
let aligned = date;
|
|
45
45
|
if (duration.years) {
|
|
@@ -53,16 +53,16 @@ export function alignStart(date: CalendarDate, duration: DateDuration, locale: s
|
|
|
53
53
|
return constrainStart(date, aligned, duration, locale, minValue, maxValue);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
export function alignEnd(date: CalendarDate, duration: DateDuration, locale: string, minValue?: DateValue, maxValue?: DateValue) {
|
|
56
|
+
export function alignEnd(date: CalendarDate, duration: DateDuration, locale: string, minValue?: DateValue | null, maxValue?: DateValue | null) {
|
|
57
57
|
let d = {...duration};
|
|
58
58
|
// subtract 1 from the smallest unit
|
|
59
|
-
if (
|
|
59
|
+
if (d.days) {
|
|
60
60
|
d.days--;
|
|
61
|
-
} else if (
|
|
61
|
+
} else if (d.weeks) {
|
|
62
62
|
d.weeks--;
|
|
63
|
-
} else if (
|
|
63
|
+
} else if (d.months) {
|
|
64
64
|
d.months--;
|
|
65
|
-
} else if (
|
|
65
|
+
} else if (d.years) {
|
|
66
66
|
d.years--;
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -75,38 +75,50 @@ export function constrainStart(
|
|
|
75
75
|
aligned: CalendarDate,
|
|
76
76
|
duration: DateDuration,
|
|
77
77
|
locale: string,
|
|
78
|
-
minValue
|
|
79
|
-
maxValue
|
|
78
|
+
minValue?: DateValue | null,
|
|
79
|
+
maxValue?: DateValue | null) {
|
|
80
80
|
if (minValue && date.compare(minValue) >= 0) {
|
|
81
|
-
|
|
81
|
+
let newDate = maxDate(
|
|
82
82
|
aligned,
|
|
83
83
|
alignStart(toCalendarDate(minValue), duration, locale)
|
|
84
84
|
);
|
|
85
|
+
if (newDate) {
|
|
86
|
+
aligned = newDate;
|
|
87
|
+
}
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
if (maxValue && date.compare(maxValue) <= 0) {
|
|
88
|
-
|
|
91
|
+
let newDate = minDate(
|
|
89
92
|
aligned,
|
|
90
93
|
alignEnd(toCalendarDate(maxValue), duration, locale)
|
|
91
94
|
);
|
|
95
|
+
if (newDate) {
|
|
96
|
+
aligned = newDate;
|
|
97
|
+
}
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
return aligned;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
export function constrainValue(date: CalendarDate, minValue
|
|
103
|
+
export function constrainValue(date: CalendarDate, minValue?: DateValue | null, maxValue?: DateValue | null) {
|
|
98
104
|
if (minValue) {
|
|
99
|
-
|
|
105
|
+
let newDate = maxDate(date, toCalendarDate(minValue));
|
|
106
|
+
if (newDate) {
|
|
107
|
+
date = newDate;
|
|
108
|
+
}
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
if (maxValue) {
|
|
103
|
-
|
|
112
|
+
let newDate = minDate(date, toCalendarDate(maxValue));
|
|
113
|
+
if (newDate) {
|
|
114
|
+
date = newDate;
|
|
115
|
+
}
|
|
104
116
|
}
|
|
105
117
|
|
|
106
118
|
return date;
|
|
107
119
|
}
|
|
108
120
|
|
|
109
|
-
export function previousAvailableDate(date: CalendarDate, minValue: DateValue, isDateUnavailable
|
|
121
|
+
export function previousAvailableDate(date: CalendarDate, minValue: DateValue, isDateUnavailable?: (date: CalendarDate) => boolean): CalendarDate | null {
|
|
110
122
|
if (!isDateUnavailable) {
|
|
111
123
|
return date;
|
|
112
124
|
}
|
|
@@ -118,4 +130,5 @@ export function previousAvailableDate(date: CalendarDate, minValue: DateValue, i
|
|
|
118
130
|
if (date.compare(minValue) >= 0) {
|
|
119
131
|
return date;
|
|
120
132
|
}
|
|
133
|
+
return null;
|
|
121
134
|
}
|