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