@react-aria/datepicker 3.0.0-nightly.3103 → 3.0.0-nightly.3104

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 (220) hide show
  1. package/dist/ar-AE.main.js +21 -0
  2. package/dist/ar-AE.main.js.map +1 -0
  3. package/dist/ar-AE.mjs +23 -0
  4. package/dist/ar-AE.module.js +23 -0
  5. package/dist/ar-AE.module.js.map +1 -0
  6. package/dist/bg-BG.main.js +21 -0
  7. package/dist/bg-BG.main.js.map +1 -0
  8. package/dist/bg-BG.mjs +23 -0
  9. package/dist/bg-BG.module.js +23 -0
  10. package/dist/bg-BG.module.js.map +1 -0
  11. package/dist/cs-CZ.main.js +21 -0
  12. package/dist/cs-CZ.main.js.map +1 -0
  13. package/dist/cs-CZ.mjs +23 -0
  14. package/dist/cs-CZ.module.js +23 -0
  15. package/dist/cs-CZ.module.js.map +1 -0
  16. package/dist/da-DK.main.js +21 -0
  17. package/dist/da-DK.main.js.map +1 -0
  18. package/dist/da-DK.mjs +23 -0
  19. package/dist/da-DK.module.js +23 -0
  20. package/dist/da-DK.module.js.map +1 -0
  21. package/dist/de-DE.main.js +21 -0
  22. package/dist/de-DE.main.js.map +1 -0
  23. package/dist/de-DE.mjs +23 -0
  24. package/dist/de-DE.module.js +23 -0
  25. package/dist/de-DE.module.js.map +1 -0
  26. package/dist/el-GR.main.js +21 -0
  27. package/dist/el-GR.main.js.map +1 -0
  28. package/dist/el-GR.mjs +23 -0
  29. package/dist/el-GR.module.js +23 -0
  30. package/dist/el-GR.module.js.map +1 -0
  31. package/dist/en-US.main.js +21 -0
  32. package/dist/en-US.main.js.map +1 -0
  33. package/dist/en-US.mjs +23 -0
  34. package/dist/en-US.module.js +23 -0
  35. package/dist/en-US.module.js.map +1 -0
  36. package/dist/es-ES.main.js +21 -0
  37. package/dist/es-ES.main.js.map +1 -0
  38. package/dist/es-ES.mjs +23 -0
  39. package/dist/es-ES.module.js +23 -0
  40. package/dist/es-ES.module.js.map +1 -0
  41. package/dist/et-EE.main.js +21 -0
  42. package/dist/et-EE.main.js.map +1 -0
  43. package/dist/et-EE.mjs +23 -0
  44. package/dist/et-EE.module.js +23 -0
  45. package/dist/et-EE.module.js.map +1 -0
  46. package/dist/fi-FI.main.js +21 -0
  47. package/dist/fi-FI.main.js.map +1 -0
  48. package/dist/fi-FI.mjs +23 -0
  49. package/dist/fi-FI.module.js +23 -0
  50. package/dist/fi-FI.module.js.map +1 -0
  51. package/dist/fr-FR.main.js +21 -0
  52. package/dist/fr-FR.main.js.map +1 -0
  53. package/dist/fr-FR.mjs +23 -0
  54. package/dist/fr-FR.module.js +23 -0
  55. package/dist/fr-FR.module.js.map +1 -0
  56. package/dist/he-IL.main.js +21 -0
  57. package/dist/he-IL.main.js.map +1 -0
  58. package/dist/he-IL.mjs +23 -0
  59. package/dist/he-IL.module.js +23 -0
  60. package/dist/he-IL.module.js.map +1 -0
  61. package/dist/hr-HR.main.js +21 -0
  62. package/dist/hr-HR.main.js.map +1 -0
  63. package/dist/hr-HR.mjs +23 -0
  64. package/dist/hr-HR.module.js +23 -0
  65. package/dist/hr-HR.module.js.map +1 -0
  66. package/dist/hu-HU.main.js +21 -0
  67. package/dist/hu-HU.main.js.map +1 -0
  68. package/dist/hu-HU.mjs +23 -0
  69. package/dist/hu-HU.module.js +23 -0
  70. package/dist/hu-HU.module.js.map +1 -0
  71. package/dist/import.mjs +25 -0
  72. package/dist/intlStrings.main.js +108 -0
  73. package/dist/intlStrings.main.js.map +1 -0
  74. package/dist/intlStrings.mjs +110 -0
  75. package/dist/intlStrings.module.js +110 -0
  76. package/dist/intlStrings.module.js.map +1 -0
  77. package/dist/it-IT.main.js +21 -0
  78. package/dist/it-IT.main.js.map +1 -0
  79. package/dist/it-IT.mjs +23 -0
  80. package/dist/it-IT.module.js +23 -0
  81. package/dist/it-IT.module.js.map +1 -0
  82. package/dist/ja-JP.main.js +21 -0
  83. package/dist/ja-JP.main.js.map +1 -0
  84. package/dist/ja-JP.mjs +23 -0
  85. package/dist/ja-JP.module.js +23 -0
  86. package/dist/ja-JP.module.js.map +1 -0
  87. package/dist/ko-KR.main.js +21 -0
  88. package/dist/ko-KR.main.js.map +1 -0
  89. package/dist/ko-KR.mjs +23 -0
  90. package/dist/ko-KR.module.js +23 -0
  91. package/dist/ko-KR.module.js.map +1 -0
  92. package/dist/lt-LT.main.js +21 -0
  93. package/dist/lt-LT.main.js.map +1 -0
  94. package/dist/lt-LT.mjs +23 -0
  95. package/dist/lt-LT.module.js +23 -0
  96. package/dist/lt-LT.module.js.map +1 -0
  97. package/dist/lv-LV.main.js +21 -0
  98. package/dist/lv-LV.main.js.map +1 -0
  99. package/dist/lv-LV.mjs +23 -0
  100. package/dist/lv-LV.module.js +23 -0
  101. package/dist/lv-LV.module.js.map +1 -0
  102. package/dist/main.js +22 -759
  103. package/dist/main.js.map +1 -1
  104. package/dist/module.js +17 -744
  105. package/dist/module.js.map +1 -1
  106. package/dist/nb-NO.main.js +21 -0
  107. package/dist/nb-NO.main.js.map +1 -0
  108. package/dist/nb-NO.mjs +23 -0
  109. package/dist/nb-NO.module.js +23 -0
  110. package/dist/nb-NO.module.js.map +1 -0
  111. package/dist/nl-NL.main.js +21 -0
  112. package/dist/nl-NL.main.js.map +1 -0
  113. package/dist/nl-NL.mjs +23 -0
  114. package/dist/nl-NL.module.js +23 -0
  115. package/dist/nl-NL.module.js.map +1 -0
  116. package/dist/pl-PL.main.js +21 -0
  117. package/dist/pl-PL.main.js.map +1 -0
  118. package/dist/pl-PL.mjs +23 -0
  119. package/dist/pl-PL.module.js +23 -0
  120. package/dist/pl-PL.module.js.map +1 -0
  121. package/dist/pt-BR.main.js +21 -0
  122. package/dist/pt-BR.main.js.map +1 -0
  123. package/dist/pt-BR.mjs +23 -0
  124. package/dist/pt-BR.module.js +23 -0
  125. package/dist/pt-BR.module.js.map +1 -0
  126. package/dist/pt-PT.main.js +21 -0
  127. package/dist/pt-PT.main.js.map +1 -0
  128. package/dist/pt-PT.mjs +23 -0
  129. package/dist/pt-PT.module.js +23 -0
  130. package/dist/pt-PT.module.js.map +1 -0
  131. package/dist/ro-RO.main.js +21 -0
  132. package/dist/ro-RO.main.js.map +1 -0
  133. package/dist/ro-RO.mjs +23 -0
  134. package/dist/ro-RO.module.js +23 -0
  135. package/dist/ro-RO.module.js.map +1 -0
  136. package/dist/ru-RU.main.js +21 -0
  137. package/dist/ru-RU.main.js.map +1 -0
  138. package/dist/ru-RU.mjs +23 -0
  139. package/dist/ru-RU.module.js +23 -0
  140. package/dist/ru-RU.module.js.map +1 -0
  141. package/dist/sk-SK.main.js +21 -0
  142. package/dist/sk-SK.main.js.map +1 -0
  143. package/dist/sk-SK.mjs +23 -0
  144. package/dist/sk-SK.module.js +23 -0
  145. package/dist/sk-SK.module.js.map +1 -0
  146. package/dist/sl-SI.main.js +21 -0
  147. package/dist/sl-SI.main.js.map +1 -0
  148. package/dist/sl-SI.mjs +23 -0
  149. package/dist/sl-SI.module.js +23 -0
  150. package/dist/sl-SI.module.js.map +1 -0
  151. package/dist/sr-SP.main.js +21 -0
  152. package/dist/sr-SP.main.js.map +1 -0
  153. package/dist/sr-SP.mjs +23 -0
  154. package/dist/sr-SP.module.js +23 -0
  155. package/dist/sr-SP.module.js.map +1 -0
  156. package/dist/sv-SE.main.js +21 -0
  157. package/dist/sv-SE.main.js.map +1 -0
  158. package/dist/sv-SE.mjs +23 -0
  159. package/dist/sv-SE.module.js +23 -0
  160. package/dist/sv-SE.module.js.map +1 -0
  161. package/dist/tr-TR.main.js +21 -0
  162. package/dist/tr-TR.main.js.map +1 -0
  163. package/dist/tr-TR.mjs +23 -0
  164. package/dist/tr-TR.module.js +23 -0
  165. package/dist/tr-TR.module.js.map +1 -0
  166. package/dist/types.d.ts +88 -37
  167. package/dist/types.d.ts.map +1 -1
  168. package/dist/uk-UA.main.js +21 -0
  169. package/dist/uk-UA.main.js.map +1 -0
  170. package/dist/uk-UA.mjs +23 -0
  171. package/dist/uk-UA.module.js +23 -0
  172. package/dist/uk-UA.module.js.map +1 -0
  173. package/dist/useDateField.main.js +177 -0
  174. package/dist/useDateField.main.js.map +1 -0
  175. package/dist/useDateField.mjs +168 -0
  176. package/dist/useDateField.module.js +168 -0
  177. package/dist/useDateField.module.js.map +1 -0
  178. package/dist/useDatePicker.main.js +158 -0
  179. package/dist/useDatePicker.main.js.map +1 -0
  180. package/dist/useDatePicker.mjs +153 -0
  181. package/dist/useDatePicker.module.js +153 -0
  182. package/dist/useDatePicker.module.js.map +1 -0
  183. package/dist/useDatePickerGroup.main.js +91 -0
  184. package/dist/useDatePickerGroup.main.js.map +1 -0
  185. package/dist/useDatePickerGroup.mjs +86 -0
  186. package/dist/useDatePickerGroup.module.js +86 -0
  187. package/dist/useDatePickerGroup.module.js.map +1 -0
  188. package/dist/useDateRangePicker.main.js +201 -0
  189. package/dist/useDateRangePicker.main.js.map +1 -0
  190. package/dist/useDateRangePicker.mjs +196 -0
  191. package/dist/useDateRangePicker.module.js +196 -0
  192. package/dist/useDateRangePicker.module.js.map +1 -0
  193. package/dist/useDateSegment.main.js +373 -0
  194. package/dist/useDateSegment.main.js.map +1 -0
  195. package/dist/useDateSegment.mjs +364 -0
  196. package/dist/useDateSegment.module.js +364 -0
  197. package/dist/useDateSegment.module.js.map +1 -0
  198. package/dist/useDisplayNames.main.js +59 -0
  199. package/dist/useDisplayNames.main.js.map +1 -0
  200. package/dist/useDisplayNames.mjs +54 -0
  201. package/dist/useDisplayNames.module.js +54 -0
  202. package/dist/useDisplayNames.module.js.map +1 -0
  203. package/dist/zh-CN.main.js +21 -0
  204. package/dist/zh-CN.main.js.map +1 -0
  205. package/dist/zh-CN.mjs +23 -0
  206. package/dist/zh-CN.module.js +23 -0
  207. package/dist/zh-CN.module.js.map +1 -0
  208. package/dist/zh-TW.main.js +21 -0
  209. package/dist/zh-TW.main.js.map +1 -0
  210. package/dist/zh-TW.mjs +23 -0
  211. package/dist/zh-TW.module.js +23 -0
  212. package/dist/zh-TW.module.js.map +1 -0
  213. package/package.json +27 -18
  214. package/src/index.ts +12 -5
  215. package/src/useDateField.ts +163 -32
  216. package/src/useDatePicker.ts +113 -26
  217. package/src/useDatePickerGroup.ts +71 -13
  218. package/src/useDateRangePicker.ts +149 -38
  219. package/src/useDateSegment.ts +145 -91
  220. package/src/useDisplayNames.ts +10 -8
