@react-aria/table 3.8.2-nightly.3749 → 3.8.2-nightly.3757
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/import.mjs +60 -19
- package/dist/main.js +59 -18
- package/dist/main.js.map +1 -1
- package/dist/module.js +60 -19
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/useTableCell.ts +2 -0
- package/src/useTableColumnResize.ts +69 -24
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
import {ChangeEvent, Key, RefObject, useCallback, useRef} from 'react';
|
|
14
14
|
import {DOMAttributes, FocusableElement} from '@react-types/shared';
|
|
15
15
|
import {focusSafely} from '@react-aria/focus';
|
|
16
|
-
import {focusWithoutScrolling, mergeProps, useId} from '@react-aria/utils';
|
|
16
|
+
import {focusWithoutScrolling, mergeProps, useDescription, useId} from '@react-aria/utils';
|
|
17
17
|
import {getColumnHeaderId} from './utils';
|
|
18
18
|
import {GridNode} from '@react-types/grid';
|
|
19
19
|
// @ts-ignore
|
|
20
20
|
import intlMessages from '../intl/*.json';
|
|
21
21
|
import {TableColumnResizeState} from '@react-stately/table';
|
|
22
|
-
import {useKeyboard, useMove, usePress} from '@react-aria/interactions';
|
|
22
|
+
import {useInteractionModality, useKeyboard, useMove, usePress} from '@react-aria/interactions';
|
|
23
23
|
import {useLocale, useLocalizedStringFormatter} from '@react-aria/i18n';
|
|
24
24
|
|
|
25
25
|
export interface TableColumnResizeAria {
|
|
@@ -36,7 +36,8 @@ export interface AriaTableColumnResizeProps<T> {
|
|
|
36
36
|
label: string,
|
|
37
37
|
/**
|
|
38
38
|
* Ref to the trigger if resizing was started from a column header menu. If it's provided,
|
|
39
|
-
* focus will be returned there when resizing is done.
|
|
39
|
+
* focus will be returned there when resizing is done. If it isn't provided, it is assumed that the resizer is
|
|
40
|
+
* visible at all time and keyboard resizing is started via pressing Enter on the resizer and not on focus.
|
|
40
41
|
* */
|
|
41
42
|
triggerRef?: RefObject<FocusableElement>,
|
|
42
43
|
/** If resizing is disabled. */
|
|
@@ -63,14 +64,31 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
|
|
|
63
64
|
let id = useId();
|
|
64
65
|
let isResizing = useRef(false);
|
|
65
66
|
let lastSize = useRef(null);
|
|
67
|
+
let editModeEnabled = state.tableState.isKeyboardNavigationDisabled;
|
|
66
68
|
|
|
67
69
|
let {direction} = useLocale();
|
|
68
70
|
let {keyboardProps} = useKeyboard({
|
|
69
71
|
onKeyDown: (e) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
let resizeOnFocus = !!triggerRef?.current;
|
|
73
|
+
if (editModeEnabled) {
|
|
74
|
+
if (e.key === 'Escape' || e.key === 'Enter' || e.key === ' ' || e.key === 'Tab') {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
if (resizeOnFocus) {
|
|
77
|
+
// switch focus back to the column header on anything that ends edit mode
|
|
78
|
+
focusSafely(triggerRef.current);
|
|
79
|
+
} else {
|
|
80
|
+
endResize(item);
|
|
81
|
+
state.tableState.setKeyboardNavigationDisabled(false);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} else if (!resizeOnFocus) {
|
|
85
|
+
// Continue propagation on keydown events so they still bubbles to useSelectableCollection and are handled there
|
|
86
|
+
e.continuePropagation();
|
|
87
|
+
|
|
88
|
+
if (e.key === 'Enter') {
|
|
89
|
+
startResize(item);
|
|
90
|
+
state.tableState.setKeyboardNavigationDisabled(true);
|
|
91
|
+
}
|
|
74
92
|
}
|
|
75
93
|
}
|
|
76
94
|
});
|
|
@@ -91,10 +109,11 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
|
|
|
91
109
|
}, [onResize, state]);
|
|
92
110
|
|
|
93
111
|
let endResize = useCallback((item) => {
|
|
94
|
-
if (lastSize.current == null) {
|
|
95
|
-
lastSize.current = state.updateResizedColumns(item.key, state.getColumnWidth(item.key));
|
|
96
|
-
}
|
|
97
112
|
if (isResizing.current) {
|
|
113
|
+
if (lastSize.current == null) {
|
|
114
|
+
lastSize.current = state.updateResizedColumns(item.key, state.getColumnWidth(item.key));
|
|
115
|
+
}
|
|
116
|
+
|
|
98
117
|
state.endResize();
|
|
99
118
|
onResizeEnd?.(lastSize.current);
|
|
100
119
|
}
|
|
@@ -126,20 +145,31 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
|
|
|
126
145
|
}
|
|
127
146
|
},
|
|
128
147
|
onMoveEnd(e) {
|
|
148
|
+
let resizeOnFocus = !!triggerRef?.current;
|
|
129
149
|
let {pointerType} = e;
|
|
130
150
|
columnResizeWidthRef.current = 0;
|
|
131
|
-
if (pointerType === 'mouse') {
|
|
151
|
+
if (pointerType === 'mouse' || (pointerType === 'touch' && !resizeOnFocus)) {
|
|
132
152
|
endResize(item);
|
|
133
153
|
}
|
|
134
154
|
}
|
|
135
155
|
});
|
|
136
156
|
|
|
157
|
+
let onKeyDown = useCallback((e) => {
|
|
158
|
+
if (editModeEnabled) {
|
|
159
|
+
moveProps.onKeyDown(e);
|
|
160
|
+
}
|
|
161
|
+
}, [editModeEnabled, moveProps]);
|
|
162
|
+
|
|
163
|
+
|
|
137
164
|
let min = Math.floor(state.getColumnMinWidth(item.key));
|
|
138
165
|
let max = Math.floor(state.getColumnMaxWidth(item.key));
|
|
139
166
|
if (max === Infinity) {
|
|
140
167
|
max = Number.MAX_SAFE_INTEGER;
|
|
141
168
|
}
|
|
142
169
|
let value = Math.floor(state.getColumnWidth(item.key));
|
|
170
|
+
let modality = useInteractionModality();
|
|
171
|
+
let description = triggerRef?.current == null && (modality === 'keyboard' || modality === 'virtual') && !isResizing.current ? stringFormatter.format('resizerDescription') : undefined;
|
|
172
|
+
let descriptionProps = useDescription(description);
|
|
143
173
|
let ariaProps = {
|
|
144
174
|
'aria-label': props.label,
|
|
145
175
|
'aria-orientation': 'horizontal' as 'horizontal',
|
|
@@ -148,7 +178,8 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
|
|
|
148
178
|
'type': 'range',
|
|
149
179
|
min,
|
|
150
180
|
max,
|
|
151
|
-
value
|
|
181
|
+
value,
|
|
182
|
+
...descriptionProps
|
|
152
183
|
};
|
|
153
184
|
|
|
154
185
|
const focusInput = useCallback(() => {
|
|
@@ -175,21 +206,28 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
|
|
|
175
206
|
return;
|
|
176
207
|
}
|
|
177
208
|
if (e.pointerType === 'virtual' && state.resizingColumn != null) {
|
|
209
|
+
let resizeOnFocus = !!triggerRef?.current;
|
|
178
210
|
endResize(item);
|
|
179
|
-
if (
|
|
211
|
+
if (resizeOnFocus) {
|
|
180
212
|
focusSafely(triggerRef.current);
|
|
181
213
|
}
|
|
182
214
|
return;
|
|
183
215
|
}
|
|
216
|
+
|
|
217
|
+
// Sometimes onPress won't trigger for quick taps on mobile so we want to focus the input so blurring away
|
|
218
|
+
// can cancel resize mode for us.
|
|
184
219
|
focusInput();
|
|
220
|
+
|
|
221
|
+
// If resizer is always visible, mobile screenreader user can access the visually hidden resizer directly and thus we don't need
|
|
222
|
+
// to handle a virtual click to start the resizer.
|
|
223
|
+
if (e.pointerType !== 'virtual') {
|
|
224
|
+
startResize(item);
|
|
225
|
+
}
|
|
185
226
|
},
|
|
186
227
|
onPress: (e) => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (triggerRef?.current) {
|
|
191
|
-
focusSafely(triggerRef.current);
|
|
192
|
-
}
|
|
228
|
+
let resizeOnFocus = !!triggerRef?.current;
|
|
229
|
+
if (((e.pointerType === 'touch' && !resizeOnFocus) || e.pointerType === 'mouse') && state.resizingColumn != null) {
|
|
230
|
+
endResize(item);
|
|
193
231
|
}
|
|
194
232
|
}
|
|
195
233
|
});
|
|
@@ -197,17 +235,24 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
|
|
|
197
235
|
return {
|
|
198
236
|
resizerProps: mergeProps(
|
|
199
237
|
keyboardProps,
|
|
200
|
-
moveProps,
|
|
238
|
+
{...moveProps, onKeyDown},
|
|
201
239
|
pressProps
|
|
202
240
|
),
|
|
203
241
|
inputProps: mergeProps(
|
|
204
242
|
{
|
|
205
243
|
id,
|
|
244
|
+
// Override browser default margin. Without this, scrollIntoViewport will think we need to scroll the input into view
|
|
245
|
+
style: {
|
|
246
|
+
margin: '0px'
|
|
247
|
+
},
|
|
206
248
|
onFocus: () => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
249
|
+
let resizeOnFocus = !!triggerRef?.current;
|
|
250
|
+
if (resizeOnFocus) {
|
|
251
|
+
// useMove calls onMoveStart for every keypress, but we want resize start to only be called when we start resize mode
|
|
252
|
+
// call instead during focus and blur
|
|
253
|
+
startResize(item);
|
|
254
|
+
state.tableState.setKeyboardNavigationDisabled(true);
|
|
255
|
+
}
|
|
211
256
|
},
|
|
212
257
|
onBlur: () => {
|
|
213
258
|
endResize(item);
|