@react-stately/datepicker 3.5.0 → 3.7.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.
@@ -53,8 +53,13 @@ export interface DatePickerState extends OverlayTriggerState {
53
53
  isOpen: boolean,
54
54
  /** Sets whether the calendar popover is open. */
55
55
  setOpen(isOpen: boolean): void,
56
- /** The current validation state of the date picker, based on the `validationState`, `minValue`, and `maxValue` props. */
56
+ /**
57
+ * The current validation state of the date picker, based on the `validationState`, `minValue`, and `maxValue` props.
58
+ * @deprecated Use `isInvalid` instead.
59
+ */
57
60
  validationState: ValidationState,
61
+ /** Whether the date picker is invalid, based on the `isInvalid`, `minValue`, and `maxValue` props. */
62
+ isInvalid: boolean,
58
63
  /** Formats the selected value using the given options. */
59
64
  formatValue(locale: string, fieldOptions: FieldOptions): string
60
65
  }
@@ -120,9 +125,10 @@ export function useDatePickerState<T extends DateValue = DateValue>(props: DateP
120
125
  }
121
126
  };
122
127
 
123
- let validationState: ValidationState = props.validationState ||
124
- (isInvalid(value, props.minValue, props.maxValue) ? 'invalid' : null) ||
125
- (value && props.isDateUnavailable?.(value) ? 'invalid' : null);
128
+ let isValueInvalid = props.isInvalid || props.validationState === 'invalid' ||
129
+ isInvalid(value, props.minValue, props.maxValue) ||
130
+ value && props.isDateUnavailable?.(value);
131
+ let validationState: ValidationState = props.validationState || (isValueInvalid ? 'invalid' : null);
126
132
 
127
133
  return {
128
134
  value,
@@ -145,6 +151,7 @@ export function useDatePickerState<T extends DateValue = DateValue>(props: DateP
145
151
  overlayState.setOpen(isOpen);
146
152
  },
147
153
  validationState,
154
+ isInvalid: isValueInvalid,
148
155
  formatValue(locale, fieldOptions) {
149
156
  if (!dateValue) {
150
157
  return '';
@@ -60,8 +60,13 @@ export interface DateRangePickerState extends OverlayTriggerState {
60
60
  isOpen: boolean,
61
61
  /** Sets whether the calendar popover is open. */
62
62
  setOpen(isOpen: boolean): void,
63
- /** The current validation state of the date picker, based on the `validationState`, `minValue`, and `maxValue` props. */
63
+ /**
64
+ * The current validation state of the date range picker, based on the `validationState`, `minValue`, and `maxValue` props.
65
+ * @deprecated Use `isInvalid` instead.
66
+ */
64
67
  validationState: ValidationState,
68
+ /** Whether the date range picker is invalid, based on the `isInvalid`, `minValue`, and `maxValue` props. */
69
+ isInvalid: boolean,
65
70
  /** Formats the selected range using the given options. */
66
71
  formatValue(locale: string, fieldOptions: FieldOptions): {start: string, end: string}
67
72
  }
@@ -148,14 +153,15 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
148
153
  }
149
154
  };
150
155
 
151
- let validationState: ValidationState = props.validationState
156
+ let isValueInvalid = props.isInvalid || props.validationState === 'invalid'
152
157
  || (value != null && (
153
158
  isInvalid(value.start, props.minValue, props.maxValue) ||
154
159
  isInvalid(value.end, props.minValue, props.maxValue) ||
155
160
  (value.end != null && value.start != null && value.end.compare(value.start) < 0) ||
156
161
  (value?.start && props.isDateUnavailable?.(value.start)) ||
157
162
  (value?.end && props.isDateUnavailable?.(value.end))
158
- ) ? 'invalid' : null);
163
+ ));
164
+ let validationState: ValidationState = props.validationState || (isValueInvalid ? 'invalid' : null);
159
165
 
