@octanejs/aria 0.0.46 → 0.0.47
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} +239 -259
- 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} +121 -64
- package/src/grid/utils.ts +1 -0
- package/src/gridlist/{useGridListItem.ts → useGridListItem.tsx} +152 -111
- 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 +217 -0
- package/src/menu/{useSubmenuTrigger.ts → useSubmenuTrigger.tsx} +112 -152
- package/src/numberfield/{useNumberField.ts → useNumberField.tsx} +185 -239
- 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} +72 -84
- 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} +83 -80
- package/src/searchfield/useSearchField.tsx +147 -0
- package/src/select/useSelect.ts +20 -20
- package/src/selection/useSelectableCollection.tsx +751 -0
- package/src/selection/useSelectableItem.ts +48 -11
- package/src/slider/{useSliderThumb.ts → useSliderThumb.tsx} +116 -159
- package/src/spinbutton/useSpinButton.tsx +330 -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 +354 -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 +3 -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,20 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import type {
|
|
1
|
+
/** @jsxImportSource octane */
|
|
2
|
+
// Ported from adobe/react-spectrum@5ecb3333001313e83898cd07644227897e3bae1f (packages/react-aria/src/menu/useSubmenuTrigger.ts).
|
|
3
|
+
/*
|
|
4
|
+
* Copyright 2023 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { AriaMenuItemProps } from './useMenuItem';
|
|
16
|
+
import { AriaMenuOptions } from './useMenu';
|
|
17
|
+
import type { AriaPopoverProps } from '../overlays/usePopover';
|
|
18
|
+
import { FocusableElement, FocusStrategy, Node, PressEvent, RefObject } from '@react-types/shared';
|
|
18
19
|
import { focusWithoutScrolling } from '../utils/focusWithoutScrolling';
|
|
19
20
|
import {
|
|
20
21
|
getActiveElement,
|
|
@@ -22,17 +23,16 @@ import {
|
|
|
22
23
|
isFocusWithin,
|
|
23
24
|
nodeContains,
|
|
24
25
|
} from '../utils/shadowdom/DOMFunctions';
|
|
25
|
-
import type {
|
|
26
|
-
import type { SubmenuTriggerState } from '../stately/
|
|
27
|
-
import { useCallback, useRef } from '
|
|
26
|
+
import type { OverlayProps } from '../overlays/Overlay';
|
|
27
|
+
import type { SubmenuTriggerState } from '../upstream-exports/react-stately/useMenuTriggerState';
|
|
28
|
+
import { useCallback, useRef } from '../compat/react';
|
|
28
29
|
import { useEvent } from '../utils/useEvent';
|
|
29
30
|
import { useId } from '../utils/useId';
|
|
31
|
+
import { useKeyboard } from '../interactions/useKeyboard';
|
|
30
32
|
import { useLayoutEffect } from '../utils/useLayoutEffect';
|
|
31
33
|
import { useLocale } from '../i18n/I18nProvider';
|
|
32
34
|
import { useSafelyMouseToSubmenu } from './useSafelyMouseToSubmenu';
|
|
33
35
|
|
|
34
|
-
import { S, splitSlot, subSlot } from '../internal';
|
|
35
|
-
|
|
36
36
|
export interface AriaSubmenuTriggerProps {
|
|
37
37
|
/**
|
|
38
38
|
* An object representing the submenu trigger menu item. Contains all the relevant information
|
|
@@ -40,7 +40,7 @@ export interface AriaSubmenuTriggerProps {
|
|
|
40
40
|
*
|
|
41
41
|
* @deprecated
|
|
42
42
|
*/
|
|
43
|
-
node?:
|
|
43
|
+
node?: Node<unknown>;
|
|
44
44
|
/** Whether the submenu trigger is disabled. */
|
|
45
45
|
isDisabled?: boolean;
|
|
46
46
|
/** The type of the contents that the submenu trigger opens. */
|
|
@@ -74,18 +74,9 @@ export interface SubmenuTriggerAria<T> {
|
|
|
74
74
|
submenuTriggerProps: SubmenuTriggerProps;
|
|
75
75
|
/** Props for the submenu controlled by the submenu trigger menu item. */
|
|
76
76
|
submenuProps: SubmenuProps<T>;
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
* octane adaptation: a structural equivalent of upstream's
|
|
81
|
-
* `Pick<AriaPopoverProps, 'isNonModal' | 'shouldCloseOnInteractOutside'> &
|
|
82
|
-
* Pick<OverlayProps, 'disableFocusManagement'>` (the overlays area is not yet ported).
|
|
83
|
-
*/
|
|
84
|
-
popoverProps: {
|
|
85
|
-
isNonModal?: boolean;
|
|
86
|
-
shouldCloseOnInteractOutside?: (element: Element) => boolean;
|
|
87
|
-
disableFocusManagement?: boolean;
|
|
88
|
-
};
|
|
77
|
+
/** Props for the submenu's popover container. */
|
|
78
|
+
popoverProps: Pick<AriaPopoverProps, 'isNonModal' | 'shouldCloseOnInteractOutside'> &
|
|
79
|
+
Pick<OverlayProps, 'disableFocusManagement'>;
|
|
89
80
|
}
|
|
90
81
|
|
|
91
82
|
/**
|
|
@@ -100,21 +91,8 @@ export function useSubmenuTrigger<T>(
|
|
|
100
91
|
props: AriaSubmenuTriggerProps,
|
|
101
92
|
state: SubmenuTriggerState,
|
|
102
93
|
ref: RefObject<FocusableElement | null>,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
export function useSubmenuTrigger<T>(
|
|
106
|
-
props: AriaSubmenuTriggerProps,
|
|
107
|
-
state: SubmenuTriggerState,
|
|
108
|
-
ref: RefObject<FocusableElement | null>,
|
|
109
|
-
slot: symbol | undefined,
|
|
110
|
-
): SubmenuTriggerAria<T>;
|
|
111
|
-
export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
112
|
-
const [user, slotArg] = splitSlot(args);
|
|
113
|
-
const slot = slotArg ?? S('useSubmenuTrigger');
|
|
114
|
-
const props = user[0] as AriaSubmenuTriggerProps;
|
|
115
|
-
const state = user[1] as SubmenuTriggerState;
|
|
116
|
-
const ref = user[2] as RefObject<FocusableElement | null>;
|
|
117
|
-
|
|
94
|
+
_slot?: symbol,
|
|
95
|
+
): SubmenuTriggerAria<T> {
|
|
118
96
|
let {
|
|
119
97
|
parentMenuRef,
|
|
120
98
|
submenuRef,
|
|
@@ -123,23 +101,16 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
123
101
|
delay = 200,
|
|
124
102
|
shouldUseVirtualFocus,
|
|
125
103
|
} = props;
|
|
126
|
-
let submenuTriggerId = useId(
|
|
127
|
-
let overlayId = useId(
|
|
128
|
-
let { direction } = useLocale(
|
|
129
|
-
let openTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
clearTimeout(openTimeout.current);
|
|
137
|
-
openTimeout.current = undefined;
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
[openTimeout],
|
|
141
|
-
subSlot(slot, 'cancelOpen'),
|
|
142
|
-
);
|
|
104
|
+
let submenuTriggerId = useId();
|
|
105
|
+
let overlayId = useId();
|
|
106
|
+
let { direction } = useLocale();
|
|
107
|
+
let openTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
|
108
|
+
let cancelOpenTimeout = useCallback(() => {
|
|
109
|
+
if (openTimeout.current) {
|
|
110
|
+
clearTimeout(openTimeout.current);
|
|
111
|
+
openTimeout.current = undefined;
|
|
112
|
+
}
|
|
113
|
+
}, [openTimeout]);
|
|
143
114
|
|
|
144
115
|
let onSubmenuOpen = useCallback(
|
|
145
116
|
(focusStrategy?: FocusStrategy) => {
|
|
@@ -147,74 +118,70 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
147
118
|
state.open(focusStrategy);
|
|
148
119
|
},
|
|
149
120
|
[state, cancelOpenTimeout],
|
|
150
|
-
subSlot(slot, 'open'),
|
|
151
121
|
);
|
|
152
122
|
|
|
153
|
-
let onSubmenuClose = useCallback(
|
|
154
|
-
()
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
},
|
|
158
|
-
[state, cancelOpenTimeout],
|
|
159
|
-
subSlot(slot, 'close'),
|
|
160
|
-
);
|
|
123
|
+
let onSubmenuClose = useCallback(() => {
|
|
124
|
+
cancelOpenTimeout();
|
|
125
|
+
state.close();
|
|
126
|
+
}, [state, cancelOpenTimeout]);
|
|
161
127
|
|
|
162
|
-
useLayoutEffect(
|
|
163
|
-
() => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
[cancelOpenTimeout],
|
|
169
|
-
subSlot(slot, 'teardown'),
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
let submenuKeyDown = (e: KeyboardEvent) => {
|
|
173
|
-
// If focus is not within the menu, assume virtual focus is being used.
|
|
174
|
-
// This means some other input element is also within the popover, so we shouldn't close the menu.
|
|
175
|
-
if (!isFocusWithin(e.currentTarget as Element)) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
128
|
+
useLayoutEffect(() => {
|
|
129
|
+
return () => {
|
|
130
|
+
cancelOpenTimeout();
|
|
131
|
+
};
|
|
132
|
+
}, [cancelOpenTimeout]);
|
|
178
133
|
|
|
179
|
-
|
|
180
|
-
|
|
134
|
+
let { keyboardProps } = useKeyboard({
|
|
135
|
+
shortcuts: {
|
|
136
|
+
ArrowLeft: (e) => {
|
|
137
|
+
// If focus is not within the menu, assume virtual focus is being used.
|
|
138
|
+
// This means some other input element is also within the popover, so we shouldn't close the menu.
|
|
139
|
+
if (!isFocusWithin(e.currentTarget as Element)) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
181
142
|
if (
|
|
182
143
|
direction === 'ltr' &&
|
|
183
|
-
nodeContains(e.currentTarget as
|
|
144
|
+
nodeContains(e.currentTarget as globalThis.Node, getEventTarget(e) as Element)
|
|
184
145
|
) {
|
|
185
|
-
e.preventDefault();
|
|
186
|
-
e.stopPropagation();
|
|
187
146
|
onSubmenuClose();
|
|
188
147
|
if (!shouldUseVirtualFocus && ref.current) {
|
|
189
148
|
focusWithoutScrolling(ref.current);
|
|
190
149
|
}
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
},
|
|
154
|
+
ArrowRight: (e) => {
|
|
155
|
+
if (!isFocusWithin(e.currentTarget as Element)) {
|
|
156
|
+
return false;
|
|
191
157
|
}
|
|
192
|
-
break;
|
|
193
|
-
case 'ArrowRight':
|
|
194
158
|
if (
|
|
195
159
|
direction === 'rtl' &&
|
|
196
|
-
nodeContains(e.currentTarget as
|
|
160
|
+
nodeContains(e.currentTarget as globalThis.Node, getEventTarget(e) as Element)
|
|
197
161
|
) {
|
|
198
|
-
e.preventDefault();
|
|
199
|
-
e.stopPropagation();
|
|
200
162
|
onSubmenuClose();
|
|
201
163
|
if (!shouldUseVirtualFocus && ref.current) {
|
|
202
164
|
focusWithoutScrolling(ref.current);
|
|
203
165
|
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
},
|
|
170
|
+
Escape: (e) => {
|
|
171
|
+
if (!isFocusWithin(e.currentTarget as Element)) {
|
|
172
|
+
return false;
|
|
204
173
|
}
|
|
205
|
-
break;
|
|
206
|
-
case 'Escape':
|
|
207
|
-
// TODO: can remove this when we fix collection event leaks
|
|
208
174
|
if (nodeContains(submenuRef.current, getEventTarget(e) as Element)) {
|
|
209
|
-
e.stopPropagation();
|
|
210
175
|
onSubmenuClose();
|
|
211
176
|
if (!shouldUseVirtualFocus && ref.current) {
|
|
212
177
|
focusWithoutScrolling(ref.current);
|
|
213
178
|
}
|
|
179
|
+
return;
|
|
214
180
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
181
|
+
return false;
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
218
185
|
|
|
219
186
|
let submenuProps = {
|
|
220
187
|
id: overlayId,
|
|
@@ -223,16 +190,15 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
223
190
|
...(type === 'menu' && {
|
|
224
191
|
onClose: state.closeAll,
|
|
225
192
|
autoFocus: state.focusStrategy ?? undefined,
|
|
226
|
-
|
|
193
|
+
...keyboardProps,
|
|
227
194
|
}),
|
|
228
195
|
};
|
|
229
196
|
|
|
230
|
-
let
|
|
231
|
-
|
|
232
|
-
|
|
197
|
+
let { keyboardProps: submenuTriggerKeyboardProps } = useKeyboard({
|
|
198
|
+
shortcuts: {
|
|
199
|
+
ArrowRight: () => {
|
|
233
200
|
if (!isDisabled) {
|
|
234
201
|
if (direction === 'ltr') {
|
|
235
|
-
e.preventDefault();
|
|
236
202
|
if (!state.isOpen) {
|
|
237
203
|
onSubmenuOpen('first');
|
|
238
204
|
}
|
|
@@ -240,18 +206,19 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
240
206
|
if (type === 'menu' && !!submenuRef?.current && getActiveElement() === ref?.current) {
|
|
241
207
|
focusWithoutScrolling(submenuRef.current);
|
|
242
208
|
}
|
|
209
|
+
return;
|
|
243
210
|
} else if (state.isOpen) {
|
|
244
211
|
onSubmenuClose();
|
|
212
|
+
return;
|
|
245
213
|
} else {
|
|
246
|
-
|
|
214
|
+
return false;
|
|
247
215
|
}
|
|
248
216
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
217
|
+
return false;
|
|
218
|
+
},
|
|
219
|
+
ArrowLeft: () => {
|
|
252
220
|
if (!isDisabled) {
|
|
253
221
|
if (direction === 'rtl') {
|
|
254
|
-
e.preventDefault();
|
|
255
222
|
if (!state.isOpen) {
|
|
256
223
|
onSubmenuOpen('first');
|
|
257
224
|
}
|
|
@@ -259,18 +226,18 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
259
226
|
if (type === 'menu' && !!submenuRef?.current && getActiveElement() === ref?.current) {
|
|
260
227
|
focusWithoutScrolling(submenuRef.current);
|
|
261
228
|
}
|
|
229
|
+
return;
|
|
262
230
|
} else if (state.isOpen) {
|
|
263
231
|
onSubmenuClose();
|
|
232
|
+
return;
|
|
264
233
|
} else {
|
|
265
|
-
|
|
234
|
+
return false;
|
|
266
235
|
}
|
|
267
236
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
};
|
|
237
|
+
return false;
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
});
|
|
274
241
|
|
|
275
242
|
let onPressStart = (e: PressEvent) => {
|
|
276
243
|
if (!isDisabled && (e.pointerType === 'virtual' || e.pointerType === 'keyboard')) {
|
|
@@ -301,22 +268,17 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
301
268
|
}
|
|
302
269
|
};
|
|
303
270
|
|
|
304
|
-
useEvent(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
(
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
onSubmenuClose();
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
|
-
subSlot(slot, 'focusin'),
|
|
319
|
-
);
|
|
271
|
+
useEvent(parentMenuRef, 'focusin', (e) => {
|
|
272
|
+
// If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in
|
|
273
|
+
// then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open
|
|
274
|
+
if (
|
|
275
|
+
state.isOpen &&
|
|
276
|
+
nodeContains(parentMenuRef.current, getEventTarget(e) as HTMLElement) &&
|
|
277
|
+
getEventTarget(e) !== ref.current
|
|
278
|
+
) {
|
|
279
|
+
onSubmenuClose();
|
|
280
|
+
}
|
|
281
|
+
});
|
|
320
282
|
|
|
321
283
|
let shouldCloseOnInteractOutside = (target: Element) => {
|
|
322
284
|
if (target !== ref.current) {
|
|
@@ -326,18 +288,17 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
326
288
|
return false;
|
|
327
289
|
};
|
|
328
290
|
|
|
329
|
-
useSafelyMouseToSubmenu(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
},
|
|
336
|
-
subSlot(slot, 'safeMouse'),
|
|
337
|
-
);
|
|
291
|
+
useSafelyMouseToSubmenu({
|
|
292
|
+
menuRef: parentMenuRef,
|
|
293
|
+
submenuRef,
|
|
294
|
+
isOpen: state.isOpen,
|
|
295
|
+
isDisabled: isDisabled,
|
|
296
|
+
});
|
|
338
297
|
|
|
339
298
|
return {
|
|
340
299
|
submenuTriggerProps: {
|
|
300
|
+
onKeyDown: submenuTriggerKeyboardProps.onKeyDown,
|
|
301
|
+
onKeyUp: submenuTriggerKeyboardProps.onKeyUp,
|
|
341
302
|
id: submenuTriggerId,
|
|
342
303
|
'aria-controls': state.isOpen ? overlayId : undefined,
|
|
343
304
|
'aria-haspopup': !isDisabled ? type : undefined,
|
|
@@ -345,7 +306,6 @@ export function useSubmenuTrigger(...args: any[]): SubmenuTriggerAria<any> {
|
|
|
345
306
|
onPressStart,
|
|
346
307
|
onPress,
|
|
347
308
|
onHoverChange,
|
|
348
|
-
onKeyDown: submenuTriggerKeyDown,
|
|
349
309
|
isOpen: state.isOpen,
|
|
350
310
|
},
|
|
351
311
|
submenuProps,
|