@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
|
@@ -12,7 +12,14 @@ export declare const TAB_SIZE: Readonly<{
|
|
|
12
12
|
}>;
|
|
13
13
|
export declare const tabSizeOptions: Array<unknown>;
|
|
14
14
|
export type TabSize = keyof typeof TAB_SIZE;
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Attributes forwarded straight to the underlying `<button>`. Declared rather
|
|
17
|
+
* than relied on: `Tab` spreads its rest props, so these reached the DOM
|
|
18
|
+
* whether or not the type mentioned them — which meant a future refactor could
|
|
19
|
+
* drop a popup trigger's ARIA with no type error anywhere.
|
|
20
|
+
*/
|
|
21
|
+
type ForwardedButtonProps = Pick<React.ButtonHTMLAttributes<HTMLButtonElement>, 'id' | 'aria-label' | 'aria-haspopup' | 'aria-expanded' | 'aria-controls' | 'onKeyDown'>;
|
|
22
|
+
export interface TabProps extends ForwardedButtonProps {
|
|
16
23
|
classNames?: ClassNames;
|
|
17
24
|
onSelect?: (arg1: {
|
|
18
25
|
tabId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tab.d.ts","sourceRoot":"","sources":["../../../../src/components/Tabs/Tab/Tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAMrD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAM1D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAEH,eAAO,MAAM,QAAQ;;;EAGnB,CAAC;AAEH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,OAAO,CAA8B,CAAC;AAEzE,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,QAAQ,CAAC;AAE5C,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"Tab.d.ts","sourceRoot":"","sources":["../../../../src/components/Tabs/Tab/Tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAMrD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAM1D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAEH,eAAO,MAAM,QAAQ;;;EAGnB,CAAC;AAEH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,OAAO,CAA8B,CAAC;AAEzE,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,QAAQ,CAAC;AAE5C;;;;;GAKG;AACH,KAAK,oBAAoB,GAAG,IAAI,CAC9B,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAC3C,IAAI,GACJ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,eAAe,GACf,WAAW,CACd,CAAC;AAEF,MAAM,WAAW,QAAS,SAAQ,oBAAoB;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,CA6HjE,CAAC"}
|
|
@@ -20,6 +20,14 @@ const TAB_SIZE = exports.TAB_SIZE = Object.freeze({
|
|
|
20
20
|
medium: 'medium'
|
|
21
21
|
});
|
|
22
22
|
const tabSizeOptions = exports.tabSizeOptions = [...Object.keys(TAB_SIZE)];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Attributes forwarded straight to the underlying `<button>`. Declared rather
|
|
26
|
+
* than relied on: `Tab` spreads its rest props, so these reached the DOM
|
|
27
|
+
* whether or not the type mentioned them — which meant a future refactor could
|
|
28
|
+
* drop a popup trigger's ARIA with no type error anywhere.
|
|
29
|
+
*/
|
|
30
|
+
|
|
23
31
|
const Tab = exports.Tab = /*#__PURE__*/React.forwardRef((_ref, forwardRef) => {
|
|
24
32
|
let {
|
|
25
33
|
classNames,
|
|
@@ -17,9 +17,18 @@ export interface TabDropdownProps {
|
|
|
17
17
|
classNames?: ClassNames;
|
|
18
18
|
selected?: boolean;
|
|
19
19
|
disabled?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Opt in to the accessibility behavior: `aria-haspopup` / `aria-expanded` /
|
|
22
|
+
* `aria-controls` on the tab, the arrow key that opens the popup, and focus
|
|
23
|
+
* moving into the menu and back. Forwarded to the `Menu` this opens.
|
|
24
|
+
*
|
|
25
|
+
* Off by default, and off is this component exactly as it behaved before any
|
|
26
|
+
* of it existed.
|
|
27
|
+
*/
|
|
28
|
+
enableA11y?: boolean;
|
|
20
29
|
elevation?: ElevationType;
|
|
21
30
|
testId?: string;
|
|
22
31
|
}
|
|
23
|
-
export declare const TabDropdown: ({ anchorPosition, size, onOptionSelect, props, elevation, classNames, testId, }: TabDropdownProps) => React.JSX.Element;
|
|
32
|
+
export declare const TabDropdown: ({ anchorPosition, size, onOptionSelect, props, elevation, classNames, enableA11y, testId, }: TabDropdownProps) => React.JSX.Element;
|
|
24
33
|
export {};
|
|
25
34
|
//# sourceMappingURL=TabDropdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabDropdown.d.ts","sourceRoot":"","sources":["../../../../src/components/Tabs/TabList/TabDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TabDropdown.d.ts","sourceRoot":"","sources":["../../../../src/components/Tabs/TabList/TabDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAC,UAAU,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAI/D,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAM1D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,QAAQ,CAAC;QACd,IAAI,EAAE,SAAS,CAAC;KACjB,CAAC;IACF,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,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,WAAW,GAAI,6FASzB,gBAAgB,sBAwFlB,CAAC"}
|
|
@@ -12,6 +12,8 @@ var _clickAway = require("../../../utils/click-away");
|
|
|
12
12
|
var _mergeRefs = require("../../../utils/merge-refs");
|
|
13
13
|
var _qa = require("../../../utils/qa");
|
|
14
14
|
var _Menu = require("../../Menu");
|
|
15
|
+
var _MenuFocusScope = require("../../Menu/MenuFocusScope");
|
|
16
|
+
var _useMenuTrigger = require("../../Menu/useMenuTrigger");
|
|
15
17
|
var _Tab = require("../Tab");
|
|
16
18
|
var _Tooltip = require("../../Tooltip");
|
|
17
19
|
var _TabDropdownModule = _interopRequireDefault(require("./TabDropdown.module.css"));
|
|
@@ -26,8 +28,17 @@ const TabDropdown = _ref => {
|
|
|
26
28
|
props,
|
|
27
29
|
elevation = 'modal',
|
|
28
30
|
classNames,
|
|
31
|
+
enableA11y = false,
|
|
29
32
|
testId
|
|
30
33
|
} = _ref;
|
|
34
|
+
const menuTrigger = (0, _useMenuTrigger.useMenuTrigger)({
|
|
35
|
+
enabled: enableA11y,
|
|
36
|
+
// The consumer's own id and menu naming win — see ButtonDropdown.
|
|
37
|
+
id: props?.tab?.id,
|
|
38
|
+
menuId: props?.menu?.menuId,
|
|
39
|
+
ariaLabel: props?.menu?.ariaLabel,
|
|
40
|
+
ariaLabelledBy: props?.menu?.ariaLabelledBy
|
|
41
|
+
});
|
|
31
42
|
const {
|
|
32
43
|
x,
|
|
33
44
|
y,
|
|
@@ -42,6 +53,7 @@ const TabDropdown = _ref => {
|
|
|
42
53
|
middleware: [(0, _react2.shift)(), (0, _react2.flip)(), (0, _react2.offset)(parseInt(_space.spaceXXSmall))]
|
|
43
54
|
});
|
|
44
55
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_clickAway.ClickAway, {
|
|
56
|
+
restoreFocusOnClose: enableA11y,
|
|
45
57
|
children: _ref2 => {
|
|
46
58
|
let {
|
|
47
59
|
isOpen,
|
|
@@ -58,6 +70,12 @@ const TabDropdown = _ref => {
|
|
|
58
70
|
className: (0, _classify.classify)(_TabDropdownModule.default.tabDropdownContainer, classNames?.wrapper),
|
|
59
71
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tab.Tab, {
|
|
60
72
|
...props?.tab,
|
|
73
|
+
...menuTrigger.getTriggerProps({
|
|
74
|
+
// With no `menu` there is no popup to advertise or to open.
|
|
75
|
+
isOpen: isOpen && Boolean(props?.menu),
|
|
76
|
+
onOpen,
|
|
77
|
+
onKeyDown: props?.tab?.onKeyDown
|
|
78
|
+
}),
|
|
61
79
|
size: size,
|
|
62
80
|
ref: (0, _mergeRefs.mergeRefs)([refs.setReference, triggerRef]),
|
|
63
81
|
onClick: e => {
|
|
@@ -73,8 +91,8 @@ const TabDropdown = _ref => {
|
|
|
73
91
|
slot: 'dropdown-tab'
|
|
74
92
|
})
|
|
75
93
|
}), isOpen && props?.menu && /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.FloatingPortal, {
|
|
76
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
77
|
-
|
|
94
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MenuFocusScope.MenuFocusScope, {
|
|
95
|
+
enabled: !enableA11y,
|
|
78
96
|
context: context,
|
|
79
97
|
initialFocus: refs.reference,
|
|
80
98
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
@@ -93,6 +111,7 @@ const TabDropdown = _ref => {
|
|
|
93
111
|
},
|
|
94
112
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Menu.Menu, {
|
|
95
113
|
...props.menu,
|
|
114
|
+
...menuTrigger.menuProps,
|
|
96
115
|
onSelect: (option, e) => {
|
|
97
116
|
onOptionSelect?.(option, e);
|
|
98
117
|
clickAway();
|
|
@@ -102,7 +121,8 @@ const TabDropdown = _ref => {
|
|
|
102
121
|
testId: (0, _qa.generateTestId)({
|
|
103
122
|
base: testId,
|
|
104
123
|
slot: 'menu'
|
|
105
|
-
})
|
|
124
|
+
}),
|
|
125
|
+
enableA11y: enableA11y
|
|
106
126
|
})
|
|
107
127
|
})
|
|
108
128
|
})
|
|
@@ -19,6 +19,20 @@ export interface TabListProps {
|
|
|
19
19
|
menuWidth?: string;
|
|
20
20
|
elevation?: ElevationType;
|
|
21
21
|
maxTabWidth?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Accessible name for the overflow tab, which is icon-only and therefore has
|
|
24
|
+
* no text of its own — it also names the listbox that tab opens. Override it
|
|
25
|
+
* for another language, as `ButtonTabs` does with `wrapTabTitle`.
|
|
26
|
+
*/
|
|
27
|
+
overflowTabLabel?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Opt in to the accessibility behavior for the overflow tab and the menu it
|
|
30
|
+
* opens, and give that icon-only tab an accessible name.
|
|
31
|
+
*
|
|
32
|
+
* Off by default, and off is this component exactly as it behaved before any
|
|
33
|
+
* of it existed.
|
|
34
|
+
*/
|
|
35
|
+
enableA11y?: boolean;
|
|
22
36
|
testId?: string;
|
|
23
37
|
}
|
|
24
38
|
export declare const TabList: Flow.AbstractComponent<TabListProps, HTMLDivElement>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../../../src/components/Tabs/TabList/TabList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAWrD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAuB1D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC;IAC9D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../../../src/components/Tabs/TabList/TabList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAWrD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAuB1D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC;IAC9D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,cAAc,CAoKtE,CAAC"}
|
|
@@ -29,6 +29,8 @@ const TabList = exports.TabList = /*#__PURE__*/React.forwardRef((_ref, forwardRe
|
|
|
29
29
|
// tooltips may appear over the modal. In such cases, handle it by passing an appropriate elevation.
|
|
30
30
|
elevation = 'modal',
|
|
31
31
|
maxTabWidth = _size.size120,
|
|
32
|
+
overflowTabLabel = 'More tabs',
|
|
33
|
+
enableA11y = false,
|
|
32
34
|
testId
|
|
33
35
|
} = _ref;
|
|
34
36
|
const ref = React.useRef(null);
|
|
@@ -107,6 +109,9 @@ const TabList = exports.TabList = /*#__PURE__*/React.forwardRef((_ref, forwardRe
|
|
|
107
109
|
props: {
|
|
108
110
|
tab: {
|
|
109
111
|
iconName: 'ellipsis',
|
|
112
|
+
// Also names the listbox this tab opens, through the trigger
|
|
113
|
+
// idref the hook sets up.
|
|
114
|
+
'aria-label': enableA11y ? overflowTabLabel : undefined,
|
|
110
115
|
tabId: 'tab-dropdown',
|
|
111
116
|
selectedTab: {
|
|
112
117
|
tabId: isMenuOptionSelected ? 'tab-dropdown' : ''
|
|
@@ -121,6 +126,7 @@ const TabList = exports.TabList = /*#__PURE__*/React.forwardRef((_ref, forwardRe
|
|
|
121
126
|
}
|
|
122
127
|
},
|
|
123
128
|
elevation: elevation,
|
|
129
|
+
enableA11y: enableA11y,
|
|
124
130
|
testId: (0, _qa.generateTestId)({
|
|
125
131
|
base: testId,
|
|
126
132
|
slot: 'dropdown'
|
|
@@ -21,6 +21,15 @@ interface BaseTypeaheadProps extends Omit<InputProps, 'classNames' | 'onSelect'
|
|
|
21
21
|
menuOpenOffset?: number;
|
|
22
22
|
clickAwayRef?: React.RefObject<ClickAwayRefType | null>;
|
|
23
23
|
elevation?: ElevationType;
|
|
24
|
+
/**
|
|
25
|
+
* Opt in to the accessibility behavior: the `combobox` role and its ARIA,
|
|
26
|
+
* arrow-key navigation of the suggestions from the input, and focus handling
|
|
27
|
+
* on close. Forwarded to the `Menu` this opens.
|
|
28
|
+
*
|
|
29
|
+
* Off by default, and off is this component exactly as it behaved before any
|
|
30
|
+
* of it existed.
|
|
31
|
+
*/
|
|
32
|
+
enableA11y?: boolean;
|
|
24
33
|
testId?: string;
|
|
25
34
|
rightSlot?: React.ReactNode;
|
|
26
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../../src/components/Typeahead/Typeahead.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../../src/components/Typeahead/Typeahead.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAKrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAK3D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAC,UAAU,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAK/D,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAM1D,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH,UAAU,kBACR,SAAQ,IAAI,CACV,UAAU,EACR,YAAY,GACZ,UAAU,GACV,UAAU,GACV,YAAY,GACZ,aAAa,GACb,oBAAoB,GACpB,MAAM,GACN,SAAS,GACT,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,WAAW,CACd;IACD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,UAAU,EAClB,IAAI,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,KACxD,OAAO,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,OAAO,CAAC;IACjE,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACxD,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,cACf,SAAQ,IAAI,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;IACvD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAuXD,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAC5C,cAAc,EACd,gBAAgB,CASjB,CAAC"}
|
|
@@ -13,6 +13,8 @@ var _clickAway = require("../../utils/click-away");
|
|
|
13
13
|
var _mergeRefs = require("../../utils/merge-refs");
|
|
14
14
|
var _qa = require("../../utils/qa");
|
|
15
15
|
var _Menu = require("../Menu");
|
|
16
|
+
var _MenuFocusScope = require("../Menu/MenuFocusScope");
|
|
17
|
+
var _useMenuTrigger = require("../Menu/useMenuTrigger");
|
|
16
18
|
var _SearchInput = require("../SearchInput");
|
|
17
19
|
var _Tooltip = require("../Tooltip");
|
|
18
20
|
var _TypeaheadModule = _interopRequireDefault(require("./Typeahead.module.css"));
|
|
@@ -36,6 +38,7 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
36
38
|
onFocus,
|
|
37
39
|
clickAwayRef,
|
|
38
40
|
elevation = 'modal',
|
|
41
|
+
enableA11y = false,
|
|
39
42
|
testId,
|
|
40
43
|
rightSlot,
|
|
41
44
|
...inputProps
|
|
@@ -44,6 +47,12 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
44
47
|
const groupTitleOptions = menu?.groupTitleOptions;
|
|
45
48
|
const isMenuOptionsPresent = menuOptions && menuOptions.length > 0;
|
|
46
49
|
const isMenuGroupPresent = groupTitleOptions && groupTitleOptions.length > 0;
|
|
50
|
+
const menuListRef = React.useRef(null);
|
|
51
|
+
const clickAwayFnRef = React.useRef(null);
|
|
52
|
+
// Set when we close the menu ourselves after a selection, so the focus
|
|
53
|
+
// restoration that follows does not read as the user entering the field.
|
|
54
|
+
const skipNextFocusOpenRef = React.useRef(false);
|
|
55
|
+
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
|
|
47
56
|
const {
|
|
48
57
|
x,
|
|
49
58
|
y,
|
|
@@ -58,7 +67,58 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
58
67
|
middleware: [(0, _react2.flip)(), (0, _react2.offset)(parseInt(_space.spaceXXSmall))]
|
|
59
68
|
});
|
|
60
69
|
const dropdownWidth = (0, _hooks.useReferenceElementWidth)(refs.reference?.current);
|
|
70
|
+
|
|
71
|
+
// The options Menu will actually render, in its own precedence: it returns
|
|
72
|
+
// on the first non-empty source, so concatenating both would count and
|
|
73
|
+
// navigate rows that are not on screen.
|
|
74
|
+
const flatOptions = React.useMemo(() => (0, _Menu.getFlatOptions)({
|
|
75
|
+
options: menuOptions,
|
|
76
|
+
groupTitleOptions
|
|
77
|
+
}), [menuOptions, groupTitleOptions]);
|
|
78
|
+
const focusSearchInput = () => {
|
|
79
|
+
refs.reference?.current?.querySelector('input')?.focus();
|
|
80
|
+
};
|
|
81
|
+
const handleOptionSelect = (option, e) => {
|
|
82
|
+
onSelect?.(option, e ?? null);
|
|
83
|
+
if (
|
|
84
|
+
// keepMenuOpenOnOptionSelect lets the menu persist on select in the normal variant
|
|
85
|
+
!option.keepMenuOpenOnOptionSelect && (!menu?.optionsVariant || menu.optionsVariant === 'normal')) {
|
|
86
|
+
// Swallow the focus event that ClickAway's focus restoration will fire
|
|
87
|
+
// on the input, so closing here actually sticks — but only when focus is
|
|
88
|
+
// inside the menu and a restoration is therefore coming. Selecting with
|
|
89
|
+
// Enter never moves focus off the input, so nothing would consume the
|
|
90
|
+
// flag and it would swallow the user's next genuine focus instead.
|
|
91
|
+
// Only with the opt-in: without it ClickAway restores no focus, so
|
|
92
|
+
// there is no restoration event to swallow.
|
|
93
|
+
skipNextFocusOpenRef.current = Boolean(enableA11y && typeof document !== 'undefined' && menuListRef.current?.contains(document.activeElement));
|
|
94
|
+
clickAwayFnRef.current?.();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Editable combobox: focus stays on the SearchInput, arrows move the active
|
|
99
|
+
// descendant in the portaled listbox, Enter selects, printable keys fall
|
|
100
|
+
// through to the input (which filters the options). The shared hook owns
|
|
101
|
+
// that wiring, the highlight and the trigger's ARIA.
|
|
102
|
+
const comboboxTrigger = (0, _useMenuTrigger.useComboboxMenuTrigger)({
|
|
103
|
+
enabled: enableA11y,
|
|
104
|
+
pattern: 'autocomplete',
|
|
105
|
+
menu,
|
|
106
|
+
// This component owns filtering, so it hands over the options it will
|
|
107
|
+
// actually render rather than letting the hook read them from `menu`.
|
|
108
|
+
options: flatOptions,
|
|
109
|
+
menuRef: menuListRef,
|
|
110
|
+
isOpen: isMenuOpen,
|
|
111
|
+
onSelectOption: option => handleOptionSelect(option, null),
|
|
112
|
+
onClose: () => clickAwayFnRef.current?.(),
|
|
113
|
+
focusTrigger: focusSearchInput,
|
|
114
|
+
canOpen: () => typeaheadInputText.length >= menuOpenOffset,
|
|
115
|
+
triggerAriaLabelledBy: inputProps['aria-labelledby'],
|
|
116
|
+
triggerAriaLabel: inputProps['aria-label'],
|
|
117
|
+
// These are suggestions, not a fixed set of options.
|
|
118
|
+
defaultAriaLabel: 'Suggestions'
|
|
119
|
+
});
|
|
61
120
|
const onMenuToggle = isOpen => {
|
|
121
|
+
setIsMenuOpen(isOpen);
|
|
62
122
|
if (isOpen) {
|
|
63
123
|
onMenuOpen?.();
|
|
64
124
|
} else {
|
|
@@ -68,6 +128,7 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
68
128
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_clickAway.ClickAway, {
|
|
69
129
|
onChange: onMenuToggle,
|
|
70
130
|
clickAwayRef: clickAwayRef,
|
|
131
|
+
restoreFocusOnClose: enableA11y,
|
|
71
132
|
children: _ref2 => {
|
|
72
133
|
let {
|
|
73
134
|
isOpen,
|
|
@@ -76,6 +137,13 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
76
137
|
boundaryRef,
|
|
77
138
|
triggerRef
|
|
78
139
|
} = _ref2;
|
|
140
|
+
// Capture the latest close handler for keyboard selection (wired at
|
|
141
|
+
// the component top level).
|
|
142
|
+
clickAwayFnRef.current = clickAway;
|
|
143
|
+
// The single source of truth for "the listbox exists right now", used
|
|
144
|
+
// both to render the portal and to drive the trigger's ARIA state so
|
|
145
|
+
// the two can never disagree.
|
|
146
|
+
const isMenuRendered = Boolean(isOpen && !isLoading && menu && (isMenuOptionsPresent || isMenuGroupPresent));
|
|
79
147
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
80
148
|
"data-testid": (0, _qa.generateTestId)({
|
|
81
149
|
base: testId,
|
|
@@ -85,6 +153,21 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
85
153
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_SearchInput.SearchInput, {
|
|
86
154
|
...inputProps,
|
|
87
155
|
ref: ref,
|
|
156
|
+
...comboboxTrigger.getTriggerProps({
|
|
157
|
+
// The popup's own state routes the keys: `onOpen` TOGGLES, so
|
|
158
|
+
// treating an open-but-withheld menu (loading, no matches) as
|
|
159
|
+
// closed would make ArrowDown close it.
|
|
160
|
+
isOpen,
|
|
161
|
+
// ...while the ARIA describes what is actually rendered, since
|
|
162
|
+
// the popup is withheld while loading and when nothing
|
|
163
|
+
// matches. Claiming aria-expanded with an aria-controls IDREF
|
|
164
|
+
// that resolves to nothing is both a lie to the user and an
|
|
165
|
+
// invalid value.
|
|
166
|
+
isExpanded: isMenuRendered,
|
|
167
|
+
onOpen,
|
|
168
|
+
onKeyDown: inputProps.onKeyDown
|
|
169
|
+
}),
|
|
170
|
+
"aria-busy": enableA11y && isLoading || undefined,
|
|
88
171
|
boxRef: (0, _mergeRefs.mergeRefs)([refs.setReference, triggerRef]),
|
|
89
172
|
size: size,
|
|
90
173
|
placeholder: placeholder,
|
|
@@ -106,7 +189,13 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
106
189
|
}
|
|
107
190
|
},
|
|
108
191
|
onFocus: _e => {
|
|
109
|
-
|
|
192
|
+
// Picking an option with the pointer unmounts the row that had
|
|
193
|
+
// focus, so ClickAway hands focus back to this input. That is a
|
|
194
|
+
// restoration, not the user entering the field, and treating it
|
|
195
|
+
// as one would immediately reopen the menu we just closed.
|
|
196
|
+
if (skipNextFocusOpenRef.current) {
|
|
197
|
+
skipNextFocusOpenRef.current = false;
|
|
198
|
+
} else if (typeaheadInputText.length >= menuOpenOffset) {
|
|
110
199
|
if (!isOpen) {
|
|
111
200
|
onOpen();
|
|
112
201
|
}
|
|
@@ -122,9 +211,18 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
122
211
|
base: testId,
|
|
123
212
|
slot: 'search-input'
|
|
124
213
|
})
|
|
125
|
-
}),
|
|
126
|
-
|
|
127
|
-
|
|
214
|
+
}), enableA11y && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
215
|
+
role: "status",
|
|
216
|
+
"aria-live": "polite",
|
|
217
|
+
className: _TypeaheadModule.default.visuallyHidden,
|
|
218
|
+
"data-testid": (0, _qa.generateTestId)({
|
|
219
|
+
base: testId,
|
|
220
|
+
slot: 'live-status'
|
|
221
|
+
}),
|
|
222
|
+
children: isLoading ? menu?.staticLabels?.LOADING_RESULTS ?? 'Loading results' : isOpen ? flatOptions.length === 0 ? menu?.staticLabels?.NO_RESULTS ?? 'No results' : `${flatOptions.length} ${flatOptions.length === 1 ? menu?.staticLabels?.RESULT ?? 'result' : menu?.staticLabels?.RESULTS ?? 'results'}` : ''
|
|
223
|
+
}), isMenuRendered && menu && /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.FloatingPortal, {
|
|
224
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MenuFocusScope.MenuFocusScope, {
|
|
225
|
+
enabled: !enableA11y,
|
|
128
226
|
context: context,
|
|
129
227
|
returnFocus: false,
|
|
130
228
|
initialFocus: refs.reference,
|
|
@@ -151,22 +249,18 @@ const BaseTypeahead = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
151
249
|
},
|
|
152
250
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Menu.Menu, {
|
|
153
251
|
...menu,
|
|
252
|
+
ref: menuListRef,
|
|
253
|
+
...comboboxTrigger.menuProps,
|
|
154
254
|
groupTitleOptions: groupTitleOptions,
|
|
155
255
|
options: menuOptions,
|
|
156
256
|
testId: (0, _qa.generateTestId)({
|
|
157
257
|
base: testId,
|
|
158
258
|
slot: 'menu'
|
|
159
259
|
}),
|
|
160
|
-
onSelect:
|
|
161
|
-
onSelect?.(option, e);
|
|
162
|
-
if (
|
|
163
|
-
// option.keepMenuOpenOnOptionSelect - to allow the menu persist its open stat upon option selection in normal variant
|
|
164
|
-
!option.keepMenuOpenOnOptionSelect && (!menu.optionsVariant || menu.optionsVariant === 'normal')) {
|
|
165
|
-
clickAway();
|
|
166
|
-
}
|
|
167
|
-
},
|
|
260
|
+
onSelect: handleOptionSelect,
|
|
168
261
|
size: menu.size || size,
|
|
169
|
-
onTabOut: clickAway
|
|
262
|
+
onTabOut: clickAway,
|
|
263
|
+
enableA11y: enableA11y
|
|
170
264
|
})
|
|
171
265
|
})
|
|
172
266
|
})
|
|
@@ -14,3 +14,16 @@
|
|
|
14
14
|
width: var(--dropdown-width);
|
|
15
15
|
z-index: var(--menu-elevation);
|
|
16
16
|
}
|
|
17
|
+
|
|
18
|
+
/* Announced by screen readers (loading / result count) but visually hidden. */
|
|
19
|
+
.visuallyHidden {
|
|
20
|
+
position: absolute;
|
|
21
|
+
width: 1px;
|
|
22
|
+
height: 1px;
|
|
23
|
+
margin: -1px;
|
|
24
|
+
padding: 0;
|
|
25
|
+
border: 0;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
clip: rect(0, 0, 0, 0);
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
}
|
package/lib/hooks/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from '../hooks/useDebounce';
|
|
|
4
4
|
export * from '../hooks/useFileUpload';
|
|
5
5
|
export * from '../hooks/useFilteredOptions';
|
|
6
6
|
export * from '../hooks/useInfiniteScroll';
|
|
7
|
+
export * from '../hooks/useInteractionModality';
|
|
7
8
|
export * from '../hooks/useInputState';
|
|
8
9
|
export * from '../hooks/useLockedBody';
|
|
9
10
|
export * from '../hooks/useModal';
|
package/lib/hooks/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC"}
|
package/lib/hooks/index.js
CHANGED
|
@@ -69,6 +69,17 @@ Object.keys(_useInfiniteScroll).forEach(function (key) {
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
|
+
var _useInteractionModality = require("./useInteractionModality");
|
|
73
|
+
Object.keys(_useInteractionModality).forEach(function (key) {
|
|
74
|
+
if (key === "default" || key === "__esModule") return;
|
|
75
|
+
if (key in exports && exports[key] === _useInteractionModality[key]) return;
|
|
76
|
+
Object.defineProperty(exports, key, {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function () {
|
|
79
|
+
return _useInteractionModality[key];
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
72
83
|
var _useInputState = require("./useInputState");
|
|
73
84
|
Object.keys(_useInputState).forEach(function (key) {
|
|
74
85
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInteractionModality/index.ts"],"names":[],"mappings":"AAAA,cAAc,yDAAyD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _useInteractionModality = require("./useInteractionModality");
|
|
7
|
+
Object.keys(_useInteractionModality).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _useInteractionModality[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _useInteractionModality[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type InteractionModality = 'keyboard' | 'pointer';
|
|
2
|
+
/**
|
|
3
|
+
* Begin tracking. Idempotent, and session-scoped by design: the listeners live
|
|
4
|
+
* for the life of the page, so there is nothing to tear down.
|
|
5
|
+
*
|
|
6
|
+
* Tracking has to start BEFORE the thing that wants the answer exists. The
|
|
7
|
+
* interesting question is "how was the popup that just mounted opened?", and the
|
|
8
|
+
* keypress that opened it happened while the popup did not yet exist — so a
|
|
9
|
+
* component reading this on mount is always too late to have attached the
|
|
10
|
+
* listener itself. Whatever renders earlier and knows a popup may follow — a
|
|
11
|
+
* menu trigger — primes it.
|
|
12
|
+
*
|
|
13
|
+
* It is not primed on import. Attaching document listeners is a side effect, and
|
|
14
|
+
* a consumer that has not opted into any of this should get none: an app merely
|
|
15
|
+
* importing a component from this package must not start listening to its
|
|
16
|
+
* keyboard. Capture phase, so the modality is recorded before any component
|
|
17
|
+
* handler reacts to the same event.
|
|
18
|
+
*/
|
|
19
|
+
export declare const startInteractionModalityTracking: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* How the user last interacted with the page, read imperatively.
|
|
22
|
+
*
|
|
23
|
+
* Use this when the answer is needed during render or in an effect rather than
|
|
24
|
+
* as reactive state — for example a popup deciding on mount whether it was opened
|
|
25
|
+
* by keyboard, where re-rendering on later modality changes would be wrong.
|
|
26
|
+
*/
|
|
27
|
+
export declare const getInteractionModality: () => InteractionModality;
|
|
28
|
+
/**
|
|
29
|
+
* How the user last interacted with the page, as reactive state. Re-renders the
|
|
30
|
+
* caller when the user switches between keyboard and pointer.
|
|
31
|
+
*/
|
|
32
|
+
export declare const useInteractionModality: (
|
|
33
|
+
/**
|
|
34
|
+
* Subscribe at all. False leaves the caller on the default and attaches
|
|
35
|
+
* nothing — for a component whose consumer has not opted into the behavior
|
|
36
|
+
* this modality serves.
|
|
37
|
+
*/
|
|
38
|
+
enabled?: boolean) => InteractionModality;
|
|
39
|
+
//# sourceMappingURL=useInteractionModality.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInteractionModality.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInteractionModality/useInteractionModality.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,SAAS,CAAC;AAgEzD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gCAAgC,QAAO,IAOnD,CAAC;AAUF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QAAO,mBACzB,CAAC;AAElB;;;GAGG;AACH,eAAO,MAAM,sBAAsB;AACjC;;;;GAIG;AACH,iBAAc,KACb,mBAWF,CAAC"}
|