@spaced-out/ui-design-system 0.6.36 → 0.6.37
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/.cspell/custom-words.txt +9 -0
- package/CHANGELOG.md +9 -0
- package/lib/components/ButtonDropdown/ButtonDropdown.d.ts +10 -0
- package/lib/components/ButtonDropdown/ButtonDropdown.d.ts.map +1 -1
- package/lib/components/ButtonDropdown/ButtonDropdown.js +26 -3
- package/lib/components/ButtonTabs/ButtonTab/ButtonTab.d.ts +9 -1
- package/lib/components/ButtonTabs/ButtonTab/ButtonTab.d.ts.map +1 -1
- package/lib/components/ButtonTabs/ButtonTab/ButtonTab.js +8 -0
- package/lib/components/ButtonTabs/ButtonTabDropdown.d.ts +10 -1
- package/lib/components/ButtonTabs/ButtonTabDropdown.d.ts.map +1 -1
- package/lib/components/ButtonTabs/ButtonTabDropdown.js +31 -3
- package/lib/components/ButtonTabs/ButtonTabs.d.ts +6 -0
- package/lib/components/ButtonTabs/ButtonTabs.d.ts.map +1 -1
- package/lib/components/ButtonTabs/ButtonTabs.js +2 -0
- package/lib/components/Combobox/Combobox.d.ts +9 -0
- package/lib/components/Combobox/Combobox.d.ts.map +1 -1
- package/lib/components/Combobox/Combobox.js +21 -0
- package/lib/components/Combobox/helper.d.ts.map +1 -1
- package/lib/components/Combobox/helper.js +0 -4
- package/lib/components/Dropdown/Dropdown.d.ts +9 -0
- package/lib/components/Dropdown/Dropdown.d.ts.map +1 -1
- package/lib/components/Dropdown/Dropdown.js +92 -24
- package/lib/components/Dropdown/Dropdown.module.css +24 -0
- package/lib/components/InlineDropdown/InlineDropdown.d.ts +10 -0
- package/lib/components/InlineDropdown/InlineDropdown.d.ts.map +1 -1
- package/lib/components/InlineDropdown/InlineDropdown.js +23 -3
- package/lib/components/Input/Input.module.css +38 -0
- package/lib/components/Menu/Menu.d.ts +99 -0
- package/lib/components/Menu/Menu.d.ts.map +1 -1
- package/lib/components/Menu/Menu.js +1152 -187
- package/lib/components/Menu/Menu.module.css +191 -7
- package/lib/components/Menu/MenuFocusScope.d.ts +21 -0
- package/lib/components/Menu/MenuFocusScope.d.ts.map +1 -0
- package/lib/components/Menu/MenuFocusScope.js +37 -0
- package/lib/components/Menu/MenuOptionButton.d.ts +36 -0
- package/lib/components/Menu/MenuOptionButton.d.ts.map +1 -1
- package/lib/components/Menu/MenuOptionButton.js +137 -29
- package/lib/components/Menu/index.d.ts +2 -0
- package/lib/components/Menu/index.d.ts.map +1 -1
- package/lib/components/Menu/index.js +22 -0
- package/lib/components/Menu/menuOptionId.d.ts +12 -0
- package/lib/components/Menu/menuOptionId.d.ts.map +1 -0
- package/lib/components/Menu/menuOptionId.js +18 -0
- package/lib/components/Menu/useMenuKeyboardNavigation.d.ts +93 -0
- package/lib/components/Menu/useMenuKeyboardNavigation.d.ts.map +1 -0
- package/lib/components/Menu/useMenuKeyboardNavigation.js +471 -0
- package/lib/components/Menu/useMenuTrigger.d.ts +207 -0
- package/lib/components/Menu/useMenuTrigger.d.ts.map +1 -0
- package/lib/components/Menu/useMenuTrigger.js +389 -0
- package/lib/components/OptionButton/OptionButton.d.ts +16 -0
- package/lib/components/OptionButton/OptionButton.d.ts.map +1 -1
- package/lib/components/OptionButton/OptionButton.js +4 -1
- package/lib/components/Tabs/Tab/Tab.d.ts +8 -1
- package/lib/components/Tabs/Tab/Tab.d.ts.map +1 -1
- package/lib/components/Tabs/Tab/Tab.js +8 -0
- package/lib/components/Tabs/TabList/TabDropdown.d.ts +10 -1
- package/lib/components/Tabs/TabList/TabDropdown.d.ts.map +1 -1
- package/lib/components/Tabs/TabList/TabDropdown.js +23 -3
- package/lib/components/Tabs/TabList/TabList.d.ts +14 -0
- package/lib/components/Tabs/TabList/TabList.d.ts.map +1 -1
- package/lib/components/Tabs/TabList/TabList.js +6 -0
- package/lib/components/Typeahead/Typeahead.d.ts +9 -0
- package/lib/components/Typeahead/Typeahead.d.ts.map +1 -1
- package/lib/components/Typeahead/Typeahead.js +107 -13
- package/lib/components/Typeahead/Typeahead.module.css +13 -0
- package/lib/hooks/index.d.ts +1 -0
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/index.js +11 -0
- package/lib/hooks/useInteractionModality/index.d.ts +2 -0
- package/lib/hooks/useInteractionModality/index.d.ts.map +1 -0
- package/lib/hooks/useInteractionModality/index.js +16 -0
- package/lib/hooks/useInteractionModality/useInteractionModality.d.ts +39 -0
- package/lib/hooks/useInteractionModality/useInteractionModality.d.ts.map +1 -0
- package/lib/hooks/useInteractionModality/useInteractionModality.js +111 -0
- package/lib/utils/click-away/click-away.d.ts +16 -0
- package/lib/utils/click-away/click-away.d.ts.map +1 -1
- package/lib/utils/click-away/click-away.js +49 -0
- package/mcp/package.json +1 -1
- package/package.json +1 -1
|
@@ -14,6 +14,8 @@ var _mergeRefs = require("../../utils/merge-refs");
|
|
|
14
14
|
var _qa = require("../../utils/qa");
|
|
15
15
|
var _Input = require("../Input");
|
|
16
16
|
var _Menu = require("../Menu");
|
|
17
|
+
var _MenuFocusScope = require("../Menu/MenuFocusScope");
|
|
18
|
+
var _useMenuTrigger = require("../Menu/useMenuTrigger");
|
|
17
19
|
var _Tooltip = require("../Tooltip");
|
|
18
20
|
var _DropdownModule = _interopRequireDefault(require("./Dropdown.module.css"));
|
|
19
21
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -32,10 +34,13 @@ const Dropdown = exports.Dropdown = /*#__PURE__*/React.forwardRef((_ref, ref) =>
|
|
|
32
34
|
dropdownInputText = '',
|
|
33
35
|
clickAwayRef,
|
|
34
36
|
elevation = 'modal',
|
|
37
|
+
enableA11y = false,
|
|
35
38
|
testId,
|
|
36
39
|
...inputProps
|
|
37
40
|
} = _ref;
|
|
38
41
|
const menuRef = React.useRef(null);
|
|
42
|
+
const clickAwayFnRef = React.useRef(null);
|
|
43
|
+
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
|
|
39
44
|
const {
|
|
40
45
|
x,
|
|
41
46
|
y,
|
|
@@ -50,19 +55,75 @@ const Dropdown = exports.Dropdown = /*#__PURE__*/React.forwardRef((_ref, ref) =>
|
|
|
50
55
|
middleware: [(0, _react2.flip)(), (0, _react2.offset)(parseInt(_space.spaceXXSmall))]
|
|
51
56
|
});
|
|
52
57
|
const dropdownWidth = (0, _hooks.useReferenceElementWidth)(refs.reference?.current);
|
|
58
|
+
const focusTriggerInput = () => {
|
|
59
|
+
refs.reference?.current?.querySelector('input')?.focus();
|
|
60
|
+
};
|
|
61
|
+
const handleOptionSelect = (option, e) => {
|
|
62
|
+
onChange?.(option, e ?? null);
|
|
63
|
+
if (
|
|
64
|
+
// keepMenuOpenOnOptionSelect lets the menu persist on select in the normal variant
|
|
65
|
+
!option.keepMenuOpenOnOptionSelect && (!menu?.optionsVariant || menu.optionsVariant === 'normal')) {
|
|
66
|
+
clickAwayFnRef.current?.();
|
|
67
|
+
focusTriggerInput();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// The combobox half of the trigger wiring: the role and its ARIA, the
|
|
72
|
+
// active-option state behind `aria-activedescendant`, keyboard navigation
|
|
73
|
+
// against the real option list, and the props that tie the two together.
|
|
74
|
+
const comboboxTrigger = (0, _useMenuTrigger.useComboboxMenuTrigger)({
|
|
75
|
+
enabled: enableA11y,
|
|
76
|
+
menu,
|
|
77
|
+
menuRef,
|
|
78
|
+
isOpen: isMenuOpen,
|
|
79
|
+
onSelectOption: option => handleOptionSelect(option, null),
|
|
80
|
+
onClose: () => clickAwayFnRef.current?.(),
|
|
81
|
+
focusTrigger: focusTriggerInput,
|
|
82
|
+
triggerAriaLabelledBy: inputProps['aria-labelledby'],
|
|
83
|
+
triggerAriaLabel: inputProps['aria-label']
|
|
84
|
+
});
|
|
53
85
|
const onMenuToggle = isOpen => {
|
|
86
|
+
setIsMenuOpen(isOpen);
|
|
54
87
|
if (isOpen) {
|
|
55
88
|
onMenuOpen?.();
|
|
56
89
|
} else {
|
|
57
90
|
onMenuClose?.();
|
|
58
91
|
}
|
|
59
|
-
if (scrollMenuToBottom && menuRef.current && isOpen) {
|
|
92
|
+
if (!enableA11y && scrollMenuToBottom && menuRef.current && isOpen) {
|
|
93
|
+
// Kept as it was, deliberately. This runs before the portal holding
|
|
94
|
+
// the menu has mounted, so `menuRef` is empty and it does nothing —
|
|
95
|
+
// the effect below is the working version, and it is part of the
|
|
96
|
+
// opt-in because the element it scrolls only exists there. Restoring
|
|
97
|
+
// the scroll for consumers who have not opted in would be a visible
|
|
98
|
+
// change to menus that have never scrolled to the bottom.
|
|
60
99
|
menuRef.current.scrollTop = isOpen ? menuRef.current.scrollHeight : 0;
|
|
61
100
|
}
|
|
62
101
|
};
|
|
102
|
+
|
|
103
|
+
// `scrollMenuToBottom` cannot be honoured from ClickAway's open callback:
|
|
104
|
+
// the menu lives in a portal that has not mounted yet at that point, so
|
|
105
|
+
// `menuRef` is still empty and the scroll silently does nothing. Wait for
|
|
106
|
+
// the open render to commit, then scroll the element that actually
|
|
107
|
+
// scrolls — the listbox itself, or react-window's box when virtualized,
|
|
108
|
+
// whichever Menu marked. rAF rather than a layout effect because the
|
|
109
|
+
// portal fills in a commit later still, and Menu's own open-time scroll
|
|
110
|
+
// (to a seeded active option) must not be undone by this one.
|
|
111
|
+
React.useEffect(() => {
|
|
112
|
+
if (!enableA11y || !scrollMenuToBottom || !isMenuOpen) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const frame = requestAnimationFrame(() => {
|
|
116
|
+
const scroller = menuRef.current?.querySelector('[data-menu-scroll-container]') ?? menuRef.current;
|
|
117
|
+
if (scroller) {
|
|
118
|
+
scroller.scrollTop = scroller.scrollHeight;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return () => cancelAnimationFrame(frame);
|
|
122
|
+
}, [enableA11y, scrollMenuToBottom, isMenuOpen]);
|
|
63
123
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_clickAway.ClickAway, {
|
|
64
124
|
onChange: onMenuToggle,
|
|
65
125
|
clickAwayRef: clickAwayRef,
|
|
126
|
+
restoreFocusOnClose: enableA11y,
|
|
66
127
|
children: _ref2 => {
|
|
67
128
|
let {
|
|
68
129
|
isOpen,
|
|
@@ -71,6 +132,9 @@ const Dropdown = exports.Dropdown = /*#__PURE__*/React.forwardRef((_ref, ref) =>
|
|
|
71
132
|
boundaryRef,
|
|
72
133
|
triggerRef
|
|
73
134
|
} = _ref2;
|
|
135
|
+
// Capture the latest close handler so keyboard selection (which is
|
|
136
|
+
// wired at the component top level) can close the menu.
|
|
137
|
+
clickAwayFnRef.current = clickAway;
|
|
74
138
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
75
139
|
className: (0, _classify.classify)(_DropdownModule.default.dropdownContainer, classNames?.wrapper),
|
|
76
140
|
"data-testid": (0, _qa.generateTestId)({
|
|
@@ -79,22 +143,34 @@ const Dropdown = exports.Dropdown = /*#__PURE__*/React.forwardRef((_ref, ref) =>
|
|
|
79
143
|
}),
|
|
80
144
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Input.Input, {
|
|
81
145
|
...inputProps,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
146
|
+
...(enableA11y ? comboboxTrigger.getTriggerProps({
|
|
147
|
+
isOpen,
|
|
148
|
+
onOpen,
|
|
149
|
+
// Chained rather than replaced: `onKeyDown` is a public
|
|
150
|
+
// prop of Dropdown (via InputProps) and of Combobox,
|
|
151
|
+
// which forwards it as `onDropdownKeyDown`. The hook
|
|
152
|
+
// stands down for any key the consumer's handler claims.
|
|
153
|
+
onKeyDown: inputProps.onKeyDown
|
|
154
|
+
}) : {
|
|
155
|
+
onKeyDown: e => {
|
|
156
|
+
if (e.keyCode === 32) {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
if (isOpen) {
|
|
159
|
+
clickAway();
|
|
160
|
+
} else {
|
|
161
|
+
onOpen();
|
|
162
|
+
}
|
|
89
163
|
}
|
|
90
164
|
}
|
|
91
|
-
},
|
|
165
|
+
}),
|
|
92
166
|
boxRef: (0, _mergeRefs.mergeRefs)([refs.setReference, triggerRef]),
|
|
93
167
|
size: size,
|
|
94
168
|
placeholder: placeholder,
|
|
95
169
|
value: dropdownInputText,
|
|
96
170
|
classNames: {
|
|
97
|
-
box: (0, _classify.classify)(_DropdownModule.default.inputBox,
|
|
171
|
+
box: (0, _classify.classify)(_DropdownModule.default.inputBox, {
|
|
172
|
+
[_DropdownModule.default.inputBoxOpen]: enableA11y && isOpen
|
|
173
|
+
}, classNames?.box),
|
|
98
174
|
iconRight: classNames?.iconRight
|
|
99
175
|
},
|
|
100
176
|
iconRightName: isOpen ? 'angle-up' : 'angle-down',
|
|
@@ -109,8 +185,8 @@ const Dropdown = exports.Dropdown = /*#__PURE__*/React.forwardRef((_ref, ref) =>
|
|
|
109
185
|
slot: 'input'
|
|
110
186
|
})
|
|
111
187
|
}), isOpen && menu && /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.FloatingPortal, {
|
|
112
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
113
|
-
|
|
188
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MenuFocusScope.MenuFocusScope, {
|
|
189
|
+
enabled: !enableA11y,
|
|
114
190
|
context: context,
|
|
115
191
|
initialFocus: refs.reference,
|
|
116
192
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
@@ -136,24 +212,16 @@ const Dropdown = exports.Dropdown = /*#__PURE__*/React.forwardRef((_ref, ref) =>
|
|
|
136
212
|
},
|
|
137
213
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Menu.Menu, {
|
|
138
214
|
...menu,
|
|
215
|
+
...comboboxTrigger.menuProps,
|
|
139
216
|
testId: (0, _qa.generateTestId)({
|
|
140
217
|
base: testId,
|
|
141
218
|
slot: 'menu'
|
|
142
219
|
}),
|
|
143
|
-
onSelect:
|
|
144
|
-
onChange?.(option, e);
|
|
145
|
-
if (
|
|
146
|
-
// option.keepMenuOpenOnOptionSelect - to allow the menu persist its open stat upon option selection in normal variant
|
|
147
|
-
!option.keepMenuOpenOnOptionSelect && (!menu.optionsVariant || menu.optionsVariant === 'normal')) {
|
|
148
|
-
clickAway();
|
|
149
|
-
if (refs.reference?.current) {
|
|
150
|
-
refs.reference.current?.querySelector('input')?.focus();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
},
|
|
220
|
+
onSelect: handleOptionSelect,
|
|
154
221
|
size: menu.size || size,
|
|
155
222
|
onTabOut: clickAway,
|
|
156
|
-
ref: menuRef
|
|
223
|
+
ref: menuRef,
|
|
224
|
+
enableA11y: enableA11y
|
|
157
225
|
})
|
|
158
226
|
})
|
|
159
227
|
})
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
sizeFluid
|
|
3
3
|
) from '../../styles/variables/_size.css';
|
|
4
4
|
|
|
5
|
+
@value (
|
|
6
|
+
borderWidthTertiary
|
|
7
|
+
) from '../../styles/variables/_border.css';
|
|
8
|
+
|
|
5
9
|
.dropdownContainer {
|
|
6
10
|
display: flex;
|
|
7
11
|
position: relative;
|
|
@@ -13,6 +17,26 @@
|
|
|
13
17
|
cursor: pointer;
|
|
14
18
|
}
|
|
15
19
|
|
|
20
|
+
/*
|
|
21
|
+
* Keeping the trigger visually active while its menu is open (DOM focus has
|
|
22
|
+
* moved into the listbox) is done in Input.module.css, keyed off the trigger's
|
|
23
|
+
* own `aria-expanded`. It has to live there: the rules it must beat are scoped
|
|
24
|
+
* to Input's `.wrapper` / `.box` / `.withError` class names, which this module
|
|
25
|
+
* cannot name and therefore cannot reliably out-specify.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* forced-colors mode drops the box-shadow open-emphasis ring; the base box
|
|
30
|
+
* border survives, but add a system-color outline so the open state stays
|
|
31
|
+
* perceivable in Windows High Contrast.
|
|
32
|
+
*/
|
|
33
|
+
@media (forced-colors: active) {
|
|
34
|
+
.inputBox.inputBoxOpen {
|
|
35
|
+
outline: borderWidthTertiary solid Highlight;
|
|
36
|
+
outline-offset: borderWidthTertiary;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
16
40
|
.menuWrapper {
|
|
17
41
|
width: var(--dropdown-width);
|
|
18
42
|
z-index: var(--menu-elevation);
|
|
@@ -18,6 +18,16 @@ export interface InlineDropdownProps extends Omit<UnstyledButtonProps, 'classNam
|
|
|
18
18
|
onMenuClose?: () => unknown;
|
|
19
19
|
size?: 'medium' | 'small' | 'extraSmall';
|
|
20
20
|
elevation?: ElevationType;
|
|
21
|
+
/**
|
|
22
|
+
* Opt in to the accessibility behavior: `aria-haspopup` / `aria-expanded` /
|
|
23
|
+
* `aria-controls` on the trigger, the arrow key that opens the popup, focus
|
|
24
|
+
* moving into the menu and back to the trigger, and the roving tab stop
|
|
25
|
+
* inside it. Forwarded to the `Menu` this opens.
|
|
26
|
+
*
|
|
27
|
+
* Off by default, and off is this component exactly as it behaved before any
|
|
28
|
+
* of it existed.
|
|
29
|
+
*/
|
|
30
|
+
enableA11y?: boolean;
|
|
21
31
|
clickAwayRef?: React.RefObject<ClickAwayRefType | null>;
|
|
22
32
|
testId?: string;
|
|
23
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InlineDropdown.d.ts","sourceRoot":"","sources":["../../../src/components/InlineDropdown/InlineDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"InlineDropdown.d.ts","sourceRoot":"","sources":["../../../src/components/InlineDropdown/InlineDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAKrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAK3D,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,+BAA+B,CAAC;AAE9D,OAAO,KAAK,EAAC,UAAU,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAI/D,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAO1D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC,CAAC;AAEH,MAAM,WAAW,mBACf,SAAQ,IAAI,CACV,mBAAmB,EACjB,YAAY,GACZ,MAAM,GACN,gBAAgB,GAChB,gBAAgB,GAChB,YAAY,GACZ,aAAa,GACb,MAAM,GACN,WAAW,GACX,cAAc,CACjB;IACD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,UAAU,EAClB,IAAI,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,KACxD,OAAO,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IACzC,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,iBAAiB,CACjD,mBAAmB,EACnB,cAAc,CAiKf,CAAC"}
|
|
@@ -15,6 +15,8 @@ var _qa = require("../../utils/qa");
|
|
|
15
15
|
var _Button = require("../Button");
|
|
16
16
|
var _Icon = require("../Icon");
|
|
17
17
|
var _Menu = require("../Menu");
|
|
18
|
+
var _MenuFocusScope = require("../Menu/MenuFocusScope");
|
|
19
|
+
var _useMenuTrigger = require("../Menu/useMenuTrigger");
|
|
18
20
|
var _Tooltip = require("../Tooltip");
|
|
19
21
|
var _Truncate = require("../Truncate");
|
|
20
22
|
var _InlineDropdownModule = _interopRequireDefault(require("./InlineDropdown.module.css"));
|
|
@@ -34,9 +36,18 @@ const InlineDropdown = exports.InlineDropdown = /*#__PURE__*/React.forwardRef((_
|
|
|
34
36
|
children,
|
|
35
37
|
clickAwayRef,
|
|
36
38
|
elevation = 'modal',
|
|
39
|
+
enableA11y = false,
|
|
37
40
|
testId,
|
|
38
41
|
...restButtonProps
|
|
39
42
|
} = _ref;
|
|
43
|
+
const menuTrigger = (0, _useMenuTrigger.useMenuTrigger)({
|
|
44
|
+
enabled: enableA11y,
|
|
45
|
+
// The consumer's own id and menu naming are kept — see ButtonDropdown.
|
|
46
|
+
id: restButtonProps.id,
|
|
47
|
+
menuId: menu?.menuId,
|
|
48
|
+
ariaLabel: menu?.ariaLabel,
|
|
49
|
+
ariaLabelledBy: menu?.ariaLabelledBy
|
|
50
|
+
});
|
|
40
51
|
const {
|
|
41
52
|
x,
|
|
42
53
|
y,
|
|
@@ -61,6 +72,7 @@ const InlineDropdown = exports.InlineDropdown = /*#__PURE__*/React.forwardRef((_
|
|
|
61
72
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_clickAway.ClickAway, {
|
|
62
73
|
onChange: onMenuToggle,
|
|
63
74
|
clickAwayRef: clickAwayRef,
|
|
75
|
+
restoreFocusOnClose: enableA11y,
|
|
64
76
|
children: _ref2 => {
|
|
65
77
|
let {
|
|
66
78
|
isOpen,
|
|
@@ -79,6 +91,12 @@ const InlineDropdown = exports.InlineDropdown = /*#__PURE__*/React.forwardRef((_
|
|
|
79
91
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_Button.UnstyledButton, {
|
|
80
92
|
...restButtonProps,
|
|
81
93
|
disabled: disabled,
|
|
94
|
+
...menuTrigger.getTriggerProps({
|
|
95
|
+
// With no `menu` there is no popup to advertise or to open.
|
|
96
|
+
isOpen: isOpen && Boolean(menu),
|
|
97
|
+
onOpen,
|
|
98
|
+
onKeyDown: restButtonProps.onKeyDown
|
|
99
|
+
}),
|
|
82
100
|
ref: (0, _mergeRefs.mergeRefs)([refs.setReference, triggerRef]),
|
|
83
101
|
onClick: e => {
|
|
84
102
|
e.stopPropagation();
|
|
@@ -110,10 +128,10 @@ const InlineDropdown = exports.InlineDropdown = /*#__PURE__*/React.forwardRef((_
|
|
|
110
128
|
})
|
|
111
129
|
})]
|
|
112
130
|
}), isOpen && menu && /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.FloatingPortal, {
|
|
113
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
114
|
-
|
|
131
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MenuFocusScope.MenuFocusScope, {
|
|
132
|
+
enabled: !enableA11y,
|
|
115
133
|
context: context,
|
|
116
|
-
initialFocus:
|
|
134
|
+
initialFocus: refs.reference,
|
|
117
135
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
118
136
|
className: _InlineDropdownModule.default.menuWrapper,
|
|
119
137
|
ref: (0, _mergeRefs.mergeRefs)([refs.setFloating, boundaryRef]),
|
|
@@ -138,6 +156,7 @@ const InlineDropdown = exports.InlineDropdown = /*#__PURE__*/React.forwardRef((_
|
|
|
138
156
|
},
|
|
139
157
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Menu.Menu, {
|
|
140
158
|
...menu,
|
|
159
|
+
...menuTrigger.menuProps,
|
|
141
160
|
onSelect: (option, e) => {
|
|
142
161
|
onOptionSelect?.(option, e);
|
|
143
162
|
if (
|
|
@@ -148,6 +167,7 @@ const InlineDropdown = exports.InlineDropdown = /*#__PURE__*/React.forwardRef((_
|
|
|
148
167
|
},
|
|
149
168
|
size: menu.size || 'medium',
|
|
150
169
|
onTabOut: clickAway,
|
|
170
|
+
enableA11y: enableA11y,
|
|
151
171
|
testId: (0, _qa.generateTestId)({
|
|
152
172
|
base: testId,
|
|
153
173
|
slot: 'menu'
|
|
@@ -111,6 +111,44 @@
|
|
|
111
111
|
borderWidthTertiary colorFocusPrimary;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/*
|
|
115
|
+
* The field is a popup trigger whose popup is open, so DOM focus has moved into a
|
|
116
|
+
* portal and `:focus-within` above no longer matches. Keep the emphasis anyway,
|
|
117
|
+
* including while hovered — otherwise the hover rule repaints the border grey and
|
|
118
|
+
* leaves the popup's halo behind it, a two-tone broken state.
|
|
119
|
+
*
|
|
120
|
+
* These live here rather than in Dropdown/Typeahead's own module because the
|
|
121
|
+
* rules being overridden are scoped to THIS module's `.wrapper` / `.box` /
|
|
122
|
+
* `.withError` class names, which a consumer stylesheet cannot name and so cannot
|
|
123
|
+
* reliably out-specify.
|
|
124
|
+
*
|
|
125
|
+
* Both the popup attribute AND the expanded state are required so this only ever
|
|
126
|
+
* hits a TRIGGER. On `aria-expanded` alone it also matches any other expanded
|
|
127
|
+
* input inside the field — such as a filter field rendered in the popup — and
|
|
128
|
+
* paints a focus ring on something that never has focus. `:not(.locked)` matches
|
|
129
|
+
* the adjacent hover rules: keying off ARIA loses the protection `:focus-within`
|
|
130
|
+
* had for free, since a locked field's input is natively disabled and so could
|
|
131
|
+
* never have been focused.
|
|
132
|
+
*/
|
|
133
|
+
.wrapper:not(.withError)
|
|
134
|
+
.box:not(.inputDisabled):not(.locked):has(
|
|
135
|
+
input[aria-haspopup][aria-expanded='true']
|
|
136
|
+
) {
|
|
137
|
+
border-color: colorFillPrimary;
|
|
138
|
+
box-shadow: borderWidthNone borderWidthNone borderWidthNone
|
|
139
|
+
borderWidthTertiary colorFocusPrimary;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* An errored trigger keeps the danger colors when its popup is open. */
|
|
143
|
+
.wrapper.withError
|
|
144
|
+
.box:not(.inputDisabled):not(.locked):has(
|
|
145
|
+
input[aria-haspopup][aria-expanded='true']
|
|
146
|
+
) {
|
|
147
|
+
border-color: colorTextDanger;
|
|
148
|
+
box-shadow: borderWidthNone borderWidthNone borderWidthNone
|
|
149
|
+
borderWidthTertiary colorFocusDanger;
|
|
150
|
+
}
|
|
151
|
+
|
|
114
152
|
.inputDisabled {
|
|
115
153
|
color: colorTextDisabled;
|
|
116
154
|
border-color: colorBorderPrimary;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { Flow } from 'flow-to-typescript-codemod';
|
|
3
|
+
import { FixedSizeList, VariableSizeList } from 'react-window';
|
|
3
4
|
import type { MenuClassNames, MenuLabelTooltip } from '../../types/menu';
|
|
4
5
|
import type { IconType } from '../../components/Icon/Icon';
|
|
5
6
|
type ClassNames = MenuClassNames;
|
|
@@ -24,6 +25,11 @@ export type Virtualization = Readonly<{
|
|
|
24
25
|
/** Max height of the whole card in px, search/header/footer included; never below the first row. */
|
|
25
26
|
menuHeight?: number;
|
|
26
27
|
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Either react-window list Menu may render. Both expose the `scrollToItem`
|
|
30
|
+
* used to keep the keyboard's active option mounted.
|
|
31
|
+
*/
|
|
32
|
+
type VirtualList = FixedSizeList | VariableSizeList;
|
|
27
33
|
export interface MenuOption {
|
|
28
34
|
key: string;
|
|
29
35
|
classNames?: OptionClassNames;
|
|
@@ -51,7 +57,32 @@ export interface BaseMenuProps {
|
|
|
51
57
|
width?: string;
|
|
52
58
|
menuDisabled?: boolean;
|
|
53
59
|
isFluid?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Opt in to the accessibility behavior: keyboard navigation, the
|
|
62
|
+
* `listbox` / `option` roles and their states, focus management on open and
|
|
63
|
+
* close, and the scroll container moving onto the listbox.
|
|
64
|
+
*
|
|
65
|
+
* Off by default, and off is not a degraded mode — it is this component
|
|
66
|
+
* exactly as it behaved before any of it existed: no roles, no ARIA, no key
|
|
67
|
+
* handling, no focus moved, the card scrolling as it always did. Every prop
|
|
68
|
+
* below that exists to serve the accessible behavior (`onTabOut`,
|
|
69
|
+
* `onReturnFocusToInput`, `menuId`, `ariaLabelledBy`, `ariaLabel`,
|
|
70
|
+
* `initialFocusRef`, `activeOptionKey`, `externalKeyboardNav`,
|
|
71
|
+
* `onActiveOptionKeyChange`) is inert while this is unset.
|
|
72
|
+
*
|
|
73
|
+
* It is opt-in per call site so a surface can turn it on, verify it, and
|
|
74
|
+
* leave the rest of the app untouched — the behavior changes focus and DOM
|
|
75
|
+
* structure, and those are the things an app is most likely to have built
|
|
76
|
+
* around.
|
|
77
|
+
*/
|
|
78
|
+
enableA11y?: boolean;
|
|
54
79
|
onTabOut?: () => unknown;
|
|
80
|
+
/**
|
|
81
|
+
* Combobox consumers only: return focus to the trigger input (menu stays open)
|
|
82
|
+
* when Tab/Shift+Tab moves off a header/footer control back toward the input.
|
|
83
|
+
* The input lives outside the menu DOM, so it is the centre of the tab order.
|
|
84
|
+
*/
|
|
85
|
+
onReturnFocusToInput?: () => void;
|
|
55
86
|
allowSearch?: boolean;
|
|
56
87
|
resolveLabel?: (option: MenuOption) => string | React.ReactNode;
|
|
57
88
|
resolveSecondaryLabel?: (option: MenuOption) => string | React.ReactNode;
|
|
@@ -63,9 +94,56 @@ export interface BaseMenuProps {
|
|
|
63
94
|
RESULT?: string;
|
|
64
95
|
RESULTS?: string;
|
|
65
96
|
SEARCH_PLACEHOLDER?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Announced by a `Typeahead`'s live region while it is loading, and when a
|
|
99
|
+
* search returns nothing. Here rather than on `Typeahead` so every string a
|
|
100
|
+
* menu can speak is overridden in one place.
|
|
101
|
+
*/
|
|
102
|
+
LOADING_RESULTS?: string;
|
|
103
|
+
NO_RESULTS?: string;
|
|
66
104
|
};
|
|
67
105
|
showLabelTooltip?: MenuLabelTooltip;
|
|
68
106
|
allowWrap?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* id applied to the option `listbox` — the element a trigger's `aria-controls`
|
|
109
|
+
* should reference — and the prefix for the per-option ids that
|
|
110
|
+
* `aria-activedescendant` points at. Falls back to a generated id. It is not
|
|
111
|
+
* on the outer card.
|
|
112
|
+
*/
|
|
113
|
+
menuId?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Accessible name for the popup, linked to the trigger that opens it.
|
|
116
|
+
*/
|
|
117
|
+
ariaLabelledBy?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Literal accessible name for the listbox, used only when `ariaLabelledBy` is
|
|
120
|
+
* not supplied. Defaults to `'Options'` so the listbox is never unnamed — pass
|
|
121
|
+
* something specific to the content wherever you can.
|
|
122
|
+
*/
|
|
123
|
+
ariaLabel?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Marks the Menu as a popup that should auto-focus on open. When provided,
|
|
126
|
+
* Menu moves focus to the search input (or the active option) once it mounts
|
|
127
|
+
* and writes that element into the ref. Omit it for inline Menus (and for
|
|
128
|
+
* combobox triggers using `externalKeyboardNav`) so focus is never stolen.
|
|
129
|
+
*/
|
|
130
|
+
initialFocusRef?: React.RefObject<HTMLElement | null>;
|
|
131
|
+
/**
|
|
132
|
+
* Controlled active option, honoured only with `externalKeyboardNav`: the
|
|
133
|
+
* trigger outside the menu owns the highlight and reports it here. Without
|
|
134
|
+
* `externalKeyboardNav` Menu manages its own active option (the roving tab
|
|
135
|
+
* stop, or the search field's active descendant) and this prop is ignored.
|
|
136
|
+
*/
|
|
137
|
+
activeOptionKey?: string | null;
|
|
138
|
+
/**
|
|
139
|
+
* When true the Menu is driven by an external combobox input (e.g. Dropdown /
|
|
140
|
+
* Typeahead): focus stays on that input, the Menu does not run its own
|
|
141
|
+
* keyboard navigation or move focus into itself, and `activeOptionKey` is a
|
|
142
|
+
* controlled prop reflecting the input's aria-activedescendant.
|
|
143
|
+
*/
|
|
144
|
+
externalKeyboardNav?: boolean;
|
|
145
|
+
/** Report active-option changes when `externalKeyboardNav` is set. */
|
|
146
|
+
onActiveOptionKeyChange?: (key: string | null) => void;
|
|
69
147
|
testId?: string;
|
|
70
148
|
}
|
|
71
149
|
export interface MenuOptionTypes {
|
|
@@ -84,7 +162,28 @@ export interface MenuProps extends BaseMenuProps, MenuOptionTypes {
|
|
|
84
162
|
}
|
|
85
163
|
export interface RenderOptionProps extends Omit<MenuProps, 'searchText'> {
|
|
86
164
|
searchText?: string;
|
|
165
|
+
/** Pointer-activation handler threaded down to each MenuOptionButton. */
|
|
166
|
+
onPointerActivate?: (key: string, el: HTMLElement, clientX: number, clientY: number) => void;
|
|
167
|
+
/** Handle on the virtual list, so Menu can scroll the active option into view. */
|
|
168
|
+
listRef?: React.RefCallback<VirtualList>;
|
|
169
|
+
/** Key the pointer most recently highlighted — keeps the focus ring off it. */
|
|
170
|
+
pointerActiveKey?: string | null;
|
|
171
|
+
/** Withhold the opening highlight until the user drives the menu themselves. */
|
|
172
|
+
suppressInitialHighlight?: boolean;
|
|
173
|
+
/** Whether focus is inside the menu — a roving highlight is only drawn then. */
|
|
174
|
+
menuHasFocus?: boolean;
|
|
87
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Flatten the active option source (options | compose | groups) into one list.
|
|
178
|
+
* Exported because a combobox trigger drives the highlight from outside Menu
|
|
179
|
+
* and needs the same list Menu itself navigates — see `useMenuTrigger`.
|
|
180
|
+
*/
|
|
181
|
+
export declare const getFlatOptions: (props: MenuProps) => MenuOption[];
|
|
182
|
+
/**
|
|
183
|
+
* Key of the option that should own the roving tab stop when the menu opens:
|
|
184
|
+
* the selected option if present, otherwise the first enabled option.
|
|
185
|
+
*/
|
|
186
|
+
export declare const getInitialActiveOptionKey: (props: MenuProps) => string | null;
|
|
88
187
|
export declare const Menu: Flow.AbstractComponent<MenuProps, HTMLDivElement>;
|
|
89
188
|
export {};
|
|
90
189
|
//# sourceMappingURL=Menu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"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"}
|