@react-aria/datepicker 3.11.3 → 3.12.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.
Files changed (101) hide show
  1. package/LICENSE +201 -0
  2. package/dist/ar-AE.main.js.map +1 -1
  3. package/dist/ar-AE.module.js.map +1 -1
  4. package/dist/bg-BG.main.js.map +1 -1
  5. package/dist/bg-BG.module.js.map +1 -1
  6. package/dist/cs-CZ.main.js.map +1 -1
  7. package/dist/cs-CZ.module.js.map +1 -1
  8. package/dist/da-DK.main.js.map +1 -1
  9. package/dist/da-DK.module.js.map +1 -1
  10. package/dist/de-DE.main.js.map +1 -1
  11. package/dist/de-DE.module.js.map +1 -1
  12. package/dist/el-GR.main.js.map +1 -1
  13. package/dist/el-GR.module.js.map +1 -1
  14. package/dist/en-US.main.js.map +1 -1
  15. package/dist/en-US.module.js.map +1 -1
  16. package/dist/es-ES.main.js.map +1 -1
  17. package/dist/es-ES.module.js.map +1 -1
  18. package/dist/et-EE.main.js.map +1 -1
  19. package/dist/et-EE.module.js.map +1 -1
  20. package/dist/fi-FI.main.js.map +1 -1
  21. package/dist/fi-FI.module.js.map +1 -1
  22. package/dist/fr-FR.main.js.map +1 -1
  23. package/dist/fr-FR.module.js.map +1 -1
  24. package/dist/he-IL.main.js.map +1 -1
  25. package/dist/he-IL.module.js.map +1 -1
  26. package/dist/hr-HR.main.js.map +1 -1
  27. package/dist/hr-HR.module.js.map +1 -1
  28. package/dist/hu-HU.main.js.map +1 -1
  29. package/dist/hu-HU.module.js.map +1 -1
  30. package/dist/it-IT.main.js.map +1 -1
  31. package/dist/it-IT.module.js.map +1 -1
  32. package/dist/ja-JP.main.js.map +1 -1
  33. package/dist/ja-JP.module.js.map +1 -1
  34. package/dist/ko-KR.main.js.map +1 -1
  35. package/dist/ko-KR.module.js.map +1 -1
  36. package/dist/lt-LT.main.js.map +1 -1
  37. package/dist/lt-LT.module.js.map +1 -1
  38. package/dist/lv-LV.main.js.map +1 -1
  39. package/dist/lv-LV.module.js.map +1 -1
  40. package/dist/nb-NO.main.js.map +1 -1
  41. package/dist/nb-NO.module.js.map +1 -1
  42. package/dist/nl-NL.main.js.map +1 -1
  43. package/dist/nl-NL.module.js.map +1 -1
  44. package/dist/pl-PL.main.js.map +1 -1
  45. package/dist/pl-PL.module.js.map +1 -1
  46. package/dist/pt-BR.main.js.map +1 -1
  47. package/dist/pt-BR.module.js.map +1 -1
  48. package/dist/pt-PT.main.js.map +1 -1
  49. package/dist/pt-PT.module.js.map +1 -1
  50. package/dist/ro-RO.main.js.map +1 -1
  51. package/dist/ro-RO.module.js.map +1 -1
  52. package/dist/ru-RU.main.js.map +1 -1
  53. package/dist/ru-RU.module.js.map +1 -1
  54. package/dist/sk-SK.main.js.map +1 -1
  55. package/dist/sk-SK.module.js.map +1 -1
  56. package/dist/sl-SI.main.js.map +1 -1
  57. package/dist/sl-SI.module.js.map +1 -1
  58. package/dist/sr-SP.main.js.map +1 -1
  59. package/dist/sr-SP.module.js.map +1 -1
  60. package/dist/sv-SE.main.js.map +1 -1
  61. package/dist/sv-SE.module.js.map +1 -1
  62. package/dist/tr-TR.main.js.map +1 -1
  63. package/dist/tr-TR.module.js.map +1 -1
  64. package/dist/types.d.ts +1 -1
  65. package/dist/types.d.ts.map +1 -1
  66. package/dist/uk-UA.main.js.map +1 -1
  67. package/dist/uk-UA.module.js.map +1 -1
  68. package/dist/useDateField.main.js.map +1 -1
  69. package/dist/useDateField.module.js.map +1 -1
  70. package/dist/useDatePicker.main.js.map +1 -1
  71. package/dist/useDatePicker.module.js.map +1 -1
  72. package/dist/useDatePickerGroup.main.js +1 -0
  73. package/dist/useDatePickerGroup.main.js.map +1 -1
  74. package/dist/useDatePickerGroup.mjs +1 -0
  75. package/dist/useDatePickerGroup.module.js +1 -0
  76. package/dist/useDatePickerGroup.module.js.map +1 -1
  77. package/dist/useDateRangePicker.main.js +5 -4
  78. package/dist/useDateRangePicker.main.js.map +1 -1
  79. package/dist/useDateRangePicker.mjs +5 -4
  80. package/dist/useDateRangePicker.module.js +5 -4
  81. package/dist/useDateRangePicker.module.js.map +1 -1
  82. package/dist/useDateSegment.main.js +12 -11
  83. package/dist/useDateSegment.main.js.map +1 -1
  84. package/dist/useDateSegment.mjs +12 -11
  85. package/dist/useDateSegment.module.js +12 -11
  86. package/dist/useDateSegment.module.js.map +1 -1
  87. package/dist/useDisplayNames.main.js +1 -2
  88. package/dist/useDisplayNames.main.js.map +1 -1
  89. package/dist/useDisplayNames.mjs +1 -2
  90. package/dist/useDisplayNames.module.js +1 -2
  91. package/dist/useDisplayNames.module.js.map +1 -1
  92. package/dist/zh-CN.main.js.map +1 -1
  93. package/dist/zh-CN.module.js.map +1 -1
  94. package/dist/zh-TW.main.js.map +1 -1
  95. package/dist/zh-TW.module.js.map +1 -1
  96. package/package.json +23 -22
  97. package/src/useDateField.ts +3 -3
  98. package/src/useDatePickerGroup.ts +3 -0
  99. package/src/useDateRangePicker.ts +4 -4
  100. package/src/useDateSegment.ts +28 -18
  101. package/src/useDisplayNames.ts +2 -3