@@ -1,34 +1,92 @@
1
- import {DatePickerFieldState, DatePickerState, DateRangePickerState} from '@react-stately/datepicker';
2
- import {KeyboardEvent} from '@react-types/shared';
1
+ import {createFocusManager, getFocusableTreeWalker} from '@react-aria/focus';
2
+ import {DateFieldState, DatePickerState, DateRangePickerState} from '@react-stately/datepicker';
3
+ import {FocusableElement, KeyboardEvent, RefObject} from '@react-types/shared';
3
4
  import {mergeProps} from '@react-aria/utils';
4
- import {RefObject} from 'react';
5
+ import {useLocale} from '@react-aria/i18n';
6
+ import {useMemo} from 'react';
5
7
  import {usePress} from '@react-aria/interactions';
6
8
 
7
- export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | DatePickerFieldState, ref: RefObject<HTMLElement>) {
9
+ export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | DateFieldState, ref: RefObject<Element | null>, disableArrowNavigation?: boolean) {
10
+ let {direction} = useLocale();
11
+ let focusManager = useMemo(() => createFocusManager(ref), [ref]);
12
+
8
13
  // Open the popover on alt + arrow down
9
14
  let onKeyDown = (e: KeyboardEvent) => {
10
- if (e.altKey && e.key === 'ArrowDown' && 'setOpen' in state) {
15
+ if (!e.currentTarget.contains(e.target)) {
16
+ return;
17
+ }
18
+
19
+ if (e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp') && 'setOpen' in state) {
11
20
  e.preventDefault();
12
21
  e.stopPropagation();
13
22
  state.setOpen(true);
14
23
  }
24
+
25
+ if (disableArrowNavigation) {
26
+ return;
27
+ }
28
+
29
+ switch (e.key) {
30
+ case 'ArrowLeft':
31
+ e.preventDefault();
32
+ e.stopPropagation();
33
+ if (direction === 'rtl') {
34
+ focusManager.focusNext();
35
+ } else {
36
+ focusManager.focusPrevious();
37
+ }
38
+ break;
39
+ case 'ArrowRight':
40
+ e.preventDefault();
41
+ e.stopPropagation();
42
+ if (direction === 'rtl') {
43
+ focusManager.focusPrevious();
44
+ } else {
45
+ focusManager.focusNext();
46
+ }
47
+ break;
48
+ }
15
49
  };
16
50
 
17
51
  // Focus the first placeholder segment from the end on mouse down/touch up in the field.
18
52
  let focusLast = () => {
19
- let elements = ref.current.querySelectorAll('[tabindex="0"]');
20
- let index = elements.length - 1;
21
- while (index >= 0 && elements[index].getAttribute('aria-placeholder')) {
22
- index--;
53
+ // Try to find the segment prior to the element that was clicked on.
54
+ let target = window.event?.target as FocusableElement;
55
+ let walker = getFocusableTreeWalker(ref.current, {tabbable: true});
56
+ if (target) {
57
+ walker.currentNode = target;
58
+ target = walker.previousNode() as FocusableElement;
23
59
  }
24
- index = Math.min(index + 1, elements.length - 1);
25
- let element = elements[index] as HTMLElement;
26
- if (element) {
27
- element.focus();
60
+
61
+ // If no target found, find the last element from the end.
62
+ if (!target) {
63
+ let last: FocusableElement;
64
+ do {
65
+ last = walker.lastChild() as FocusableElement;
66
+ if (last) {
67
+ target = last;
68
+ }
69
+ } while (last);
70
+ }
71
+
72
+ // Now go backwards until we find an element that is not a placeholder.
73
+ while (target?.hasAttribute('data-placeholder')) {
74
+ let prev = walker.previousNode() as FocusableElement;
75
+ if (prev && prev.hasAttribute('data-placeholder')) {
76
+ target = prev;
77
+ } else {
78
+ break;
79
+ }
80
+ }
81
+
82
+ if (target) {
83
+ target.focus();
28
84
  }
29
85
  };
30
86
 
31
87
  let {pressProps} = usePress({
88
+ preventFocusOnPress: true,
89
+ allowTextSelectionOnPress: true,
32
90
  onPressStart(e) {
33
91
  if (e.pointerType === 'mouse') {
34
92
  focusLast();
@@ -15,98 +15,209 @@ import {AriaDatePickerProps, AriaDateRangePickerProps, DateValue} from '@react-t
15
15
  import {AriaDialogProps} from '@react-types/dialog';
16
16
  import {createFocusManager} from '@react-aria/focus';
17
17
  import {DateRangePickerState} from '@react-stately/datepicker';
18
- import {HTMLAttributes, LabelHTMLAttributes, RefObject} from 'react';
18
+ import {DEFAULT_VALIDATION_RESULT, mergeValidation, privateValidationStateProp} from '@react-stately/form';
19
+ import {DOMAttributes, GroupDOMAttributes, KeyboardEvent, RefObject, ValidationResult} from '@react-types/shared';
20
+ import {filterDOMProps, mergeProps, useDescription, useId} from '@react-aria/utils';
21
+ import {focusManagerSymbol, roleSymbol} from './useDateField';
19
22
  // @ts-ignore
20
23
  import intlMessages from '../intl/*.json';
21
- import {mergeProps, useDescription, useId, useLabels} from '@react-aria/utils';
24
+ import {RangeCalendarProps} from '@react-types/calendar';
22
25
  import {useDatePickerGroup} from './useDatePickerGroup';
23
26
  import {useField} from '@react-aria/label';
24
27
  import {useFocusWithin} from '@react-aria/interactions';
25
- import {useLocale, useMessageFormatter} from '@react-aria/i18n';
28
+ import {useLocale, useLocalizedStringFormatter} from '@react-aria/i18n';
29
+ import {useMemo, useRef} from 'react';
26
30
 
27
- interface DateRangePickerAria<T extends DateValue> {
28
- labelProps: LabelHTMLAttributes<HTMLLabelElement>,
29
- groupProps: HTMLAttributes<HTMLElement>,
30
- startFieldProps: AriaDatePickerProps<T>,
31
- endFieldProps: AriaDatePickerProps<T>,
31
+ export interface DateRangePickerAria extends ValidationResult {
32
+ /** Props for the date range picker's visible label element, if any. */
33
+ labelProps: DOMAttributes,
34
+ /** Props for the grouping element containing the date fields and button. */
35
+ groupProps: GroupDOMAttributes,
36
+ /** Props for the start date field. */
37
+ startFieldProps: AriaDatePickerProps<DateValue>,
38
+ /** Props for the end date field. */
39
+ endFieldProps: AriaDatePickerProps<DateValue>,
40
+ /** Props for the popover trigger button. */
41
+ buttonProps: AriaButtonProps,
32
42
  /** Props for the description element, if any. */
33
- descriptionProps: HTMLAttributes<HTMLElement>,
43
+ descriptionProps: DOMAttributes,
34
44
  /** Props for the error message element, if any. */
35
- errorMessageProps: HTMLAttributes<HTMLElement>,
36
- buttonProps: AriaButtonProps,
37
- dialogProps: AriaDialogProps
45
+ errorMessageProps: DOMAttributes,
46
+ /** Props for the popover dialog. */
47
+ dialogProps: AriaDialogProps,
48
+ /** Props for the range calendar within the popover dialog. */
49
+ calendarProps: RangeCalendarProps<DateValue>
38
50
  }
39
51
 
40
- export function useDateRangePicker<T extends DateValue>(props: AriaDateRangePickerProps<T>, state: DateRangePickerState, ref: RefObject<HTMLElement>): DateRangePickerAria<T> {
41
- let formatMessage = useMessageFormatter(intlMessages);
52
+ /**
53
+ * Provides the behavior and accessibility implementation for a date picker component.
54
+ * A date range picker combines two DateFields and a RangeCalendar popover to allow
55
+ * users to enter or select a date and time range.
56
+ */
57
+ export function useDateRangePicker<T extends DateValue>(props: AriaDateRangePickerProps<T>, state: DateRangePickerState, ref: RefObject<Element | null>): DateRangePickerAria {
58
+ let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/datepicker');
59
+ let {isInvalid, validationErrors, validationDetails} = state.displayValidation;
42
60
  let {labelProps, fieldProps, descriptionProps, errorMessageProps} = useField({
43
61
  ...props,
44
- labelElementType: 'span'
62
+ labelElementType: 'span',
63
+ isInvalid,
64
+ errorMessage: props.errorMessage || validationErrors
45
65
  });
46
66
 
47
67
  let labelledBy = fieldProps['aria-labelledby'] || fieldProps.id;
48
68
 
49
69
  let {locale} = useLocale();
50
- let description = state.formatValue(locale, {month: 'long'});
70
+ let range = state.formatValue(locale, {month: 'long'});
71
+ let description = range ? stringFormatter.format('selectedRangeDescription', {startDate: range.start, endDate: range.end}) : '';
51
72
  let descProps = useDescription(description);
52
73
 
53
- let startFieldProps = useLabels({
54
- 'aria-label': formatMessage('startDate'),
74
+ let startFieldProps = {
75
+ 'aria-label': stringFormatter.format('startDate'),
55
76
  'aria-labelledby': labelledBy
56
- });
77
+ };
57
78
 
58
- let endFieldProps = useLabels({
59
- 'aria-label': formatMessage('endDate'),
79
+ let endFieldProps = {
80
+ 'aria-label': stringFormatter.format('endDate'),
60
81
  'aria-labelledby': labelledBy
61
- });
82
+ };
62
83
 
63
84
  let buttonId = useId();
64
85
  let dialogId = useId();
65
86
 
66
87
  let groupProps = useDatePickerGroup(state, ref);
88
+
89
+ let ariaDescribedBy = [descProps['aria-describedby'], fieldProps['aria-describedby']].filter(Boolean).join(' ') || undefined;
90
+ let focusManager = useMemo(() => createFocusManager(ref, {
91
+ // Exclude the button from the focus manager.
92
+ accept: element => element.id !== buttonId
93
+ }), [ref, buttonId]);
94
+
95
+ let commonFieldProps = {
96
+ [focusManagerSymbol]: focusManager,
97
+ [roleSymbol]: 'presentation',
98
+ 'aria-describedby': ariaDescribedBy,
99
+ placeholderValue: props.placeholderValue,
100
+ hideTimeZone: props.hideTimeZone,
101
+ hourCycle: props.hourCycle,
102
+ granularity: props.granularity,
103
+ shouldForceLeadingZeros: props.shouldForceLeadingZeros,
104
+ isDisabled: props.isDisabled,
105
+ isReadOnly: props.isReadOnly,
106
+ isRequired: props.isRequired,
107
+ validationBehavior: props.validationBehavior
108
+ };
109
+
110
+ let domProps = filterDOMProps(props);
111
+
67
112
  let {focusWithinProps} = useFocusWithin({
68
- onBlurWithin() {
69
- state.confirmPlaceholder();
70
- }
113
+ ...props,
114
+ isDisabled: state.isOpen,
115
+ onBlurWithin: props.onBlur,
116
+ onFocusWithin: props.onFocus,
117
+ onFocusWithinChange: props.onFocusChange
71
118
  });
72
119
 
73
- let ariaDescribedBy = [descProps['aria-describedby'], fieldProps['aria-describedby']].filter(Boolean).join(' ') || undefined;
120
+ let startFieldValidation = useRef(DEFAULT_VALIDATION_RESULT);
121
+ let endFieldValidation = useRef(DEFAULT_VALIDATION_RESULT);
74
122
 
75
123
  return {
76
- groupProps: mergeProps(groupProps, fieldProps, descProps, focusWithinProps, {
77
- role: 'group',
124
+ groupProps: mergeProps(domProps, groupProps, fieldProps, descProps, focusWithinProps, {
125
+ role: 'group' as const,
78
126
  'aria-disabled': props.isDisabled || null,
79
- 'aria-describedby': ariaDescribedBy
127
+ 'aria-describedby': ariaDescribedBy,
128
+ onKeyDown(e: KeyboardEvent) {
129
+ if (state.isOpen) {
130
+ return;
131
+ }
132
+
133
+ if (props.onKeyDown) {
134
+ props.onKeyDown(e);
135
+ }
136
+ },
137
+ onKeyUp(e: KeyboardEvent) {
138
+ if (state.isOpen) {
139
+ return;
140
+ }
141
+
142
+ if (props.onKeyUp) {
143
+ props.onKeyUp(e);
144
+ }
145
+ }
80
146
  }),
81
147
  labelProps: {
82
148
  ...labelProps,
83
149
  onClick: () => {
84
- let focusManager = createFocusManager(ref);
85
150
  focusManager.focusFirst();
86
151
  }
87
152
  },
88
153
  buttonProps: {
89
154
  ...descProps,
90
155
  id: buttonId,
91
- excludeFromTabOrder: true,
92
156
  'aria-haspopup': 'dialog',
93
- 'aria-label': formatMessage('calendar'),
94
- 'aria-labelledby': `${labelledBy} ${buttonId}`,
95
- 'aria-describedby': ariaDescribedBy
157
+ 'aria-label': stringFormatter.format('calendar'),
158
+ 'aria-labelledby': `${buttonId} ${labelledBy}`,
159
+ 'aria-describedby': ariaDescribedBy,
160
+ 'aria-expanded': state.isOpen,
161
+ isDisabled: props.isDisabled || props.isReadOnly,
162
+ onPress: () => state.setOpen(true)
96
163
  },
97
164
  dialogProps: {
98
165
  id: dialogId,
99
- 'aria-labelledby': `${labelledBy} ${buttonId}`
166
+ 'aria-labelledby': `${buttonId} ${labelledBy}`
100
167
  },
101
168
  startFieldProps: {
102
169
  ...startFieldProps,
103
- 'aria-describedby': fieldProps['aria-describedby']
170
+ ...commonFieldProps,
171
+ value: state.value?.start,
172
+ onChange: start => state.setDateTime('start', start),
173
+ autoFocus: props.autoFocus,
174
+ name: props.startName,
175
+ [privateValidationStateProp]: {
176
+ realtimeValidation: state.realtimeValidation,
177
+ displayValidation: state.displayValidation,
178
+ updateValidation(e) {
179
+ startFieldValidation.current = e;
180
+ state.updateValidation(mergeValidation(e, endFieldValidation.current));
181
+ },
182
+ resetValidation: state.resetValidation,
183
+ commitValidation: state.commitValidation
184
+ }
104
185
  },
105
186
  endFieldProps: {
106
187
  ...endFieldProps,
107
- 'aria-describedby': fieldProps['aria-describedby']
188
+ ...commonFieldProps,
189
+ value: state.value?.end,
190
+ onChange: end => state.setDateTime('end', end),
191
+ name: props.endName,
192
+ [privateValidationStateProp]: {
193
+ realtimeValidation: state.realtimeValidation,
194
+ displayValidation: state.displayValidation,
195
+ updateValidation(e) {
196
+ endFieldValidation.current = e;
197
+ state.updateValidation(mergeValidation(startFieldValidation.current, e));
198
+ },
199
+ resetValidation: state.resetValidation,
200
+ commitValidation: state.commitValidation
201
+ }
108
202
  },
109
203
  descriptionProps,
110
- errorMessageProps
204
+ errorMessageProps,
205
+ calendarProps: {
206
+ autoFocus: true,
207
+ value: state.dateRange,
208
+ onChange: state.setDateRange,
209
+ minValue: props.minValue,
210
+ maxValue: props.maxValue,
211
+ isDisabled: props.isDisabled,
212
+ isReadOnly: props.isReadOnly,
213
+ isDateUnavailable: props.isDateUnavailable,
214
+ allowsNonContiguousRanges: props.allowsNonContiguousRanges,
215
+ defaultFocusedValue: state.dateRange ? undefined : props.placeholderValue,
216
+ isInvalid: state.isInvalid,
217
+ errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : (props.errorMessage || state.displayValidation.validationErrors.join(' '))
218
+ },
219
+ isInvalid,
220
+ validationErrors,
221
+ validationDetails
111
222
  };
112
223
  }