160
166
  return {
161
167
  value,
@@ -190,6 +196,7 @@ export function useDateRangePickerState<T extends DateValue = DateValue>(props:
190
196
  overlayState.setOpen(isOpen);
191
197
  },
192
198
  validationState,
199
+ isInvalid: isValueInvalid,
193
200
  formatValue(locale, fieldOptions) {
194
201
  if (!value || !value.start || !value.end) {
195
202
  return null;
@@ -12,7 +12,7 @@
12
12
 
13
13
  import {DateFieldState, useDateFieldState} from '.';
14
14
  import {DateValue, TimePickerProps, TimeValue} from '@react-types/datepicker';
15
- import {getLocalTimeZone, GregorianCalendar, Time, toCalendarDateTime, today, toTime} from '@internationalized/date';
15
+ import {getLocalTimeZone, GregorianCalendar, Time, toCalendarDateTime, today, toTime, toZoned} from '@internationalized/date';
16
16
  import {useControlledState} from '@react-stately/utils';
17
17
  import {useMemo} from 'react';
18
18
 
@@ -21,12 +21,17 @@ export interface TimeFieldStateOptions<T extends TimeValue = TimeValue> extends
21
21
  locale: string
22
22
  }
23
23
 
24
+ export interface TimeFieldState extends DateFieldState {
25
+ /** The current time value. */
26
+ timeValue: Time
27
+ }
28
+
24
29
  /**
25
30
  * Provides state management for a time field component.
26
31
  * A time field allows users to enter and edit time values using a keyboard.
27
32
  * Each part of a time value is displayed in an individually editable segment.
28
33
  */
29
- export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFieldStateOptions<T>): DateFieldState {
34
+ export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFieldStateOptions<T>): TimeFieldState {
30
35
  let {
31
36
  placeholderValue = new Time(),
32
37
  minValue,
@@ -42,16 +47,22 @@ export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFi
42
47
 
43
48
  let v = value || placeholderValue;
44
49
  let day = v && 'day' in v ? v : undefined;
45
- let placeholderDate = useMemo(() => convertValue(placeholderValue), [placeholderValue]);
50
+ let defaultValueTimeZone = props.defaultValue && 'timeZone' in props.defaultValue ? props.defaultValue.timeZone : undefined;
51
+ let placeholderDate = useMemo(() => {
52
+ let valueTimeZone = v && 'timeZone' in v ? v.timeZone : undefined;
53
+
54
+ return (valueTimeZone || defaultValueTimeZone) && placeholderValue ? toZoned(convertValue(placeholderValue), valueTimeZone || defaultValueTimeZone) : convertValue(placeholderValue);
55
+ }, [placeholderValue, v, defaultValueTimeZone]);
46
56
  let minDate = useMemo(() => convertValue(minValue, day), [minValue, day]);
47
57
  let maxDate = useMemo(() => convertValue(maxValue, day), [maxValue, day]);
48
58
 
59
+ let timeValue = useMemo(() => value && 'day' in value ? toTime(value) : value as Time, [value]);
49
60
  let dateTime = useMemo(() => value == null ? null : convertValue(value), [value]);
50
61
  let onChange = newValue => {
51
- setValue(v && 'day' in v ? newValue : newValue && toTime(newValue));
62
+ setValue(day || defaultValueTimeZone ? newValue : newValue && toTime(newValue));
52
63
  };
53
64
 
54
- return useDateFieldState({
65
+ let state = useDateFieldState({
55
66
  ...props,
56
67
  value: dateTime,
57
68
  defaultValue: undefined,
@@ -64,6 +75,11 @@ export function useTimeFieldState<T extends TimeValue = TimeValue>(props: TimeFi
64
75
  // Calendar should not matter for time fields.
65
76
  createCalendar: () => new GregorianCalendar()
66
77
  });
78
+
79
+ return {
80
+ ...state,
81
+ timeValue
82
+ };
67
83
  }
68
84
 
69
85
  function convertValue(value: TimeValue, date: DateValue = today(getLocalTimeZone())) {