@@ -14,6 +14,7 @@ import {AriaButtonProps} from '@react-types/button';
14
14
  import {AriaDatePickerProps, AriaDateRangePickerProps, DateValue} from '@react-types/datepicker';
15
15
  import {AriaDialogProps} from '@react-types/dialog';
16
16
  import {createFocusManager} from '@react-aria/focus';
17
+ import {DateRange, RangeCalendarProps} from '@react-types/calendar';
17
18
  import {DateRangePickerState} from '@react-stately/datepicker';
18
19
  import {DEFAULT_VALIDATION_RESULT, mergeValidation, privateValidationStateProp} from '@react-stately/form';
19
20
  import {DOMAttributes, GroupDOMAttributes, KeyboardEvent, RefObject, ValidationResult} from '@react-types/shared';
@@ -21,7 +22,6 @@ import {filterDOMProps, mergeProps, useDescription, useId} from '@react-aria/uti
21
22
  import {focusManagerSymbol, roleSymbol} from './useDateField';
22
23
  // @ts-ignore
23
24
  import intlMessages from '../intl/*.json';
24
- import {RangeCalendarProps} from '@react-types/calendar';
25
25
  import {useDatePickerGroup} from './useDatePickerGroup';
26
26
  import {useField} from '@react-aria/label';
27
27
  import {useFocusWithin} from '@react-aria/interactions';
