@react-stately/datepicker 3.10.3 → 3.11.0
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/LICENSE +201 -0
- package/dist/types.d.ts +16 -16
- package/dist/types.d.ts.map +1 -1
- package/dist/useDateFieldState.main.js +12 -6
- package/dist/useDateFieldState.main.js.map +1 -1
- package/dist/useDateFieldState.mjs +12 -6
- package/dist/useDateFieldState.module.js +12 -6
- package/dist/useDateFieldState.module.js.map +1 -1
- package/dist/useDatePickerState.main.js +3 -3
- package/dist/useDatePickerState.main.js.map +1 -1
- package/dist/useDatePickerState.mjs +3 -3
- package/dist/useDatePickerState.module.js +3 -3
- package/dist/useDatePickerState.module.js.map +1 -1
- package/dist/useDateRangePickerState.main.js +36 -18
- package/dist/useDateRangePickerState.main.js.map +1 -1
- package/dist/useDateRangePickerState.mjs +36 -18
- package/dist/useDateRangePickerState.module.js +36 -18
- package/dist/useDateRangePickerState.module.js.map +1 -1
- package/dist/useTimeFieldState.main.js +3 -2
- package/dist/useTimeFieldState.main.js.map +1 -1
- package/dist/useTimeFieldState.mjs +3 -2
- package/dist/useTimeFieldState.module.js +3 -2
- package/dist/useTimeFieldState.module.js.map +1 -1
- package/dist/utils.main.js +8 -6
- package/dist/utils.main.js.map +1 -1
- package/dist/utils.mjs +9 -7
- package/dist/utils.module.js +9 -7
- package/dist/utils.module.js.map +1 -1
- package/package.json +12 -11
- package/src/useDateFieldState.ts +21 -17
- package/src/useDatePickerState.ts +13 -13
- package/src/useDateRangePickerState.ts +46 -30
- package/src/useTimeFieldState.ts +6 -6
- package/src/utils.ts +22 -22
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
import {DateFormatter, toCalendarDate, toCalendarDateTime} from '@internationalized/date';
|
|
15
|
-
import {DateRange, DateRangePickerProps, DateValue, Granularity, TimeValue} from '@react-types/datepicker';
|
|
15
|
+
import {DateRange, DateRangePickerProps, DateValue, Granularity, MappedDateValue, TimeValue} from '@react-types/datepicker';
|
|
16
16
|
import {FieldOptions, FormatterOptions, getFormatOptions, getPlaceholderTime, getRangeValidationResult, useDefaultProps} from './utils';
|
|
17
17
|
import {FormValidationState, useFormValidationState} from '@react-stately/form';
|
|
18
18
|
import {OverlayTriggerState, useOverlayTriggerState} from '@react-stately/overlays';
|
|
@@ -31,29 +31,29 @@ export interface DateRangePickerStateOptions<T extends DateValue = DateValue> ex
|
|
|
31
31
|
type TimeRange = RangeValue<TimeValue>;
|
|
32
32
|
export interface DateRangePickerState extends OverlayTriggerState, FormValidationState {
|
|
33
33
|
/** The currently selected date range. */
|
|
34
|
-
value:
|
|
34
|
+
value: RangeValue<DateValue | null>,
|
|
35
35
|
/** Sets the selected date range. */
|
|
36
36
|
setValue(value: DateRange | null): void,
|
|
37
37
|
/**
|
|
38
38
|
* The date portion of the selected range. This may be set prior to `value` if the user has
|
|
39
39
|
* selected a date range but has not yet selected a time range.
|
|
40
40
|
*/
|
|
41
|
-
dateRange:
|
|
41
|
+
dateRange: RangeValue<DateValue | null> | null,
|
|
42
42
|
/** Sets the date portion of the selected range. */
|
|
43
43
|
setDateRange(value: DateRange): void,
|
|
44
44
|
/**
|
|
45
45
|
* The time portion of the selected range. This may be set prior to `value` if the user has
|
|
46
46
|
* selected a time range but has not yet selected a date range.
|
|
47
47
|
*/
|
|
48
|
-
timeRange:
|
|
48
|
+
timeRange: RangeValue<TimeValue | null> | null,
|
|
49
49
|
/** Sets the time portion of the selected range. */
|
|
50
50
|
setTimeRange(value: TimeRange): void,
|
|
51
51
|
/** Sets the date portion of either the start or end of the selected range. */
|
|
52
|
-
setDate(part: 'start' | 'end', value: DateValue): void,
|
|
52
|
+
setDate(part: 'start' | 'end', value: DateValue | null): void,
|
|
53
53
|
/** Sets the time portion of either the start or end of the selected range. */
|
|
54
|
-
setTime(part: 'start' | 'end', value: TimeValue): void,
|
|
54
|
+
setTime(part: 'start' | 'end', value: TimeValue | null): void,
|
|
55
55
|
/** Sets the date and time of either the start or end of the selected range. */
|
|
56
|
-
setDateTime(part: 'start' | 'end', value: DateValue): void,
|
|
56
|
+
setDateTime(part: 'start' | 'end', value: DateValue | null): void,
|
|
57
57
|
/** The granularity for the field, based on the `granularity` prop and current value. */
|
|
58
58
|
granularity: Granularity,
|
|
59
59
|
/** Whether the date range picker supports selecting times, according to the `granularity` prop and current value. */
|
|
@@ -66,11 +66,11 @@ export interface DateRangePickerState extends OverlayTriggerState, FormValidatio
|
|
|
66
66
|
* The current validation state of the date range picker, based on the `validationState`, `minValue`, and `maxValue` props.
|
|
67
67
|
* @deprecated Use `isInvalid` instead.
|
|
68
68
|
*/
|
|
69
|
-
validationState: ValidationState,
|
|
69
|
+
validationState: ValidationState | null,
|
|
70
70
|
/** Whether the date range picker is invalid, based on the `isInvalid`, `minValue`, and `maxValue` props. */
|
|
71
71
|
isInvalid: boolean,
|
|
72
72
|
/** Formats the selected range using the given options. */
|
|
73
|
-
formatValue(locale: string, fieldOptions: FieldOptions): {start: string, end: string},
|
|
73
|
+
formatValue(locale: string, fieldOptions: FieldOptions): {start: string, end: string} | null,
|
|
74
74
|
/** Gets a formatter based on state's props. */
|
|
75
75
|
getDateFormatter(locale: string, formatOptions: FormatterOptions): DateFormatter
|
|
76
76
|
}
|
|
@@ -82,8 +82,8 @@ export interface DateRangePickerState extends OverlayTriggerState, FormValidatio
|
|
|
82
82
|
*/
|
|
83
83
|
export function useDateRangePickerState<T extends DateValue = DateValue>(props: DateRangePickerStateOptions<T>): DateRangePickerState {
|
|
84
84
|
let overlayState = useOverlayTriggerState(props);
|
|
85
|
-
let [controlledValue, setControlledValue] = useControlledState<DateRange>(props.value, props.defaultValue || null, props.onChange);
|
|
86
|
-
let [placeholderValue, setPlaceholderValue] = useState(() => controlledValue || {start: null, end: null});
|
|
85
|
+
let [controlledValue, setControlledValue] = useControlledState<DateRange | null, RangeValue<MappedDateValue<T>> | null>(props.value, props.defaultValue || null, props.onChange);
|
|
86
|
+
let [placeholderValue, setPlaceholderValue] = useState<RangeValue<DateValue | null>>(() => controlledValue || {start: null, end: null});
|
|
87
87
|
|
|
88
88
|
// Reset the placeholder if the value prop is set to null.
|
|
89
89
|
if (controlledValue == null && placeholderValue.start && placeholderValue.end) {
|
|
@@ -93,24 +93,24 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
93
93
|
|
|
94
94
|
let value = controlledValue || placeholderValue;
|
|
95
95
|
|
|
96
|
-
let setValue = (value:
|
|
96
|
+
let setValue = (value: RangeValue<DateValue | null> | null) => {
|
|
97
97
|
setPlaceholderValue(value || {start: null, end: null});
|
|
98
|
-
if (value
|
|
98
|
+
if (isCompleteRange(value)) {
|
|
99
99
|
setControlledValue(value);
|
|
100
100
|
} else {
|
|
101
101
|
setControlledValue(null);
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
-
let v = (value?.start || value?.end || props.placeholderValue);
|
|
105
|
+
let v = (value?.start || value?.end || props.placeholderValue || null);
|
|
106
106
|
let [granularity, defaultTimeZone] = useDefaultProps(v, props.granularity);
|
|
107
107
|
let hasTime = granularity === 'hour' || granularity === 'minute' || granularity === 'second';
|
|
108
108
|
let shouldCloseOnSelect = props.shouldCloseOnSelect ?? true;
|
|
109
109
|
|
|
110
|
-
let [dateRange, setSelectedDateRange] = useState<
|
|
111
|
-
let [timeRange, setSelectedTimeRange] = useState<
|
|
110
|
+
let [dateRange, setSelectedDateRange] = useState<RangeValue<DateValue | null> | null>(null);
|
|
111
|
+
let [timeRange, setSelectedTimeRange] = useState<RangeValue<TimeValue | null> | null>(null);
|
|
112
112
|
|
|
113
|
-
if (value && value
|
|
113
|
+
if (value && isCompleteRange(value)) {
|
|
114
114
|
dateRange = value;
|
|
115
115
|
if ('hour' in value.start) {
|
|
116
116
|
timeRange = value as TimeRange;
|
|
@@ -128,10 +128,10 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
// Intercept setValue to make sure the Time section is not changed by date selection in Calendar
|
|
131
|
-
let setDateRange = (range:
|
|
131
|
+
let setDateRange = (range: RangeValue<DateValue | null>) => {
|
|
132
132
|
let shouldClose = typeof shouldCloseOnSelect === 'function' ? shouldCloseOnSelect() : shouldCloseOnSelect;
|
|
133
133
|
if (hasTime) {
|
|
134
|
-
if (
|
|
134
|
+
if (isCompleteRange(range) && timeRange?.start && timeRange?.end) {
|
|
135
135
|
commitValue(range, {
|
|
136
136
|
start: timeRange?.start || getPlaceholderTime(props.placeholderValue),
|
|
137
137
|
end: timeRange?.end || getPlaceholderTime(props.placeholderValue)
|
|
@@ -139,7 +139,7 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
139
139
|
} else {
|
|
140
140
|
setSelectedDateRange(range);
|
|
141
141
|
}
|
|
142
|
-
} else if (range
|
|
142
|
+
} else if (isCompleteRange(range)) {
|
|
143
143
|
setValue(range);
|
|
144
144
|
validation.commitValidation();
|
|
145
145
|
} else {
|
|
@@ -151,8 +151,8 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
-
let setTimeRange = (range:
|
|
155
|
-
if (dateRange
|
|
154
|
+
let setTimeRange = (range: RangeValue<TimeValue | null>) => {
|
|
155
|
+
if (isCompleteRange(dateRange) && isCompleteRange(range)) {
|
|
156
156
|
commitValue(dateRange, range);
|
|
157
157
|
} else {
|
|
158
158
|
setSelectedTimeRange(range);
|
|
@@ -180,13 +180,13 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
180
180
|
|
|
181
181
|
let validation = useFormValidationState({
|
|
182
182
|
...props,
|
|
183
|
-
value: controlledValue,
|
|
184
|
-
name: useMemo(() => [props.startName, props.endName], [props.startName, props.endName]),
|
|
183
|
+
value: controlledValue as RangeValue<MappedDateValue<T>> | null,
|
|
184
|
+
name: useMemo(() => [props.startName, props.endName].filter(n => n != null), [props.startName, props.endName]),
|
|
185
185
|
builtinValidation
|
|
186
186
|
});
|
|
187
187
|
|
|
188
188
|
let isValueInvalid = validation.displayValidation.isInvalid;
|
|
189
|
-
let validationState: ValidationState = props.validationState || (isValueInvalid ? 'invalid' : null);
|
|
189
|
+
let validationState: ValidationState | null = props.validationState || (isValueInvalid ? 'invalid' : null);
|
|
190
190
|
|
|
191
191
|
return {
|
|
192
192
|
...validation,
|
|
@@ -197,13 +197,25 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
197
197
|
granularity,
|
|
198
198
|
hasTime,
|
|
199
199
|
setDate(part, date) {
|
|
200
|
-
|
|
200
|
+
if (part === 'start') {
|
|
201
|
+
setDateRange({start: date, end: dateRange?.end ?? null});
|
|
202
|
+
} else {
|
|
203
|
+
setDateRange({start: dateRange?.start ?? null, end: date});
|
|
204
|
+
}
|
|
201
205
|
},
|
|
202
206
|
setTime(part, time) {
|
|
203
|
-
|
|
207
|
+
if (part === 'start') {
|
|
208
|
+
setTimeRange({start: time, end: timeRange?.end ?? null});
|
|
209
|
+
} else {
|
|
210
|
+
setTimeRange({start: timeRange?.start ?? null, end: time});
|
|
211
|
+
}
|
|
204
212
|
},
|
|
205
213
|
setDateTime(part, dateTime) {
|
|
206
|
-
|
|
214
|
+
if (part === 'start') {
|
|
215
|
+
setValue({start: dateTime, end: value?.end ?? null});
|
|
216
|
+
} else {
|
|
217
|
+
setValue({start: value?.start ?? null, end: dateTime});
|
|
218
|
+
}
|
|
207
219
|
},
|
|
208
220
|
setDateRange,
|
|
209
221
|
setTimeRange,
|
|
@@ -212,7 +224,7 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
212
224
|
// Commit the selected date range when the calendar is closed. Use a placeholder time if one wasn't set.
|
|
213
225
|
// If only the time range was set and not the date range, don't commit. The state will be preserved until
|
|
214
226
|
// the user opens the popover again.
|
|
215
|
-
if (!isOpen && !(value?.start && value?.end) && dateRange
|
|
227
|
+
if (!isOpen && !(value?.start && value?.end) && isCompleteRange(dateRange) && hasTime) {
|
|
216
228
|
commitValue(dateRange, {
|
|
217
229
|
start: timeRange?.start || getPlaceholderTime(props.placeholderValue),
|
|
218
230
|
end: timeRange?.end || getPlaceholderTime(props.placeholderValue)
|
|
@@ -278,7 +290,7 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
278
290
|
}
|
|
279
291
|
|
|
280
292
|
return {start, end};
|
|
281
|
-
} catch
|
|
293
|
+
} catch {
|
|
282
294
|
// ignore
|
|
283
295
|
}
|
|
284
296
|
|
|
@@ -306,3 +318,7 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
|
|
|
306
318
|
}
|
|
307
319
|
};
|
|
308
320
|
}
|
|
321
|
+
|
|
322
|
+
function isCompleteRange<T>(value: RangeValue<T | null> | null): value is RangeValue<T> {
|
|
323
|
+
return value?.start != null && value.end != null;
|
|
324
|
+
}
|
package/src/useTimeFieldState.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {DateFieldState, useDateFieldState} from '.';
|
|
14
|
-
import {DateValue, TimePickerProps, TimeValue} from '@react-types/datepicker';
|
|
14
|
+
import {DateValue, MappedTimeValue, TimePickerProps, TimeValue} from '@react-types/datepicker';
|
|
15
15
|
import {getLocalTimeZone, GregorianCalendar, Time, toCalendarDateTime, today, toTime, toZoned} from '@internationalized/date';
|
|
16
16
|
import {useCallback, useMemo} from 'react';
|
|
17
17
|
import {useControlledState} from '@react-stately/utils';
|
|
@@ -40,9 +40,9 @@ export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFi
|
|
|
40
40
|
validate
|
|
41
41
|
} = props;
|
|
42
42
|
|
|
43
|
-
let [value, setValue] = useControlledState<TimeValue>(
|
|
43
|
+
let [value, setValue] = useControlledState<TimeValue | null, MappedTimeValue<T> | null>(
|
|
44
44
|
props.value,
|
|
45
|
-
props.defaultValue,
|
|
45
|
+
props.defaultValue ?? null,
|
|
46
46
|
props.onChange
|
|
47
47
|
);
|
|
48
48
|
|
|
@@ -52,7 +52,7 @@ export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFi
|
|
|
52
52
|
let placeholderDate = useMemo(() => {
|
|
53
53
|
let valueTimeZone = v && 'timeZone' in v ? v.timeZone : undefined;
|
|
54
54
|
|
|
55
|
-
return (valueTimeZone || defaultValueTimeZone) && placeholderValue ? toZoned(convertValue(placeholderValue)
|
|
55
|
+
return (valueTimeZone || defaultValueTimeZone) && placeholderValue ? toZoned(convertValue(placeholderValue)!, valueTimeZone || defaultValueTimeZone!) : convertValue(placeholderValue);
|
|
56
56
|
}, [placeholderValue, v, defaultValueTimeZone]);
|
|
57
57
|
let minDate = useMemo(() => convertValue(minValue, day), [minValue, day]);
|
|
58
58
|
let maxDate = useMemo(() => convertValue(maxValue, day), [maxValue, day]);
|
|
@@ -72,7 +72,7 @@ export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFi
|
|
|
72
72
|
onChange,
|
|
73
73
|
granularity: granularity || 'minute',
|
|
74
74
|
maxGranularity: 'hour',
|
|
75
|
-
placeholderValue: placeholderDate,
|
|
75
|
+
placeholderValue: placeholderDate ?? undefined,
|
|
76
76
|
// Calendar should not matter for time fields.
|
|
77
77
|
createCalendar: () => new GregorianCalendar(),
|
|
78
78
|
validate: useCallback(() => validate?.(value as any), [validate, value])
|
|
@@ -84,7 +84,7 @@ export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFi
|
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
function convertValue(value: TimeValue, date: DateValue = today(getLocalTimeZone())) {
|
|
87
|
+
function convertValue(value: TimeValue | null | undefined, date: DateValue = today(getLocalTimeZone())) {
|
|
88
88
|
if (!value) {
|
|
89
89
|
return null;
|
|
90
90
|
}
|
package/src/utils.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {Calendar, DateFormatter, now, Time, toCalendar, toCalendarDate, toCalendarDateTime} from '@internationalized/date';
|
|
13
|
+
import {Calendar, DateFormatter, getLocalTimeZone, now, Time, toCalendar, toCalendarDate, toCalendarDateTime} from '@internationalized/date';
|
|
14
14
|
import {DatePickerProps, DateValue, Granularity, TimeValue} from '@react-types/datepicker';
|
|
15
15
|
// @ts-ignore
|
|
16
16
|
import i18nMessages from '../intl/*.json';
|
|
@@ -29,17 +29,17 @@ function getLocale() {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export function getValidationResult(
|
|
32
|
-
value: DateValue,
|
|
33
|
-
minValue: DateValue,
|
|
34
|
-
maxValue: DateValue,
|
|
35
|
-
isDateUnavailable: (v: DateValue) => boolean,
|
|
32
|
+
value: DateValue | null,
|
|
33
|
+
minValue: DateValue | null | undefined,
|
|
34
|
+
maxValue: DateValue | null | undefined,
|
|
35
|
+
isDateUnavailable: ((v: DateValue) => boolean) | undefined,
|
|
36
36
|
options: FormatterOptions
|
|
37
37
|
): ValidationResult {
|
|
38
38
|
let rangeOverflow = value != null && maxValue != null && value.compare(maxValue) > 0;
|
|
39
39
|
let rangeUnderflow = value != null && minValue != null && value.compare(minValue) < 0;
|
|
40
40
|
let isUnavailable = (value != null && isDateUnavailable?.(value)) || false;
|
|
41
41
|
let isInvalid = rangeOverflow || rangeUnderflow || isUnavailable;
|
|
42
|
-
let errors = [];
|
|
42
|
+
let errors: string[] = [];
|
|
43
43
|
|
|
44
44
|
if (isInvalid) {
|
|
45
45
|
let locale = getLocale();
|
|
@@ -48,11 +48,11 @@ export function getValidationResult(
|
|
|
48
48
|
let dateFormatter = new DateFormatter(locale, getFormatOptions({}, options));
|
|
49
49
|
let timeZone = dateFormatter.resolvedOptions().timeZone;
|
|
50
50
|
|
|
51
|
-
if (rangeUnderflow) {
|
|
51
|
+
if (rangeUnderflow && minValue != null) {
|
|
52
52
|
errors.push(formatter.format('rangeUnderflow', {minValue: dateFormatter.format(minValue.toDate(timeZone))}));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
if (rangeOverflow) {
|
|
55
|
+
if (rangeOverflow && maxValue != null) {
|
|
56
56
|
errors.push(formatter.format('rangeOverflow', {maxValue: dateFormatter.format(maxValue.toDate(timeZone))}));
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -81,14 +81,14 @@ export function getValidationResult(
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
export function getRangeValidationResult(
|
|
84
|
-
value: RangeValue<DateValue
|
|
85
|
-
minValue: DateValue,
|
|
86
|
-
maxValue: DateValue,
|
|
87
|
-
isDateUnavailable: (v: DateValue) => boolean,
|
|
84
|
+
value: RangeValue<DateValue | null> | null,
|
|
85
|
+
minValue: DateValue | null | undefined,
|
|
86
|
+
maxValue: DateValue | null | undefined,
|
|
87
|
+
isDateUnavailable: ((v: DateValue) => boolean) | undefined,
|
|
88
88
|
options: FormatterOptions
|
|
89
89
|
) {
|
|
90
90
|
let startValidation = getValidationResult(
|
|
91
|
-
value?.start,
|
|
91
|
+
value?.start ?? null,
|
|
92
92
|
minValue,
|
|
93
93
|
maxValue,
|
|
94
94
|
isDateUnavailable,
|
|
@@ -96,7 +96,7 @@ export function getRangeValidationResult(
|
|
|
96
96
|
);
|
|
97
97
|
|
|
98
98
|
let endValidation = getValidationResult(
|
|
99
|
-
value?.end,
|
|
99
|
+
value?.end ?? null,
|
|
100
100
|
minValue,
|
|
101
101
|
maxValue,
|
|
102
102
|
isDateUnavailable,
|
|
@@ -104,7 +104,7 @@ export function getRangeValidationResult(
|
|
|
104
104
|
);
|
|
105
105
|
|
|
106
106
|
let result = mergeValidation(startValidation, endValidation);
|
|
107
|
-
if (value
|
|
107
|
+
if (value?.end != null && value.start != null && value.end.compare(value.start) < 0) {
|
|
108
108
|
let strings = LocalizedStringDictionary.getGlobalDictionaryForPackage('@react-stately/datepicker') || dictionary;
|
|
109
109
|
result = mergeValidation(result, {
|
|
110
110
|
isInvalid: true,
|
|
@@ -195,7 +195,7 @@ export function getFormatOptions(
|
|
|
195
195
|
return opts;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
export function getPlaceholderTime(placeholderValue: DateValue): TimeValue {
|
|
198
|
+
export function getPlaceholderTime(placeholderValue: DateValue | null | undefined): TimeValue {
|
|
199
199
|
if (placeholderValue && 'hour' in placeholderValue) {
|
|
200
200
|
return placeholderValue;
|
|
201
201
|
}
|
|
@@ -203,7 +203,7 @@ export function getPlaceholderTime(placeholderValue: DateValue): TimeValue {
|
|
|
203
203
|
return new Time();
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
export function convertValue(value: DateValue, calendar: Calendar): DateValue {
|
|
206
|
+
export function convertValue(value: DateValue | null | undefined, calendar: Calendar): DateValue | null | undefined {
|
|
207
207
|
if (value === null) {
|
|
208
208
|
return null;
|
|
209
209
|
}
|
|
@@ -216,12 +216,12 @@ export function convertValue(value: DateValue, calendar: Calendar): DateValue {
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
|
|
219
|
-
export function createPlaceholderDate(placeholderValue: DateValue, granularity: string, calendar: Calendar, timeZone: string) {
|
|
219
|
+
export function createPlaceholderDate(placeholderValue: DateValue | null | undefined, granularity: string, calendar: Calendar, timeZone: string | undefined): DateValue {
|
|
220
220
|
if (placeholderValue) {
|
|
221
|
-
return convertValue(placeholderValue, calendar)
|
|
221
|
+
return convertValue(placeholderValue, calendar)!;
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
let date = toCalendar(now(timeZone).set({
|
|
224
|
+
let date = toCalendar(now(timeZone ?? getLocalTimeZone()).set({
|
|
225
225
|
hour: 0,
|
|
226
226
|
minute: 0,
|
|
227
227
|
second: 0,
|
|
@@ -239,7 +239,7 @@ export function createPlaceholderDate(placeholderValue: DateValue, granularity:
|
|
|
239
239
|
return date;
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
export function useDefaultProps(v: DateValue, granularity: Granularity): [Granularity, string] {
|
|
242
|
+
export function useDefaultProps(v: DateValue | null, granularity: Granularity | undefined): [Granularity, string | undefined] {
|
|
243
243
|
// Compute default granularity and time zone from the value. If the value becomes null, keep the last values.
|
|
244
244
|
let defaultTimeZone = (v && 'timeZone' in v ? v.timeZone : undefined);
|
|
245
245
|
let defaultGranularity: Granularity = (v && 'minute' in v ? 'minute' : 'day');
|
|
@@ -249,7 +249,7 @@ export function useDefaultProps(v: DateValue, granularity: Granularity): [Granul
|
|
|
249
249
|
throw new Error('Invalid granularity ' + granularity + ' for value ' + v.toString());
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
let [lastValue, setLastValue] = useState<[Granularity, string]>([defaultGranularity, defaultTimeZone]);
|
|
252
|
+
let [lastValue, setLastValue] = useState<[Granularity, string | undefined]>([defaultGranularity, defaultTimeZone]);
|
|
253
253
|
|
|
254
254
|
// If the granularity or time zone changed, update the last value.
|
|
255
255
|
if (v && (lastValue[0] !== defaultGranularity || lastValue[1] !== defaultTimeZone)) {
|