@react-spectrum/menu 3.22.11 → 3.23.0
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 +6 -8
- package/dist/main.js +12 -14
- package/dist/main.js.map +1 -1
- package/dist/module.js +6 -8
- package/dist/module.js.map +1 -1
- package/dist/types/src/index.d.ts +8 -0
- package/package.json +14 -46
- package/src/index.ts +9 -9
- package/dist/ActionMenu.main.js +0 -67
- package/dist/ActionMenu.main.js.map +0 -1
- package/dist/ActionMenu.mjs +0 -62
- package/dist/ActionMenu.module.js +0 -62
- package/dist/ActionMenu.module.js.map +0 -1
- package/dist/ContextualHelpTrigger.main.js +0 -192
- package/dist/ContextualHelpTrigger.main.js.map +0 -1
- package/dist/ContextualHelpTrigger.mjs +0 -187
- package/dist/ContextualHelpTrigger.module.js +0 -187
- package/dist/ContextualHelpTrigger.module.js.map +0 -1
- package/dist/Menu.main.js +0 -235
- package/dist/Menu.main.js.map +0 -1
- package/dist/Menu.mjs +0 -229
- package/dist/Menu.module.js +0 -229
- package/dist/Menu.module.js.map +0 -1
- package/dist/MenuItem.main.js +0 -149
- package/dist/MenuItem.main.js.map +0 -1
- package/dist/MenuItem.mjs +0 -144
- package/dist/MenuItem.module.js +0 -144
- package/dist/MenuItem.module.js.map +0 -1
- package/dist/MenuSection.main.js +0 -81
- package/dist/MenuSection.main.js.map +0 -1
- package/dist/MenuSection.mjs +0 -76
- package/dist/MenuSection.module.js +0 -76
- package/dist/MenuSection.module.js.map +0 -1
- package/dist/MenuTrigger.main.js +0 -128
- package/dist/MenuTrigger.main.js.map +0 -1
- package/dist/MenuTrigger.mjs +0 -123
- package/dist/MenuTrigger.module.js +0 -123
- package/dist/MenuTrigger.module.js.map +0 -1
- package/dist/SubmenuTrigger.main.js +0 -154
- package/dist/SubmenuTrigger.main.js.map +0 -1
- package/dist/SubmenuTrigger.mjs +0 -149
- package/dist/SubmenuTrigger.module.js +0 -149
- package/dist/SubmenuTrigger.module.js.map +0 -1
- package/dist/ar-AE.main.js +0 -8
- package/dist/ar-AE.main.js.map +0 -1
- package/dist/ar-AE.mjs +0 -10
- package/dist/ar-AE.module.js +0 -10
- package/dist/ar-AE.module.js.map +0 -1
- package/dist/bg-BG.main.js +0 -8
- package/dist/bg-BG.main.js.map +0 -1
- package/dist/bg-BG.mjs +0 -10
- package/dist/bg-BG.module.js +0 -10
- package/dist/bg-BG.module.js.map +0 -1
- package/dist/context.main.js +0 -43
- package/dist/context.main.js.map +0 -1
- package/dist/context.mjs +0 -29
- package/dist/context.module.js +0 -29
- package/dist/context.module.js.map +0 -1
- package/dist/contextualhelp_vars_css.main.js +0 -23
- package/dist/contextualhelp_vars_css.main.js.map +0 -1
- package/dist/contextualhelp_vars_css.mjs +0 -25
- package/dist/contextualhelp_vars_css.module.js +0 -25
- package/dist/contextualhelp_vars_css.module.js.map +0 -1
- package/dist/cs-CZ.main.js +0 -8
- package/dist/cs-CZ.main.js.map +0 -1
- package/dist/cs-CZ.mjs +0 -10
- package/dist/cs-CZ.module.js +0 -10
- package/dist/cs-CZ.module.js.map +0 -1
- package/dist/da-DK.main.js +0 -8
- package/dist/da-DK.main.js.map +0 -1
- package/dist/da-DK.mjs +0 -10
- package/dist/da-DK.module.js +0 -10
- package/dist/da-DK.module.js.map +0 -1
- package/dist/de-DE.main.js +0 -8
- package/dist/de-DE.main.js.map +0 -1
- package/dist/de-DE.mjs +0 -10
- package/dist/de-DE.module.js +0 -10
- package/dist/de-DE.module.js.map +0 -1
- package/dist/el-GR.main.js +0 -8
- package/dist/el-GR.main.js.map +0 -1
- package/dist/el-GR.mjs +0 -10
- package/dist/el-GR.module.js +0 -10
- package/dist/el-GR.module.js.map +0 -1
- package/dist/en-US.main.js +0 -8
- package/dist/en-US.main.js.map +0 -1
- package/dist/en-US.mjs +0 -10
- package/dist/en-US.module.js +0 -10
- package/dist/en-US.module.js.map +0 -1
- package/dist/es-ES.main.js +0 -8
- package/dist/es-ES.main.js.map +0 -1
- package/dist/es-ES.mjs +0 -10
- package/dist/es-ES.module.js +0 -10
- package/dist/es-ES.module.js.map +0 -1
- package/dist/et-EE.main.js +0 -8
- package/dist/et-EE.main.js.map +0 -1
- package/dist/et-EE.mjs +0 -10
- package/dist/et-EE.module.js +0 -10
- package/dist/et-EE.module.js.map +0 -1
- package/dist/fi-FI.main.js +0 -8
- package/dist/fi-FI.main.js.map +0 -1
- package/dist/fi-FI.mjs +0 -10
- package/dist/fi-FI.module.js +0 -10
- package/dist/fi-FI.module.js.map +0 -1
- package/dist/fr-FR.main.js +0 -8
- package/dist/fr-FR.main.js.map +0 -1
- package/dist/fr-FR.mjs +0 -10
- package/dist/fr-FR.module.js +0 -10
- package/dist/fr-FR.module.js.map +0 -1
- package/dist/he-IL.main.js +0 -8
- package/dist/he-IL.main.js.map +0 -1
- package/dist/he-IL.mjs +0 -10
- package/dist/he-IL.module.js +0 -10
- package/dist/he-IL.module.js.map +0 -1
- package/dist/hr-HR.main.js +0 -8
- package/dist/hr-HR.main.js.map +0 -1
- package/dist/hr-HR.mjs +0 -10
- package/dist/hr-HR.module.js +0 -10
- package/dist/hr-HR.module.js.map +0 -1
- package/dist/hu-HU.main.js +0 -8
- package/dist/hu-HU.main.js.map +0 -1
- package/dist/hu-HU.mjs +0 -10
- package/dist/hu-HU.module.js +0 -10
- package/dist/hu-HU.module.js.map +0 -1
- package/dist/intlStrings.main.js +0 -108
- package/dist/intlStrings.main.js.map +0 -1
- package/dist/intlStrings.mjs +0 -110
- package/dist/intlStrings.module.js +0 -110
- package/dist/intlStrings.module.js.map +0 -1
- package/dist/it-IT.main.js +0 -8
- package/dist/it-IT.main.js.map +0 -1
- package/dist/it-IT.mjs +0 -10
- package/dist/it-IT.module.js +0 -10
- package/dist/it-IT.module.js.map +0 -1
- package/dist/ja-JP.main.js +0 -8
- package/dist/ja-JP.main.js.map +0 -1
- package/dist/ja-JP.mjs +0 -10
- package/dist/ja-JP.module.js +0 -10
- package/dist/ja-JP.module.js.map +0 -1
- package/dist/ko-KR.main.js +0 -8
- package/dist/ko-KR.main.js.map +0 -1
- package/dist/ko-KR.mjs +0 -10
- package/dist/ko-KR.module.js +0 -10
- package/dist/ko-KR.module.js.map +0 -1
- package/dist/lt-LT.main.js +0 -8
- package/dist/lt-LT.main.js.map +0 -1
- package/dist/lt-LT.mjs +0 -10
- package/dist/lt-LT.module.js +0 -10
- package/dist/lt-LT.module.js.map +0 -1
- package/dist/lv-LV.main.js +0 -8
- package/dist/lv-LV.main.js.map +0 -1
- package/dist/lv-LV.mjs +0 -10
- package/dist/lv-LV.module.js +0 -10
- package/dist/lv-LV.module.js.map +0 -1
- package/dist/menu.2ec1fdaf.css +0 -570
- package/dist/menu.2ec1fdaf.css.map +0 -1
- package/dist/menu.5b49954a.css +0 -30
- package/dist/menu.5b49954a.css.map +0 -1
- package/dist/menu_vars_css.main.js +0 -177
- package/dist/menu_vars_css.main.js.map +0 -1
- package/dist/menu_vars_css.mjs +0 -179
- package/dist/menu_vars_css.module.js +0 -179
- package/dist/menu_vars_css.module.js.map +0 -1
- package/dist/nb-NO.main.js +0 -8
- package/dist/nb-NO.main.js.map +0 -1
- package/dist/nb-NO.mjs +0 -10
- package/dist/nb-NO.module.js +0 -10
- package/dist/nb-NO.module.js.map +0 -1
- package/dist/nl-NL.main.js +0 -8
- package/dist/nl-NL.main.js.map +0 -1
- package/dist/nl-NL.mjs +0 -10
- package/dist/nl-NL.module.js +0 -10
- package/dist/nl-NL.module.js.map +0 -1
- package/dist/pl-PL.main.js +0 -8
- package/dist/pl-PL.main.js.map +0 -1
- package/dist/pl-PL.mjs +0 -10
- package/dist/pl-PL.module.js +0 -10
- package/dist/pl-PL.module.js.map +0 -1
- package/dist/pt-BR.main.js +0 -8
- package/dist/pt-BR.main.js.map +0 -1
- package/dist/pt-BR.mjs +0 -10
- package/dist/pt-BR.module.js +0 -10
- package/dist/pt-BR.module.js.map +0 -1
- package/dist/pt-PT.main.js +0 -8
- package/dist/pt-PT.main.js.map +0 -1
- package/dist/pt-PT.mjs +0 -10
- package/dist/pt-PT.module.js +0 -10
- package/dist/pt-PT.module.js.map +0 -1
- package/dist/ro-RO.main.js +0 -8
- package/dist/ro-RO.main.js.map +0 -1
- package/dist/ro-RO.mjs +0 -10
- package/dist/ro-RO.module.js +0 -10
- package/dist/ro-RO.module.js.map +0 -1
- package/dist/ru-RU.main.js +0 -8
- package/dist/ru-RU.main.js.map +0 -1
- package/dist/ru-RU.mjs +0 -10
- package/dist/ru-RU.module.js +0 -10
- package/dist/ru-RU.module.js.map +0 -1
- package/dist/sk-SK.main.js +0 -8
- package/dist/sk-SK.main.js.map +0 -1
- package/dist/sk-SK.mjs +0 -10
- package/dist/sk-SK.module.js +0 -10
- package/dist/sk-SK.module.js.map +0 -1
- package/dist/sl-SI.main.js +0 -8
- package/dist/sl-SI.main.js.map +0 -1
- package/dist/sl-SI.mjs +0 -10
- package/dist/sl-SI.module.js +0 -10
- package/dist/sl-SI.module.js.map +0 -1
- package/dist/sr-SP.main.js +0 -8
- package/dist/sr-SP.main.js.map +0 -1
- package/dist/sr-SP.mjs +0 -10
- package/dist/sr-SP.module.js +0 -10
- package/dist/sr-SP.module.js.map +0 -1
- package/dist/sv-SE.main.js +0 -8
- package/dist/sv-SE.main.js.map +0 -1
- package/dist/sv-SE.mjs +0 -10
- package/dist/sv-SE.module.js +0 -10
- package/dist/sv-SE.module.js.map +0 -1
- package/dist/tr-TR.main.js +0 -8
- package/dist/tr-TR.main.js.map +0 -1
- package/dist/tr-TR.mjs +0 -10
- package/dist/tr-TR.module.js +0 -10
- package/dist/tr-TR.module.js.map +0 -1
- package/dist/types.d.ts +0 -43
- package/dist/types.d.ts.map +0 -1
- package/dist/uk-UA.main.js +0 -8
- package/dist/uk-UA.main.js.map +0 -1
- package/dist/uk-UA.mjs +0 -10
- package/dist/uk-UA.module.js +0 -10
- package/dist/uk-UA.module.js.map +0 -1
- package/dist/zh-CN.main.js +0 -8
- package/dist/zh-CN.main.js.map +0 -1
- package/dist/zh-CN.mjs +0 -10
- package/dist/zh-CN.module.js +0 -10
- package/dist/zh-CN.module.js.map +0 -1
- package/dist/zh-TW.main.js +0 -8
- package/dist/zh-TW.main.js.map +0 -1
- package/dist/zh-TW.mjs +0 -10
- package/dist/zh-TW.module.js +0 -10
- package/dist/zh-TW.module.js.map +0 -1
- package/src/ActionMenu.tsx +0 -58
- package/src/ContextualHelpTrigger.tsx +0 -194
- package/src/Menu.tsx +0 -228
- package/src/MenuItem.tsx +0 -159
- package/src/MenuSection.tsx +0 -100
- package/src/MenuTrigger.tsx +0 -125
- package/src/SubmenuTrigger.tsx +0 -154
- package/src/context.ts +0 -63
- package/src/overlays.css +0 -32
- package/src/useCloseOnScroll.ts +0 -65
package/src/MenuSection.tsx
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2020 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import {classNames} from '@react-spectrum/utils';
|
|
14
|
-
import {getChildNodes} from '@react-stately/collections';
|
|
15
|
-
import {MenuItem} from './MenuItem';
|
|
16
|
-
import {Node} from '@react-types/shared';
|
|
17
|
-
import React, {Fragment, JSX} from 'react';
|
|
18
|
-
import styles from '@adobe/spectrum-css-temp/components/menu/vars.css';
|
|
19
|
-
import {TreeState} from '@react-stately/tree';
|
|
20
|
-
import {useMenuSection} from '@react-aria/menu';
|
|
21
|
-
import {useSeparator} from '@react-aria/separator';
|
|
22
|
-
|
|
23
|
-
interface MenuSectionProps<T> {
|
|
24
|
-
item: Node<T>,
|
|
25
|
-
state: TreeState<T>
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** @private */
|
|
29
|
-
export function MenuSection<T>(props: MenuSectionProps<T>): JSX.Element {
|
|
30
|
-
let {item, state} = props;
|
|
31
|
-
let {itemProps, headingProps, groupProps} = useMenuSection({
|
|
32
|
-
heading: item.rendered,
|
|
33
|
-
'aria-label': item['aria-label']
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
let {separatorProps} = useSeparator({
|
|
37
|
-
elementType: 'div'
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
let firstSectionKey = state.collection.getFirstKey();
|
|
41
|
-
let lastSectionKey = [...state.collection].filter(node => node.type === 'section').at(-1)?.key;
|
|
42
|
-
let sectionIsFirst = firstSectionKey === item.key && state.collection.getFirstKey() === firstSectionKey;
|
|
43
|
-
let lastKey = state.collection.getLastKey();
|
|
44
|
-
let sectionIsLast = lastSectionKey === item.key && lastKey != null && state.collection.getItem(lastKey)!.parentKey === lastSectionKey;
|
|
45
|
-
|
|
46
|
-
return (
|
|
47
|
-
<Fragment>
|
|
48
|
-
{item.key !== state.collection.getFirstKey() &&
|
|
49
|
-
<div
|
|
50
|
-
{...separatorProps}
|
|
51
|
-
className={classNames(
|
|
52
|
-
styles,
|
|
53
|
-
'spectrum-Menu-divider'
|
|
54
|
-
)} />
|
|
55
|
-
}
|
|
56
|
-
<div {...itemProps}>
|
|
57
|
-
{item.rendered &&
|
|
58
|
-
<span
|
|
59
|
-
{...headingProps}
|
|
60
|
-
className={
|
|
61
|
-
classNames(
|
|
62
|
-
styles,
|
|
63
|
-
'spectrum-Menu-sectionHeading'
|
|
64
|
-
)
|
|
65
|
-
}>
|
|
66
|
-
{item.rendered}
|
|
67
|
-
</span>
|
|
68
|
-
}
|
|
69
|
-
<div
|
|
70
|
-
{...groupProps}
|
|
71
|
-
className={
|
|
72
|
-
classNames(
|
|
73
|
-
styles,
|
|
74
|
-
'spectrum-Menu',
|
|
75
|
-
{
|
|
76
|
-
'spectrum-Menu-section--noHeading': item.rendered == null,
|
|
77
|
-
'spectrum-Menu-section--isFirst': sectionIsFirst,
|
|
78
|
-
'spectrum-Menu-section--isLast': sectionIsLast
|
|
79
|
-
}
|
|
80
|
-
)
|
|
81
|
-
}>
|
|
82
|
-
{[...getChildNodes(item, state.collection)].map(node => {
|
|
83
|
-
let item = (
|
|
84
|
-
<MenuItem
|
|
85
|
-
key={node.key}
|
|
86
|
-
item={node}
|
|
87
|
-
state={state} />
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
if (node.wrapper) {
|
|
91
|
-
item = node.wrapper(item);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return item;
|
|
95
|
-
})}
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
</Fragment>
|
|
99
|
-
);
|
|
100
|
-
}
|
package/src/MenuTrigger.tsx
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2020 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import {classNames, SlotProvider, unwrapDOMRef, useDOMRef, useIsMobileDevice} from '@react-spectrum/utils';
|
|
14
|
-
import {DOMRef} from '@react-types/shared';
|
|
15
|
-
import {MenuContext} from './context';
|
|
16
|
-
import {Placement} from '@react-types/overlays';
|
|
17
|
-
import {Popover, Tray} from '@react-spectrum/overlays';
|
|
18
|
-
import {PressResponder, useInteractOutside} from '@react-aria/interactions';
|
|
19
|
-
import React, {forwardRef, Fragment, useRef} from 'react';
|
|
20
|
-
import {SpectrumMenuTriggerProps} from '@react-types/menu';
|
|
21
|
-
import styles from '@adobe/spectrum-css-temp/components/menu/vars.css';
|
|
22
|
-
import {useMenuTrigger} from '@react-aria/menu';
|
|
23
|
-
import {useMenuTriggerState} from '@react-stately/menu';
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* The MenuTrigger serves as a wrapper around a Menu and its associated trigger,
|
|
27
|
-
* linking the Menu's open state with the trigger's press state.
|
|
28
|
-
*/
|
|
29
|
-
export const MenuTrigger = forwardRef(function MenuTrigger(props: SpectrumMenuTriggerProps, ref: DOMRef<HTMLElement>) {
|
|
30
|
-
let triggerRef = useRef<HTMLElement>(null);
|
|
31
|
-
let domRef = useDOMRef(ref);
|
|
32
|
-
let menuTriggerRef = domRef || triggerRef;
|
|
33
|
-
let menuRef = useRef<HTMLDivElement>(null);
|
|
34
|
-
let {
|
|
35
|
-
children,
|
|
36
|
-
align = 'start',
|
|
37
|
-
shouldFlip = true,
|
|
38
|
-
direction = 'bottom',
|
|
39
|
-
closeOnSelect,
|
|
40
|
-
trigger = 'press'
|
|
41
|
-
} = props;
|
|
42
|
-
|
|
43
|
-
let [menuTrigger, menu] = React.Children.toArray(children);
|
|
44
|
-
let state = useMenuTriggerState(props);
|
|
45
|
-
|
|
46
|
-
let {menuTriggerProps, menuProps} = useMenuTrigger({trigger}, state, menuTriggerRef);
|
|
47
|
-
|
|
48
|
-
let initialPlacement: Placement;
|
|
49
|
-
switch (direction) {
|
|
50
|
-
case 'left':
|
|
51
|
-
case 'right':
|
|
52
|
-
case 'start':
|
|
53
|
-
case 'end':
|
|
54
|
-
initialPlacement = `${direction} ${align === 'end' ? 'bottom' : 'top'}` as Placement;
|
|
55
|
-
break;
|
|
56
|
-
case 'bottom':
|
|
57
|
-
case 'top':
|
|
58
|
-
default:
|
|
59
|
-
initialPlacement = `${direction} ${align}` as Placement;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
let isMobile = useIsMobileDevice();
|
|
63
|
-
let menuContext = {
|
|
64
|
-
...menuProps,
|
|
65
|
-
ref: menuRef,
|
|
66
|
-
onClose: state.close,
|
|
67
|
-
closeOnSelect,
|
|
68
|
-
autoFocus: state.focusStrategy || true,
|
|
69
|
-
UNSAFE_style: isMobile ? {
|
|
70
|
-
width: '100%',
|
|
71
|
-
maxHeight: 'inherit'
|
|
72
|
-
} : undefined,
|
|
73
|
-
UNSAFE_className: classNames(styles, {'spectrum-Menu-popover': !isMobile}),
|
|
74
|
-
state
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// Close when clicking outside the root menu when a submenu is open.
|
|
78
|
-
let rootOverlayRef = useRef(null);
|
|
79
|
-
let rootOverlayDomRef = unwrapDOMRef(rootOverlayRef);
|
|
80
|
-
useInteractOutside({
|
|
81
|
-
ref: rootOverlayDomRef,
|
|
82
|
-
onInteractOutside: () => {
|
|
83
|
-
state?.close();
|
|
84
|
-
},
|
|
85
|
-
isDisabled: !state.isOpen || state.expandedKeysStack.length === 0
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// On small screen devices, the menu is rendered in a tray, otherwise a popover.
|
|
89
|
-
let overlay;
|
|
90
|
-
if (isMobile) {
|
|
91
|
-
overlay = (
|
|
92
|
-
<Tray state={state} isFixedHeight ref={rootOverlayRef}>
|
|
93
|
-
{menu}
|
|
94
|
-
</Tray>
|
|
95
|
-
);
|
|
96
|
-
} else {
|
|
97
|
-
overlay = (
|
|
98
|
-
<Popover
|
|
99
|
-
ref={rootOverlayRef}
|
|
100
|
-
UNSAFE_style={{clipPath: 'unset', overflow: 'visible', filter: 'unset', borderWidth: '0px'}}
|
|
101
|
-
state={state}
|
|
102
|
-
triggerRef={menuTriggerRef}
|
|
103
|
-
scrollRef={menuRef}
|
|
104
|
-
placement={initialPlacement}
|
|
105
|
-
hideArrow
|
|
106
|
-
shouldFlip={shouldFlip}
|
|
107
|
-
shouldContainFocus>
|
|
108
|
-
{menu}
|
|
109
|
-
</Popover>
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<Fragment>
|
|
115
|
-
<SlotProvider slots={{actionButton: {holdAffordance: trigger === 'longPress'}}}>
|
|
116
|
-
<PressResponder {...menuTriggerProps} ref={menuTriggerRef} isPressed={state.isOpen}>
|
|
117
|
-
{menuTrigger}
|
|
118
|
-
</PressResponder>
|
|
119
|
-
</SlotProvider>
|
|
120
|
-
<MenuContext.Provider value={menuContext}>
|
|
121
|
-
{overlay}
|
|
122
|
-
</MenuContext.Provider>
|
|
123
|
-
</Fragment>
|
|
124
|
-
);
|
|
125
|
-
});
|
package/src/SubmenuTrigger.tsx
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2020 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import {classNames, useIsMobileDevice} from '@react-spectrum/utils';
|
|
14
|
-
import {isFocusWithin, mergeProps} from '@react-aria/utils';
|
|
15
|
-
import {Key} from '@react-types/shared';
|
|
16
|
-
import {MenuContext, SubmenuTriggerContext, useMenuStateContext} from './context';
|
|
17
|
-
import {Popover} from '@react-spectrum/overlays';
|
|
18
|
-
import React, {type JSX, ReactElement, useRef} from 'react';
|
|
19
|
-
import ReactDOM from 'react-dom';
|
|
20
|
-
import styles from '@adobe/spectrum-css-temp/components/menu/vars.css';
|
|
21
|
-
import {useLocale} from '@react-aria/i18n';
|
|
22
|
-
import {useSubmenuTrigger} from '@react-aria/menu';
|
|
23
|
-
import {useSubmenuTriggerState} from '@react-stately/menu';
|
|
24
|
-
|
|
25
|
-
interface SubmenuTriggerProps {
|
|
26
|
-
/**
|
|
27
|
-
* The contents of the SubmenuTrigger - an Item and a Menu.
|
|
28
|
-
*/
|
|
29
|
-
children: ReactElement<any>[],
|
|
30
|
-
targetKey: Key
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface SpectrumSubmenuTriggerProps extends Omit<SubmenuTriggerProps, 'targetKey'> {}
|
|
34
|
-
|
|
35
|
-
function SubmenuTrigger(props: SubmenuTriggerProps) {
|
|
36
|
-
let triggerRef = useRef<HTMLDivElement>(null);
|
|
37
|
-
let {
|
|
38
|
-
children,
|
|
39
|
-
targetKey
|
|
40
|
-
} = props;
|
|
41
|
-
|
|
42
|
-
let [menuTrigger, menu] = React.Children.toArray(children);
|
|
43
|
-
let {popoverContainer, trayContainerRef, menu: parentMenuRef, submenu: menuRef, rootMenuTriggerState} = useMenuStateContext()!;
|
|
44
|
-
let submenuTriggerState = useSubmenuTriggerState({triggerKey: targetKey}, rootMenuTriggerState!);
|
|
45
|
-
let {submenuTriggerProps, submenuProps, popoverProps} = useSubmenuTrigger({
|
|
46
|
-
parentMenuRef,
|
|
47
|
-
submenuRef: menuRef
|
|
48
|
-
}, submenuTriggerState, triggerRef);
|
|
49
|
-
let isMobile = useIsMobileDevice();
|
|
50
|
-
let onBackButtonPress = () => {
|
|
51
|
-
submenuTriggerState.close();
|
|
52
|
-
if (parentMenuRef.current && !isFocusWithin(parentMenuRef.current)) {
|
|
53
|
-
parentMenuRef.current.focus();
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
let {direction} = useLocale();
|
|
58
|
-
let mobileSubmenuKeyDown = (e: KeyboardEvent) => {
|
|
59
|
-
switch (e.key) {
|
|
60
|
-
case 'ArrowLeft':
|
|
61
|
-
if (direction === 'ltr') {
|
|
62
|
-
triggerRef.current?.focus();
|
|
63
|
-
}
|
|
64
|
-
break;
|
|
65
|
-
case 'ArrowRight':
|
|
66
|
-
if (direction === 'rtl') {
|
|
67
|
-
triggerRef.current?.focus();
|
|
68
|
-
}
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
let overlay;
|
|
74
|
-
|
|
75
|
-
if (isMobile) {
|
|
76
|
-
delete submenuTriggerProps.onBlur;
|
|
77
|
-
delete submenuTriggerProps.onHoverChange;
|
|
78
|
-
submenuProps.autoFocus ??= true;
|
|
79
|
-
if (trayContainerRef.current && submenuTriggerState.isOpen) {
|
|
80
|
-
overlay = ReactDOM.createPortal(menu, trayContainerRef.current);
|
|
81
|
-
}
|
|
82
|
-
} else {
|
|
83
|
-
let onDismissButtonPress = () => {
|
|
84
|
-
submenuTriggerState.close();
|
|
85
|
-
parentMenuRef.current?.focus();
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
overlay = (
|
|
89
|
-
<Popover
|
|
90
|
-
{...popoverProps}
|
|
91
|
-
onDismissButtonPress={onDismissButtonPress}
|
|
92
|
-
UNSAFE_className={classNames(styles, 'spectrum-Submenu-popover')}
|
|
93
|
-
container={popoverContainer!}
|
|
94
|
-
containerPadding={0}
|
|
95
|
-
enableBothDismissButtons
|
|
96
|
-
UNSAFE_style={{clipPath: 'unset', overflow: 'visible', borderWidth: '0px'}}
|
|
97
|
-
state={submenuTriggerState}
|
|
98
|
-
triggerRef={triggerRef}
|
|
99
|
-
scrollRef={menuRef}
|
|
100
|
-
placement="end top"
|
|
101
|
-
hideArrow>
|
|
102
|
-
{menu}
|
|
103
|
-
</Popover>
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
let menuContext = {
|
|
108
|
-
...mergeProps(submenuProps, {
|
|
109
|
-
ref: menuRef,
|
|
110
|
-
UNSAFE_style: isMobile ? {
|
|
111
|
-
width: '100%',
|
|
112
|
-
maxHeight: 'inherit'
|
|
113
|
-
} : undefined,
|
|
114
|
-
UNSAFE_className: classNames(styles, {'spectrum-Menu-popover': !isMobile}),
|
|
115
|
-
...(isMobile && {
|
|
116
|
-
onBackButtonPress,
|
|
117
|
-
onKeyDown: mobileSubmenuKeyDown
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
return (
|
|
123
|
-
<>
|
|
124
|
-
<SubmenuTriggerContext.Provider value={{triggerRef, ...submenuTriggerProps}}>{menuTrigger}</SubmenuTriggerContext.Provider>
|
|
125
|
-
<MenuContext.Provider value={menuContext}>
|
|
126
|
-
{overlay}
|
|
127
|
-
</MenuContext.Provider>
|
|
128
|
-
</>
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
SubmenuTrigger.getCollectionNode = function* (props: SpectrumSubmenuTriggerProps) {
|
|
133
|
-
let childArray: ReactElement[] = [];
|
|
134
|
-
React.Children.forEach(props.children, child => {
|
|
135
|
-
if (React.isValidElement(child)) {
|
|
136
|
-
childArray.push(child);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
let [trigger] = childArray;
|
|
140
|
-
let [, content] = props.children as [ReactElement, ReactElement];
|
|
141
|
-
|
|
142
|
-
yield {
|
|
143
|
-
element: React.cloneElement(trigger, {...trigger.props as any, hasChildItems: true, isTrigger: true}),
|
|
144
|
-
wrapper: (element) => (
|
|
145
|
-
<SubmenuTrigger key={element.key} targetKey={element.key} {...props}>
|
|
146
|
-
{element}
|
|
147
|
-
{content}
|
|
148
|
-
</SubmenuTrigger>
|
|
149
|
-
)
|
|
150
|
-
};
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
let _SubmenuTrigger = SubmenuTrigger as unknown as (props: SpectrumSubmenuTriggerProps) => JSX.Element;
|
|
154
|
-
export {_SubmenuTrigger as SubmenuTrigger};
|
package/src/context.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2020 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import {DOMProps, FocusStrategy, HoverEvents, KeyboardEvents, PressEvents, RefObject} from '@react-types/shared';
|
|
14
|
-
import React, {HTMLAttributes, useContext} from 'react';
|
|
15
|
-
import {RootMenuTriggerState} from '@react-stately/menu';
|
|
16
|
-
import {TreeState} from '@react-stately/tree';
|
|
17
|
-
|
|
18
|
-
export interface MenuContextValue extends Omit<HTMLAttributes<HTMLElement>, 'autoFocus' | 'onKeyDown'>, Pick<KeyboardEvents, 'onKeyDown'> {
|
|
19
|
-
onClose?: () => void,
|
|
20
|
-
closeOnSelect?: boolean,
|
|
21
|
-
shouldFocusWrap?: boolean,
|
|
22
|
-
autoFocus?: boolean | FocusStrategy,
|
|
23
|
-
ref?: RefObject<HTMLDivElement | null>,
|
|
24
|
-
state?: RootMenuTriggerState,
|
|
25
|
-
onBackButtonPress?: () => void,
|
|
26
|
-
submenuLevel?: number
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const MenuContext = React.createContext<MenuContextValue>({});
|
|
30
|
-
|
|
31
|
-
export function useMenuContext(): MenuContextValue {
|
|
32
|
-
return useContext(MenuContext);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface SubmenuTriggerContextValue extends DOMProps, Pick<PressEvents, 'onPressStart' | 'onPress'>, Pick<HoverEvents, 'onHoverChange'>, Pick<KeyboardEvents, 'onKeyDown'> {
|
|
36
|
-
isUnavailable?: boolean,
|
|
37
|
-
triggerRef?: RefObject<HTMLElement | null>,
|
|
38
|
-
'aria-expanded'?: boolean | 'true' | 'false',
|
|
39
|
-
'aria-controls'?: string,
|
|
40
|
-
'aria-haspopup'?: 'dialog' | 'menu',
|
|
41
|
-
isOpen?: boolean
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const SubmenuTriggerContext = React.createContext<SubmenuTriggerContextValue | undefined>(undefined);
|
|
45
|
-
|
|
46
|
-
export function useSubmenuTriggerContext(): SubmenuTriggerContextValue | undefined {
|
|
47
|
-
return useContext(SubmenuTriggerContext);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface MenuStateContextValue<T> {
|
|
51
|
-
state: TreeState<T>,
|
|
52
|
-
popoverContainer: HTMLElement | null,
|
|
53
|
-
trayContainerRef: RefObject<HTMLElement | null>,
|
|
54
|
-
menu: RefObject<HTMLDivElement | null>,
|
|
55
|
-
submenu: RefObject<HTMLDivElement | null>,
|
|
56
|
-
rootMenuTriggerState?: RootMenuTriggerState
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const MenuStateContext = React.createContext<MenuStateContextValue<any> | undefined>(undefined);
|
|
60
|
-
|
|
61
|
-
export function useMenuStateContext(): MenuStateContextValue<any> | undefined {
|
|
62
|
-
return useContext(MenuStateContext);
|
|
63
|
-
}
|
package/src/overlays.css
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2020 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
.spectrum-Popover {
|
|
14
|
-
/* This makes the contents of popovers focusable immediately, without waiting
|
|
15
|
-
a frame for animations to start. */
|
|
16
|
-
&.react-spectrum-Popover {
|
|
17
|
-
visibility: visible;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.spectrum-Dialog-content {
|
|
21
|
-
max-height: initial;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.spectrum-Modal-wrapper.react-spectrum-Modal-wrapper,
|
|
26
|
-
.spectrum-Modal.react-spectrum-Modal {
|
|
27
|
-
visibility: visible;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.spectrum-Tray.react-spectrum-Tray {
|
|
31
|
-
visibility: visible;
|
|
32
|
-
}
|
package/src/useCloseOnScroll.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2020 Adobe. All rights reserved.
|
|
3
|
-
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
*
|
|
7
|
-
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
-
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
-
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
-
* governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import {getEventTarget, nodeContains} from '@react-aria/utils';
|
|
14
|
-
import {RefObject} from '@react-types/shared';
|
|
15
|
-
import {useEffect} from 'react';
|
|
16
|
-
|
|
17
|
-
// This behavior moved from useOverlayTrigger to useOverlayPosition.
|
|
18
|
-
// For backward compatibility, where useOverlayTrigger handled hiding the popover on close,
|
|
19
|
-
// it sets a close function here mapped from the trigger element. This way we can avoid
|
|
20
|
-
// forcing users to pass an onClose function to useOverlayPosition which could be considered
|
|
21
|
-
// a breaking change.
|
|
22
|
-
export const onCloseMap: WeakMap<Element, () => void> = new WeakMap();
|
|
23
|
-
|
|
24
|
-
interface CloseOnScrollOptions {
|
|
25
|
-
triggerRef: RefObject<Element | null>,
|
|
26
|
-
isOpen?: boolean,
|
|
27
|
-
onClose?: (() => void) | null
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** @private */
|
|
31
|
-
export function useCloseOnScroll(opts: CloseOnScrollOptions): void {
|
|
32
|
-
let {triggerRef, isOpen, onClose} = opts;
|
|
33
|
-
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
if (!isOpen || onClose === null) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
let onScroll = (e: Event) => {
|
|
40
|
-
// Ignore if scrolling an scrollable region outside the trigger's tree.
|
|
41
|
-
let target = getEventTarget(e);
|
|
42
|
-
// window is not a Node and doesn't have contain, but window contains everything
|
|
43
|
-
if (!triggerRef.current || ((target instanceof Node) && !nodeContains(target, triggerRef.current))) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Ignore scroll events on any input or textarea as the cursor position can cause it to scroll
|
|
48
|
-
// such as in a combobox. Clicking the dropdown button places focus on the input, and if the
|
|
49
|
-
// text inside the input extends beyond the 'end', then it will scroll so the cursor is visible at the end.
|
|
50
|
-
if (getEventTarget(e) instanceof HTMLInputElement || getEventTarget(e) instanceof HTMLTextAreaElement) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
let onCloseHandler = onClose || onCloseMap.get(triggerRef.current);
|
|
55
|
-
if (onCloseHandler) {
|
|
56
|
-
onCloseHandler();
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
window.addEventListener('scroll', onScroll, true);
|
|
61
|
-
return () => {
|
|
62
|
-
window.removeEventListener('scroll', onScroll, true);
|
|
63
|
-
};
|
|
64
|
-
}, [isOpen, onClose, triggerRef]);
|
|
65
|
-
}
|