@react-aria/datepicker 3.0.0-rc.0 → 3.0.0-rc.1
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/main.js +43 -39
- package/dist/main.js.map +1 -1
- package/dist/module.js +43 -39
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/useDateField.ts +1 -2
- package/src/useDatePicker.ts +2 -3
- package/src/useDatePickerGroup.ts +32 -3
- package/src/useDateRangePicker.ts +5 -2
- package/src/useDateSegment.ts +7 -23
package/src/useDatePicker.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {CalendarProps} from '@react-types/calendar';
|
|
|
17
17
|
import {createFocusManager} from '@react-aria/focus';
|
|
18
18
|
import {DatePickerState} from '@react-stately/datepicker';
|
|
19
19
|
import {filterDOMProps, mergeProps, useDescription, useId} from '@react-aria/utils';
|
|
20
|
-
import {HTMLAttributes, RefObject} from 'react';
|
|
20
|
+
import {HTMLAttributes, RefObject, useMemo} from 'react';
|
|
21
21
|
// @ts-ignore
|
|
22
22
|
import intlMessages from '../intl/*.json';
|
|
23
23
|
import {roleSymbol} from './useDateField';
|
|
@@ -68,6 +68,7 @@ export function useDatePicker<T extends DateValue>(props: AriaDatePickerProps<T>
|
|
|
68
68
|
let descProps = useDescription(description);
|
|
69
69
|
let ariaDescribedBy = [descProps['aria-describedby'], fieldProps['aria-describedby']].filter(Boolean).join(' ') || undefined;
|
|
70
70
|
let domProps = filterDOMProps(props);
|
|
71
|
+
let focusManager = useMemo(() => createFocusManager(ref), [ref]);
|
|
71
72
|
|
|
72
73
|
return {
|
|
73
74
|
groupProps: mergeProps(domProps, groupProps, fieldProps, descProps, {
|
|
@@ -79,7 +80,6 @@ export function useDatePicker<T extends DateValue>(props: AriaDatePickerProps<T>
|
|
|
79
80
|
labelProps: {
|
|
80
81
|
...labelProps,
|
|
81
82
|
onClick: () => {
|
|
82
|
-
let focusManager = createFocusManager(ref);
|
|
83
83
|
focusManager.focusFirst();
|
|
84
84
|
}
|
|
85
85
|
},
|
|
@@ -106,7 +106,6 @@ export function useDatePicker<T extends DateValue>(props: AriaDatePickerProps<T>
|
|
|
106
106
|
buttonProps: {
|
|
107
107
|
...descProps,
|
|
108
108
|
id: buttonId,
|
|
109
|
-
excludeFromTabOrder: true,
|
|
110
109
|
'aria-haspopup': 'dialog',
|
|
111
110
|
'aria-label': formatMessage('calendar'),
|
|
112
111
|
'aria-labelledby': `${labelledBy} ${buttonId}`,
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import {createFocusManager, getFocusableTreeWalker} from '@react-aria/focus';
|
|
1
2
|
import {DateFieldState, DatePickerState, DateRangePickerState} from '@react-stately/datepicker';
|
|
2
|
-
import {getFocusableTreeWalker} from '@react-aria/focus';
|
|
3
3
|
import {KeyboardEvent} from '@react-types/shared';
|
|
4
4
|
import {mergeProps} from '@react-aria/utils';
|
|
5
|
-
import {RefObject} from 'react';
|
|
5
|
+
import {RefObject, useMemo} from 'react';
|
|
6
|
+
import {useLocale} from '@react-aria/i18n';
|
|
6
7
|
import {usePress} from '@react-aria/interactions';
|
|
7
8
|
|
|
8
|
-
export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | DateFieldState, ref: RefObject<HTMLElement
|
|
9
|
+
export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | DateFieldState, ref: RefObject<HTMLElement>, disableArrowNavigation?: boolean) {
|
|
10
|
+
let {direction} = useLocale();
|
|
11
|
+
let focusManager = useMemo(() => createFocusManager(ref), [ref]);
|
|
12
|
+
|
|
9
13
|
// Open the popover on alt + arrow down
|
|
10
14
|
let onKeyDown = (e: KeyboardEvent) => {
|
|
11
15
|
if (e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp') && 'setOpen' in state) {
|
|
@@ -13,6 +17,31 @@ export function useDatePickerGroup(state: DatePickerState | DateRangePickerState
|
|
|
13
17
|
e.stopPropagation();
|
|
14
18
|
state.setOpen(true);
|
|
15
19
|
}
|
|
20
|
+
|
|
21
|
+
if (disableArrowNavigation) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
switch (e.key) {
|
|
26
|
+
case 'ArrowLeft':
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
e.stopPropagation();
|
|
29
|
+
if (direction === 'rtl') {
|
|
30
|
+
focusManager.focusNext();
|
|
31
|
+
} else {
|
|
32
|
+
focusManager.focusPrevious();
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
case 'ArrowRight':
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
e.stopPropagation();
|
|
38
|
+
if (direction === 'rtl') {
|
|
39
|
+
focusManager.focusPrevious();
|
|
40
|
+
} else {
|
|
41
|
+
focusManager.focusNext();
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
16
45
|
};
|
|
17
46
|
|
|
18
47
|
// Focus the first placeholder segment from the end on mouse down/touch up in the field.
|
|
@@ -87,7 +87,11 @@ export function useDateRangePicker<T extends DateValue>(props: AriaDateRangePick
|
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
let ariaDescribedBy = [descProps['aria-describedby'], fieldProps['aria-describedby']].filter(Boolean).join(' ') || undefined;
|
|
90
|
-
let focusManager = useMemo(() => createFocusManager(ref
|
|
90
|
+
let focusManager = useMemo(() => createFocusManager(ref, {
|
|
91
|
+
// Exclude the button from the focus manager.
|
|
92
|
+
accept: element => element.id !== buttonId
|
|
93
|
+
}), [ref, buttonId]);
|
|
94
|
+
|
|
91
95
|
let commonFieldProps = {
|
|
92
96
|
[focusManagerSymbol]: focusManager,
|
|
93
97
|
[roleSymbol]: 'presentation',
|
|
@@ -121,7 +125,6 @@ export function useDateRangePicker<T extends DateValue>(props: AriaDateRangePick
|
|
|
121
125
|
buttonProps: {
|
|
122
126
|
...descProps,
|
|
123
127
|
id: buttonId,
|
|
124
|
-
excludeFromTabOrder: true,
|
|
125
128
|
'aria-haspopup': 'dialog',
|
|
126
129
|
'aria-label': formatMessage('calendar'),
|
|
127
130
|
'aria-labelledby': `${labelledBy} ${buttonId}`,
|
package/src/useDateSegment.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface DateSegmentAria {
|
|
|
31
31
|
*/
|
|
32
32
|
export function useDateSegment(segment: DateSegment, state: DateFieldState, ref: RefObject<HTMLElement>): DateSegmentAria {
|
|
33
33
|
let enteredKeys = useRef('');
|
|
34
|
-
let {locale
|
|
34
|
+
let {locale} = useLocale();
|
|
35
35
|
let displayNames = useDisplayNames();
|
|
36
36
|
let {ariaLabel, ariaLabelledBy, ariaDescribedBy, focusManager} = hookData.get(state);
|
|
37
37
|
|
|
@@ -114,31 +114,13 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
switch (e.key) {
|
|
117
|
-
case 'ArrowLeft':
|
|
118
|
-
e.preventDefault();
|
|
119
|
-
e.stopPropagation();
|
|
120
|
-
if (direction === 'rtl') {
|
|
121
|
-
focusManager.focusNext({tabbable: true});
|
|
122
|
-
} else {
|
|
123
|
-
focusManager.focusPrevious({tabbable: true});
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
case 'ArrowRight':
|
|
127
|
-
e.preventDefault();
|
|
128
|
-
e.stopPropagation();
|
|
129
|
-
if (direction === 'rtl') {
|
|
130
|
-
focusManager.focusPrevious({tabbable: true});
|
|
131
|
-
} else {
|
|
132
|
-
focusManager.focusNext({tabbable: true});
|
|
133
|
-
}
|
|
134
|
-
break;
|
|
135
117
|
case 'Enter':
|
|
136
118
|
e.preventDefault();
|
|
137
119
|
e.stopPropagation();
|
|
138
120
|
if (segment.isPlaceholder && !state.isReadOnly) {
|
|
139
121
|
state.confirmPlaceholder(segment.type);
|
|
140
122
|
}
|
|
141
|
-
focusManager.focusNext(
|
|
123
|
+
focusManager.focusNext();
|
|
142
124
|
break;
|
|
143
125
|
case 'Tab':
|
|
144
126
|
break;
|
|
@@ -184,7 +166,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
|
|
|
184
166
|
} else {
|
|
185
167
|
break;
|
|
186
168
|
}
|
|
187
|
-
focusManager.focusNext(
|
|
169
|
+
focusManager.focusNext();
|
|
188
170
|
break;
|
|
189
171
|
case 'day':
|
|
190
172
|
case 'hour':
|
|
@@ -233,7 +215,7 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
|
|
|
233
215
|
if (Number(numberValue + '0') > segment.maxValue || newValue.length >= String(segment.maxValue).length) {
|
|
234
216
|
enteredKeys.current = '';
|
|
235
217
|
if (shouldSetValue) {
|
|
236
|
-
focusManager.focusNext(
|
|
218
|
+
focusManager.focusNext();
|
|
237
219
|
}
|
|
238
220
|
} else {
|
|
239
221
|
enteredKeys.current = newValue;
|
|
@@ -250,9 +232,11 @@ export function useDateSegment(segment: DateSegment, state: DateFieldState, ref:
|
|
|
250
232
|
// Safari requires that a selection is set or it won't fire input events.
|
|
251
233
|
// Since usePress disables text selection, this won't happen by default.
|
|
252
234
|
ref.current.style.webkitUserSelect = 'text';
|
|
235
|
+
ref.current.style.userSelect = 'text';
|
|
253
236
|
let selection = window.getSelection();
|
|
254
237
|
selection.collapse(ref.current);
|
|
255
|
-
ref.current.style.webkitUserSelect = '';
|
|
238
|
+
ref.current.style.webkitUserSelect = 'none';
|
|
239
|
+
ref.current.style.userSelect = 'none';
|
|
256
240
|
};
|
|
257
241
|
|
|
258
242
|
let compositionRef = useRef('');
|