@octanejs/aria 0.0.46 → 0.0.48
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/README.md +7 -6
- package/UPSTREAM.md +58 -69
- package/package.json +11 -11
- package/src/calendar/useCalendarGrid.tsx +64 -62
- package/src/collections/Document.ts +3 -0
- package/src/color/useColorArea.tsx +95 -69
- package/src/color/useColorWheel.tsx +38 -37
- package/src/combobox/{useComboBox.ts → useComboBox.tsx} +243 -258
- package/src/components/ComboBox.ts +35 -2
- package/src/components/Dialog.ts +12 -1
- package/src/components/DropZone.tsx +3 -2
- package/src/components/FileTrigger.tsx +1 -0
- package/src/components/GridList.ts +11 -2
- package/src/components/ListBox.ts +1 -1
- package/src/components/Menu.ts +1 -0
- package/src/components/Meter.ts +3 -1
- package/src/components/Popover.ts +20 -8
- package/src/components/PreviewTrigger.tsx +101 -0
- package/src/components/ProgressBar.ts +10 -2
- package/src/components/Select.ts +1 -1
- package/src/components/Table.ts +26 -15
- package/src/components/TokenField.tsx +395 -0
- package/src/components/Tooltip.ts +4 -6
- package/src/components/Tree.ts +14 -7
- package/src/components/Virtualizer.tsx +30 -14
- package/src/components/index.ts +22 -0
- package/src/components/utils.ts +1 -1
- package/src/datepicker/useDateField.tsx +2 -11
- package/src/datepicker/useDatePickerGroup.tsx +44 -33
- package/src/datepicker/useDateSegment.tsx +31 -30
- package/src/dialog/useDialog.ts +8 -1
- package/src/dnd/DragManager.tsx +5 -1
- package/src/dnd/useDrag.tsx +2 -1
- package/src/focus/FocusScope.ts +2 -2
- package/src/grid/useGrid.ts +3 -0
- package/src/grid/{useGridCell.ts → useGridCell.tsx} +128 -66
- package/src/grid/utils.ts +1 -0
- package/src/gridlist/{useGridListItem.ts → useGridListItem.tsx} +154 -112
- package/src/index.ts +22 -0
- package/src/interactions/createEventHandler.ts +11 -8
- package/src/interactions/createKeyboardShortcutHandler.tsx +218 -0
- package/src/interactions/textSelection.ts +3 -3
- package/src/interactions/useContextMenu.tsx +125 -0
- package/src/interactions/useFocusVisible.ts +4 -4
- package/src/interactions/useKeyboard.ts +50 -2
- package/src/interactions/useLongPress.ts +33 -22
- package/src/interactions/useMove.ts +6 -6
- package/src/interactions/usePress.ts +8 -0
- package/src/interactions/utils.ts +10 -10
- package/src/intl/combobox/fi-FI.json +2 -2
- package/src/intl/previewtrigger/ar-AE.json +3 -0
- package/src/intl/previewtrigger/bg-BG.json +3 -0
- package/src/intl/previewtrigger/cs-CZ.json +3 -0
- package/src/intl/previewtrigger/da-DK.json +3 -0
- package/src/intl/previewtrigger/de-DE.json +3 -0
- package/src/intl/previewtrigger/el-GR.json +3 -0
- package/src/intl/previewtrigger/en-US.json +3 -0
- package/src/intl/previewtrigger/es-ES.json +3 -0
- package/src/intl/previewtrigger/et-EE.json +3 -0
- package/src/intl/previewtrigger/fi-FI.json +3 -0
- package/src/intl/previewtrigger/fr-FR.json +3 -0
- package/src/intl/previewtrigger/he-IL.json +3 -0
- package/src/intl/previewtrigger/hr-HR.json +3 -0
- package/src/intl/previewtrigger/hu-HU.json +3 -0
- package/src/intl/previewtrigger/index.ts +73 -0
- package/src/intl/previewtrigger/it-IT.json +3 -0
- package/src/intl/previewtrigger/ja-JP.json +3 -0
- package/src/intl/previewtrigger/ko-KR.json +3 -0
- package/src/intl/previewtrigger/lt-LT.json +3 -0
- package/src/intl/previewtrigger/lv-LV.json +3 -0
- package/src/intl/previewtrigger/nb-NO.json +3 -0
- package/src/intl/previewtrigger/nl-NL.json +3 -0
- package/src/intl/previewtrigger/pl-PL.json +3 -0
- package/src/intl/previewtrigger/pt-BR.json +3 -0
- package/src/intl/previewtrigger/pt-PT.json +3 -0
- package/src/intl/previewtrigger/ro-RO.json +3 -0
- package/src/intl/previewtrigger/ru-RU.json +3 -0
- package/src/intl/previewtrigger/sk-SK.json +3 -0
- package/src/intl/previewtrigger/sl-SI.json +3 -0
- package/src/intl/previewtrigger/sr-SP.json +3 -0
- package/src/intl/previewtrigger/sv-SE.json +3 -0
- package/src/intl/previewtrigger/tr-TR.json +3 -0
- package/src/intl/previewtrigger/uk-UA.json +3 -0
- package/src/intl/previewtrigger/zh-CN.json +3 -0
- package/src/intl/previewtrigger/zh-TW.json +3 -0
- package/src/intl/table/ar-AE.json +3 -3
- package/src/intl/table/bg-BG.json +3 -3
- package/src/intl/table/cs-CZ.json +3 -3
- package/src/intl/table/da-DK.json +3 -3
- package/src/intl/table/de-DE.json +3 -3
- package/src/intl/table/el-GR.json +3 -3
- package/src/intl/table/es-ES.json +3 -3
- package/src/intl/table/et-EE.json +3 -3
- package/src/intl/table/fi-FI.json +3 -3
- package/src/intl/table/fr-FR.json +3 -3
- package/src/intl/table/he-IL.json +3 -3
- package/src/intl/table/hr-HR.json +3 -3
- package/src/intl/table/hu-HU.json +3 -3
- package/src/intl/table/it-IT.json +3 -3
- package/src/intl/table/ja-JP.json +3 -3
- package/src/intl/table/ko-KR.json +3 -3
- package/src/intl/table/lt-LT.json +3 -3
- package/src/intl/table/lv-LV.json +3 -3
- package/src/intl/table/nb-NO.json +3 -3
- package/src/intl/table/nl-NL.json +3 -3
- package/src/intl/table/pl-PL.json +3 -3
- package/src/intl/table/pt-BR.json +3 -3
- package/src/intl/table/pt-PT.json +3 -3
- package/src/intl/table/ro-RO.json +3 -3
- package/src/intl/table/ru-RU.json +3 -3
- package/src/intl/table/sk-SK.json +3 -3
- package/src/intl/table/sl-SI.json +3 -3
- package/src/intl/table/sr-SP.json +3 -3
- package/src/intl/table/sv-SE.json +3 -3
- package/src/intl/table/tr-TR.json +3 -3
- package/src/intl/table/uk-UA.json +3 -3
- package/src/intl/table/zh-CN.json +4 -4
- package/src/intl/table/zh-TW.json +3 -3
- package/src/intl/tree/es-ES.json +1 -1
- package/src/link/useLink.ts +2 -0
- package/src/menu/useMenuItem.ts +33 -36
- package/src/menu/useMenuTrigger.tsx +222 -0
- package/src/menu/{useSubmenuTrigger.ts → useSubmenuTrigger.tsx} +116 -151
- package/src/numberfield/{useNumberField.ts → useNumberField.tsx} +188 -238
- package/src/overlays/Overlay.ts +5 -1
- package/src/overlays/ariaHideOutside.ts +6 -8
- package/src/overlays/useCloseOnScroll.ts +7 -5
- package/src/overlays/{useOverlay.ts → useOverlay.tsx} +76 -83
- package/src/overlays/usePopover.ts +10 -5
- package/src/overlays/usePreventScroll.ts +4 -4
- package/src/progress/useProgressBar.ts +2 -1
- package/src/radio/{useRadioGroup.ts → useRadioGroup.tsx} +87 -79
- package/src/searchfield/useSearchField.tsx +152 -0
- package/src/select/useSelect.ts +20 -20
- package/src/selection/useSelectableCollection.tsx +755 -0
- package/src/selection/useSelectableItem.ts +48 -11
- package/src/slider/{useSliderThumb.ts → useSliderThumb.tsx} +120 -158
- package/src/spinbutton/useSpinButton.tsx +335 -0
- package/src/stately/combobox/useComboBoxState.ts +1 -1
- package/src/stately/grid/useGridState.ts +9 -10
- package/src/stately/index.ts +11 -0
- package/src/stately/menu/useMenuTriggerState.ts +1 -1
- package/src/stately/menu/useSubmenuTriggerState.ts +2 -0
- package/src/stately/overlays/useOverlayTriggerState.ts +12 -1
- package/src/stately/radio/useRadioGroupState.ts +5 -1
- package/src/stately/table/TableUtils.ts +15 -1
- package/src/stately/table/useTableState.ts +7 -0
- package/src/stately/tokenfield/TokenFieldValue.tsx +440 -0
- package/src/stately/tokenfield/useTokenFieldState.tsx +57 -0
- package/src/stately/tooltip/useTooltipTriggerState.ts +16 -7
- package/src/stately/virtualizer/Layout.tsx +2 -0
- package/src/stately/virtualizer/ScrollAnchor.tsx +338 -0
- package/src/stately/virtualizer/Virtualizer.tsx +52 -1
- package/src/stately/virtualizer/types.tsx +2 -0
- package/src/table/useTableCell.ts +12 -0
- package/src/table/useTableColumnHeader.ts +8 -1
- package/src/table/useTableColumnResize.tsx +359 -0
- package/src/tag/useTag.ts +22 -15
- package/src/textfield/useTextField.ts +2 -0
- package/src/tokenfield/useToken.tsx +64 -0
- package/src/tokenfield/useTokenField.tsx +849 -0
- package/src/tooltip/usePreviewTrigger.tsx +266 -0
- package/src/tooltip/useSafeArea.tsx +171 -0
- package/src/upstream-exports/react-aria/mergeRefs.tsx +3 -0
- package/src/upstream-exports/react-aria/usePreviewTrigger.tsx +18 -0
- package/src/upstream-exports/react-aria/useTokenField.tsx +22 -0
- package/src/upstream-exports/react-stately/private/collections/getChildNodes.tsx +8 -0
- package/src/upstream-exports/react-stately/private/collections/getItemCount.tsx +2 -0
- package/src/upstream-exports/react-stately/private/grid/GridCollection.tsx +7 -0
- package/src/upstream-exports/react-stately/private/grid/useGridState.tsx +6 -0
- package/src/upstream-exports/react-stately/private/utils/number.tsx +2 -0
- package/src/upstream-exports/react-stately/useComboBoxState.tsx +23 -0
- package/src/upstream-exports/react-stately/useListState.tsx +15 -0
- package/src/upstream-exports/react-stately/useMenuTriggerState.tsx +26 -0
- package/src/upstream-exports/react-stately/useMultipleSelectionState.tsx +21 -0
- package/src/upstream-exports/react-stately/useNumberFieldState.tsx +20 -0
- package/src/upstream-exports/react-stately/useOverlayTriggerState.tsx +20 -0
- package/src/upstream-exports/react-stately/useRadioGroupState.tsx +16 -0
- package/src/upstream-exports/react-stately/useSearchFieldState.tsx +19 -0
- package/src/upstream-exports/react-stately/useSliderState.tsx +20 -0
- package/src/upstream-exports/react-stately/useTableState.tsx +45 -0
- package/src/upstream-exports/react-stately/useTokenFieldState.tsx +25 -0
- package/src/upstream-exports/react-stately/useTooltipTriggerState.tsx +20 -0
- package/src/upstream-exports/react-stately/useTreeState.tsx +14 -0
- package/src/utils/domHelpers.ts +74 -17
- package/src/utils/isVirtualEvent.ts +2 -1
- package/src/utils/openLink.ts +8 -3
- package/src/utils/platform.ts +7 -3
- package/src/utils/scrollIntoView.ts +4 -4
- package/src/utils/shadowdom/DOMFunctions.ts +42 -2
- package/src/utils/useId.ts +11 -2
- package/src/utils/useLoadMoreSentinel.ts +8 -3
- package/src/utils/useViewportSize.ts +3 -3
- package/src/virtualizer/ScrollView.tsx +13 -4
- package/src/virtualizer/VirtualizerItem.tsx +4 -1
- package/src/virtualizer/useVirtualizerItem.tsx +43 -3
- package/src/menu/useMenuTrigger.ts +0 -189
- package/src/searchfield/useSearchField.ts +0 -156
- package/src/selection/useSelectableCollection.ts +0 -750
- package/src/spinbutton/useSpinButton.ts +0 -380
- package/src/table/useTableColumnResize.ts +0 -374
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
/** @jsxImportSource octane */
|
|
2
|
+
type DOMAttributes = Record<string, any>;
|
|
3
|
+
// Ported from adobe/react-spectrum@5ecb3333001313e83898cd07644227897e3bae1f (packages/react-aria/src/grid/useGridCell.ts).
|
|
4
|
+
/*
|
|
5
|
+
* Copyright 2020 Adobe. All rights reserved.
|
|
6
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
8
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
11
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
12
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
|
+
* governing permissions and limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { FocusableElement, Key, RefObject } from '@react-types/shared';
|
|
17
|
+
import { withSlot } from 'octane';
|
|
12
18
|
import { focusSafely } from '../interactions/focusSafely';
|
|
13
19
|
import {
|
|
14
20
|
getActiveElement,
|
|
@@ -17,23 +23,21 @@ import {
|
|
|
17
23
|
nodeContains,
|
|
18
24
|
} from '../utils/shadowdom/DOMFunctions';
|
|
19
25
|
import { getFocusableTreeWalker } from '../focus/FocusScope';
|
|
26
|
+
import { getOwnerDocument } from '../utils/domHelpers';
|
|
20
27
|
import { getScrollParent } from '../utils/getScrollParent';
|
|
21
|
-
import
|
|
28
|
+
import {
|
|
29
|
+
IGridCollection as GridCollection,
|
|
30
|
+
GridNode,
|
|
31
|
+
} from '../upstream-exports/react-stately/private/grid/GridCollection';
|
|
22
32
|
import { gridMap } from './utils';
|
|
23
|
-
import
|
|
33
|
+
import { GridState } from '../upstream-exports/react-stately/private/grid/useGridState';
|
|
24
34
|
import { isFocusVisible } from '../interactions/useFocusVisible';
|
|
25
35
|
import { mergeProps } from '../utils/mergeProps';
|
|
26
|
-
import { useRef } from '
|
|
36
|
+
import { KeyboardEvent as ReactKeyboardEvent, useRef } from '../compat/react';
|
|
27
37
|
import { scrollIntoViewport } from '../utils/scrollIntoView';
|
|
28
38
|
import { useLocale } from '../i18n/I18nProvider';
|
|
29
39
|
import { useSelectableItem } from '../selection/useSelectableItem';
|
|
30
40
|
|
|
31
|
-
import { S, splitSlot, subSlot } from '../internal';
|
|
32
|
-
|
|
33
|
-
// octane adaptation: minimal structural DOMAttributes (upstream's drags React's synthetic
|
|
34
|
-
// handler types along).
|
|
35
|
-
type DOMAttributes = Record<string, any>;
|
|
36
|
-
|
|
37
41
|
export interface GridCellProps {
|
|
38
42
|
/**
|
|
39
43
|
* An object representing the grid cell. Contains all the relevant information that makes up the
|
|
@@ -44,9 +48,16 @@ export interface GridCellProps {
|
|
|
44
48
|
isVirtualized?: boolean;
|
|
45
49
|
/**
|
|
46
50
|
* Whether the cell or its first focusable child element should be focused when the grid cell is
|
|
47
|
-
* focused.
|
|
51
|
+
* focused. Defaults to 'child' in arrow keyboard navigation mode and 'cell' in
|
|
52
|
+
* tab keyboard navigation mode.
|
|
48
53
|
*/
|
|
49
54
|
focusMode?: 'child' | 'cell';
|
|
55
|
+
/**
|
|
56
|
+
* Whether the cell should support arrow key navigation even when the containing collection uses
|
|
57
|
+
* tab keyboard navigation. Allows users to navigate between rows and cells with arrow keys while
|
|
58
|
+
* focus is on an interactive child element within the cell.
|
|
59
|
+
*/
|
|
60
|
+
allowsArrowNavigation?: boolean;
|
|
50
61
|
/** Whether selection should occur on press up instead of press down. */
|
|
51
62
|
shouldSelectOnPressUp?: boolean;
|
|
52
63
|
/** Indicates how many columns the data cell spans. */
|
|
@@ -77,32 +88,32 @@ export function useGridCell<T, C extends GridCollection<T>>(
|
|
|
77
88
|
props: GridCellProps,
|
|
78
89
|
state: GridState<T, C>,
|
|
79
90
|
ref: RefObject<FocusableElement | null>,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let {
|
|
96
|
-
|
|
97
|
-
let { direction } = useLocale(subSlot(slot, 'locale'));
|
|
91
|
+
_slot?: symbol,
|
|
92
|
+
): GridCellAria {
|
|
93
|
+
if (_slot !== undefined) {
|
|
94
|
+
return withSlot(_slot, useGridCell<T, C>, props, state, ref);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let {
|
|
98
|
+
node,
|
|
99
|
+
isVirtualized,
|
|
100
|
+
focusMode: focusModeProp,
|
|
101
|
+
allowsArrowNavigation,
|
|
102
|
+
shouldSelectOnPressUp,
|
|
103
|
+
onAction,
|
|
104
|
+
} = props;
|
|
105
|
+
|
|
106
|
+
let { direction } = useLocale();
|
|
98
107
|
let {
|
|
99
108
|
keyboardDelegate,
|
|
100
109
|
actions: { onCellAction },
|
|
110
|
+
keyboardNavigationBehavior,
|
|
101
111
|
} = gridMap.get(state)!;
|
|
112
|
+
let focusMode = focusModeProp ?? (keyboardNavigationBehavior === 'tab' ? 'cell' : 'child');
|
|
102
113
|
|
|
103
114
|
// We need to track the key of the item at the time it was last focused so that we force
|
|
104
115
|
// focus to go to the item when the DOM node is reused for a different item in a virtualizer.
|
|
105
|
-
let keyWhenFocused = useRef<Key | null>(null
|
|
116
|
+
let keyWhenFocused = useRef<Key | null>(null);
|
|
106
117
|
|
|
107
118
|
// Handles focusing the cell. If there is a focusable child,
|
|
108
119
|
// it is focused, otherwise the cell itself is focused.
|
|
@@ -111,7 +122,10 @@ export function useGridCell(...args: any[]): GridCellAria {
|
|
|
111
122
|
let treeWalker = getFocusableTreeWalker(ref.current);
|
|
112
123
|
if (focusMode === 'child') {
|
|
113
124
|
// If focus is already on a focusable child within the cell, early return so we don't shift focus
|
|
114
|
-
if (
|
|
125
|
+
if (
|
|
126
|
+
isFocusWithin(ref.current) &&
|
|
127
|
+
ref.current !== getActiveElement(getOwnerDocument(ref.current))
|
|
128
|
+
) {
|
|
115
129
|
return;
|
|
116
130
|
}
|
|
117
131
|
|
|
@@ -134,24 +148,21 @@ export function useGridCell(...args: any[]): GridCellAria {
|
|
|
134
148
|
}
|
|
135
149
|
};
|
|
136
150
|
|
|
137
|
-
let { itemProps, isPressed } = useSelectableItem(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
let onKeyDownCapture = (e: KeyboardEvent) => {
|
|
152
|
-
let activeElement = getActiveElement();
|
|
151
|
+
let { itemProps, isPressed } = useSelectableItem({
|
|
152
|
+
selectionManager: state.selectionManager,
|
|
153
|
+
key: node.key,
|
|
154
|
+
ref,
|
|
155
|
+
isVirtualized,
|
|
156
|
+
focus,
|
|
157
|
+
shouldSelectOnPressUp,
|
|
158
|
+
onAction: onCellAction ? () => onCellAction(node.key) : onAction,
|
|
159
|
+
isDisabled: state.collection.size === 0,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
let onKeyDownCapture = (e: ReactKeyboardEvent) => {
|
|
163
|
+
let activeElement = getActiveElement(getOwnerDocument(ref.current));
|
|
153
164
|
if (
|
|
154
|
-
!nodeContains(e.currentTarget as
|
|
165
|
+
!nodeContains(e.currentTarget as Node, getEventTarget(e) as Element) ||
|
|
155
166
|
state.isKeyboardNavigationDisabled ||
|
|
156
167
|
!ref.current ||
|
|
157
168
|
!activeElement
|
|
@@ -191,7 +202,6 @@ export function useGridCell(...args: any[]): GridCellAria {
|
|
|
191
202
|
// We prevent the capturing event from reaching children of the cell, e.g. pickers.
|
|
192
203
|
// We want arrow keys to navigate to the next cell instead. We need to re-dispatch
|
|
193
204
|
// the event from a higher parent so it still bubbles and gets handled by useSelectableCollection.
|
|
194
|
-
// octane adaptation: the native event IS `e.nativeEvent`.
|
|
195
205
|
ref.current.parentElement?.dispatchEvent(new KeyboardEvent(e.type, e));
|
|
196
206
|
break;
|
|
197
207
|
}
|
|
@@ -232,7 +242,6 @@ export function useGridCell(...args: any[]): GridCellAria {
|
|
|
232
242
|
// We prevent the capturing event from reaching children of the cell, e.g. pickers.
|
|
233
243
|
// We want arrow keys to navigate to the next cell instead. We need to re-dispatch
|
|
234
244
|
// the event from a higher parent so it still bubbles and gets handled by useSelectableCollection.
|
|
235
|
-
// octane adaptation: the native event IS `e.nativeEvent`.
|
|
236
245
|
ref.current.parentElement?.dispatchEvent(new KeyboardEvent(e.type, e));
|
|
237
246
|
break;
|
|
238
247
|
}
|
|
@@ -260,13 +269,47 @@ export function useGridCell(...args: any[]): GridCellAria {
|
|
|
260
269
|
if (!e.altKey && nodeContains(ref.current, getEventTarget(e) as Element)) {
|
|
261
270
|
e.stopPropagation();
|
|
262
271
|
e.preventDefault();
|
|
263
|
-
// octane adaptation: the native event IS `e.nativeEvent`.
|
|
264
272
|
ref.current.parentElement?.dispatchEvent(new KeyboardEvent(e.type, e));
|
|
265
273
|
}
|
|
266
274
|
break;
|
|
267
275
|
}
|
|
268
276
|
};
|
|
269
277
|
|
|
278
|
+
let onKeyDown = (e: ReactKeyboardEvent) => {
|
|
279
|
+
let activeElement = getActiveElement(getOwnerDocument(ref.current));
|
|
280
|
+
if (
|
|
281
|
+
!nodeContains(e.currentTarget as Node, getEventTarget(e) as Element) ||
|
|
282
|
+
state.isKeyboardNavigationDisabled ||
|
|
283
|
+
!ref.current ||
|
|
284
|
+
!activeElement
|
|
285
|
+
) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (keyboardNavigationBehavior === 'tab') {
|
|
290
|
+
if (getEventTarget(e) !== ref.current && e.key !== 'Tab') {
|
|
291
|
+
e.stopPropagation();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
switch (e.key) {
|
|
297
|
+
case 'Tab': {
|
|
298
|
+
if (keyboardNavigationBehavior === 'tab') {
|
|
299
|
+
// If there is another focusable element within this item, stop propagation so the tab key
|
|
300
|
+
// is handled by the browser and not by useSelectableCollection (which would take us out of the list).
|
|
301
|
+
let walker = getFocusableTreeWalker(ref.current, { tabbable: true });
|
|
302
|
+
walker.currentNode = activeElement;
|
|
303
|
+
let next = e.shiftKey ? walker.previousNode() : walker.nextNode();
|
|
304
|
+
|
|
305
|
+
if (next) {
|
|
306
|
+
e.stopPropagation();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
|
|
270
313
|
// Grid cells can have focusable elements inside them. In this case, focus should
|
|
271
314
|
// be marshalled to that element rather than focusing the cell itself.
|
|
272
315
|
let onFocus = (e: FocusEvent) => {
|
|
@@ -284,22 +327,41 @@ export function useGridCell(...args: any[]): GridCellAria {
|
|
|
284
327
|
return;
|
|
285
328
|
}
|
|
286
329
|
|
|
287
|
-
//
|
|
330
|
+
// if focus goes back to cell from child, make sure we don't refocus the cell if we are in focusMode=child
|
|
331
|
+
// since that would be a focus trap
|
|
332
|
+
if (
|
|
333
|
+
focusMode === 'child' &&
|
|
334
|
+
e.relatedTarget &&
|
|
335
|
+
nodeContains(ref.current, e.relatedTarget as Element)
|
|
336
|
+
) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// If the cell itself is focused, wait a frame so that focus finishes propagating
|
|
288
341
|
// up to the tree, and move focus to a focusable child if possible.
|
|
289
342
|
requestAnimationFrame(() => {
|
|
290
|
-
if (
|
|
343
|
+
if (
|
|
344
|
+
focusMode === 'child' &&
|
|
345
|
+
getActiveElement(getOwnerDocument(ref.current)) === ref.current
|
|
346
|
+
) {
|
|
291
347
|
focus();
|
|
292
348
|
}
|
|
293
349
|
});
|
|
294
350
|
};
|
|
295
351
|
|
|
352
|
+
// oxlint-disable-next-line react/react-compiler
|
|
296
353
|
let gridCellProps: DOMAttributes = mergeProps(itemProps, {
|
|
297
354
|
role: 'gridcell',
|
|
298
|
-
onKeyDownCapture
|
|
355
|
+
onKeyDownCapture:
|
|
356
|
+
keyboardNavigationBehavior !== 'tab' || allowsArrowNavigation ? onKeyDownCapture : undefined,
|
|
357
|
+
onKeyDown: keyboardNavigationBehavior === 'tab' ? onKeyDown : undefined,
|
|
299
358
|
'aria-colspan': node.colSpan,
|
|
300
359
|
'aria-colindex': node.colIndex != null ? node.colIndex + 1 : undefined, // aria-colindex is 1-based
|
|
301
360
|
colSpan: isVirtualized ? undefined : node.colSpan,
|
|
302
361
|
onFocus,
|
|
362
|
+
// make sure shift tabbing from a child of a cell doesnt move focus back to cell if focusMode="child" and in tab nav
|
|
363
|
+
// consistent with arrow nav and focusMode="child" since you can't go back to the cell there either
|
|
364
|
+
...(focusMode === 'child' && keyboardNavigationBehavior === 'tab' ? { tabIndex: -1 } : {}),
|
|
303
365
|
});
|
|
304
366
|
|
|
305
367
|
if (isVirtualized) {
|
|
@@ -315,8 +377,8 @@ export function useGridCell(...args: any[]): GridCellAria {
|
|
|
315
377
|
gridCellProps.tabIndex != null &&
|
|
316
378
|
gridCellProps.onPointerDown == null
|
|
317
379
|
) {
|
|
318
|
-
gridCellProps.onPointerDown = (e: PointerEvent) => {
|
|
319
|
-
let el = e.currentTarget
|
|
380
|
+
gridCellProps.onPointerDown = (e: import('octane').PointerEvent<HTMLElement>) => {
|
|
381
|
+
let el = e.currentTarget;
|
|
320
382
|
let tabindex = el.getAttribute('tabindex');
|
|
321
383
|
el.removeAttribute('tabindex');
|
|
322
384
|
requestAnimationFrame(() => {
|