@@ -168,7 +168,7 @@ export function useDateRangePicker<T extends DateValue>(props: AriaDateRangePick
168
168
  startFieldProps: {
169
169
  ...startFieldProps,
170
170
  ...commonFieldProps,
171
- value: state.value?.start,
171
+ value: state.value?.start ?? null,
172
172
  onChange: start => state.setDateTime('start', start),
173
173
  autoFocus: props.autoFocus,
174
174
  name: props.startName,
@@ -186,7 +186,7 @@ export function useDateRangePicker<T extends DateValue>(props: AriaDateRangePick
186
186
  endFieldProps: {
187
187
  ...endFieldProps,
188
188
  ...commonFieldProps,
189
- value: state.value?.end,
189
+ value: state.value?.end ?? null,
190
190
  onChange: end => state.setDateTime('end', end),
191
191
  name: props.endName,
192
192
  [privateValidationStateProp]: {
@@ -204,7 +204,7 @@ export function useDateRangePicker<T extends DateValue>(props: AriaDateRangePick
204
204
  errorMessageProps,
205
205
  calendarProps: {
206
206
  autoFocus: true,
207
- value: state.dateRange,
207
+ value: state.dateRange?.start && state.dateRange.end ? state.dateRange as DateRange : null,
208
208
  onChange: state.setDateRange,
209
209
  minValue: props.minValue,
210
210
  maxValue: props.maxValue,
@@ -35,7 +35,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
35
35
  let enteredKeys = useRef('');
36
36
  let {locale} = useLocale();
37
37
  let displayNames = useDisplayNames();
38
- let {ariaLabel, ariaLabelledBy, ariaDescribedBy, focusManager} = hookData.get(state);
38
+ let {ariaLabel, ariaLabelledBy, ariaDescribedBy, focusManager} = hookData.get(state)!;
39
39
 
40
40
  let textValue = segment.isPlaceholder ? '' : segment.text;
41
41
  let options = useMemo(() => state.dateFormatter.resolvedOptions(), [state.dateFormatter]);
@@ -82,11 +82,15 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
82
82
  },
83
83
  onIncrementToMax: () => {
84
84
  enteredKeys.current = '';
85
- state.setSegment(segment.type, segment.maxValue);
85
+ if (segment.maxValue !== undefined) {
86
+ state.setSegment(segment.type, segment.maxValue);
87
+ }
86
88
  },
87
89
  onDecrementToMin: () => {
88
90
  enteredKeys.current = '';
89
- state.setSegment(segment.type, segment.minValue);
91
+ if (segment.minValue !== undefined) {
92
+ state.setSegment(segment.type, segment.minValue);
93
+ }
90
94
  }
91
95
  });
92
96
 
@@ -140,13 +144,13 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
140
144
  let am = useMemo(() => {
141
145
  let date = new Date();
142
146
  date.setHours(0);
143
- return amPmFormatter.formatToParts(date).find(part => part.type === 'dayPeriod').value;
147
+ return amPmFormatter.formatToParts(date).find(part => part.type === 'dayPeriod')!.value;
144
148
  }, [amPmFormatter]);
145
149
 
146
150
  let pm = useMemo(() => {
147
151
  let date = new Date();
148
152
  date.setHours(12);
149
- return amPmFormatter.formatToParts(date).find(part => part.type === 'dayPeriod').value;
153
+ return amPmFormatter.formatToParts(date).find(part => part.type === 'dayPeriod')!.value;
150
154
  }, [amPmFormatter]);
151
155
 
152
156
  // Get a list of formatted era names so users can type the first character to choose one.
@@ -160,7 +164,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
160
164
  let eras = state.calendar.getEras().map(era => {
161
165
  let eraDate = date.set({year: 1, month: 1, day: 1, era}).toDate('UTC');
162
166
  let parts = eraFormatter.formatToParts(eraDate);
163
- let formatted = parts.find(p => p.type === 'era').value;
167
+ let formatted = parts.find(p => p.type === 'era')!.value;
164
168
  return {era, formatted};
165
169
  });
166
170
 
@@ -231,10 +235,10 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
231
235
  break;
232
236
  }
233
237
 
234
- if (segment.value >= 12 && numberValue > 1) {
238
+ if (segment.value !== undefined && segment.value >= 12 && numberValue > 1) {
235
239
  numberValue += 12;
236
240
  }
237
- } else if (numberValue > segment.maxValue) {
241
+ } else if (segment.maxValue !== undefined && numberValue > segment.maxValue) {
238
242
  segmentValue = parser.parse(key);
239
243
  }
240
244
 
@@ -247,7 +251,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
247
251
  state.setSegment(segment.type, segmentValue);
248
252
  }
249
253
 
250
- if (Number(numberValue + '0') > segment.maxValue || newValue.length >= String(segment.maxValue).length) {
254
+ if (segment.maxValue !== undefined && (Number(numberValue + '0') > segment.maxValue || newValue.length >= String(segment.maxValue).length)) {
251
255
  enteredKeys.current = '';
252
256
  if (shouldSetValue) {
253
257
  focusManager.focusNext();
@@ -262,11 +266,13 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
262
266
 
263
267
  let onFocus = () => {
264
268
  enteredKeys.current = '';
265
- scrollIntoViewport(ref.current, {containingElement: getScrollParent(ref.current)});
269
+ if (ref.current) {
270
+ scrollIntoViewport(ref.current, {containingElement: getScrollParent(ref.current)});
271
+ }
266
272
 
267
273
  // Collapse selection to start or Chrome won't fire input events.
268
274
  let selection = window.getSelection();
269
- selection.collapse(ref.current);
275
+ selection?.collapse(ref.current);
270
276
  };
271
277
 
272
278
  let documentRef = useRef(typeof document !== 'undefined' ? document : null);
@@ -275,14 +281,16 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
275
281
  // Otherwise, when tapping on a segment in Android Chrome and then entering text,
276
282
  // composition events will be fired that break the DOM structure and crash the page.
277
283
  let selection = window.getSelection();
278
- if (ref.current && ref.current.contains(selection.anchorNode)) {
284
+ if (selection?.anchorNode && ref.current?.contains(selection?.anchorNode)) {
279
285
  selection.collapse(ref.current);
280
286
  }
281
287
  });
282
288
 
283
- let compositionRef = useRef('');
284
- // @ts-ignore - TODO: possibly old TS version? doesn't fail in my editor...
289
+ let compositionRef = useRef<string | null>('');
285
290
  useEvent(ref, 'beforeinput', e => {
291
+ if (!ref.current) {
292
+ return;
293
+ }
286
294
  e.preventDefault();
287
295
 
288
296
  switch (e.inputType) {
@@ -309,16 +317,18 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
309
317
  }
310
318
  });
311
319
 
312
- useEvent(ref, 'input', (e: InputEvent) => {
313
- let {inputType, data} = e;
320
+ useEvent(ref, 'input', e => {
321
+ let {inputType, data} = e as InputEvent;
314
322
  switch (inputType) {
315
323
  case 'insertCompositionText':
316
324
  // Reset the DOM to how it was in the beforeinput event.
317
- ref.current.textContent = compositionRef.current;
325
+ if (ref.current) {
326
+ ref.current.textContent = compositionRef.current;
327
+ }
318
328
 
319
329
  // Android sometimes fires key presses of letters as composition events. Need to handle am/pm keys here too.
320
330
  // Can also happen e.g. with Pinyin keyboard on iOS.
321
- if (startsWith(am, data) || startsWith(pm, data)) {
331
+ if (data != null && (startsWith(am, data) || startsWith(pm, data))) {
322
332
  onInput(data);
323
333
  }
324
334
  break;
@@ -18,7 +18,7 @@ import {useMemo} from 'react';
18
18
 
19
19
  type Field = Intl.DateTimeFormatPartTypes;
20
20
  interface DisplayNames {
21
- of(field: Field): string
21
+ of(field: Field): string | undefined
22
22
  }
23
23
 
24
24
  /** @private */
@@ -29,9 +29,8 @@ export function useDisplayNames(): DisplayNames {
29
29
  // Try to use Intl.DisplayNames if possible. It may be supported in browsers, but not support the dateTimeField
30
30
  // type as that was only added in v2. https://github.com/tc39/intl-displaynames-v2
31
31
  try {
32
- // @ts-ignore
33
32
  return new Intl.DisplayNames(locale, {type: 'dateTimeField'});
34
- } catch (err) {
33
+ } catch {
35
34
  return new DisplayNamesPolyfill(locale, dictionary);
36
35
  }
37
36
  }, [locale, dictionary]);