@atlaskit/react-select 2.2.1 → 2.4.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/CHANGELOG.md +29 -0
- package/dist/cjs/compiled/components/containers.compiled.css +26 -0
- package/dist/cjs/compiled/components/containers.js +119 -0
- package/dist/cjs/compiled/components/control.compiled.css +51 -0
- package/dist/cjs/compiled/components/control.js +66 -0
- package/dist/cjs/compiled/components/group.compiled.css +12 -0
- package/dist/cjs/compiled/components/group.js +81 -0
- package/dist/cjs/compiled/components/indicators.compiled.css +24 -0
- package/dist/cjs/compiled/components/indicators.js +157 -0
- package/dist/cjs/compiled/components/input.compiled.css +49 -0
- package/dist/cjs/compiled/components/input.js +69 -0
- package/dist/cjs/compiled/components/internal/a11y-text.compiled.css +15 -0
- package/dist/cjs/compiled/components/internal/a11y-text.js +23 -0
- package/dist/cjs/compiled/components/internal/dummy-input.compiled.css +17 -0
- package/dist/cjs/compiled/components/internal/dummy-input.js +30 -0
- package/dist/cjs/compiled/components/internal/required-input.compiled.css +8 -0
- package/dist/cjs/compiled/components/internal/required-input.js +34 -0
- package/dist/cjs/compiled/components/live-region.js +177 -0
- package/dist/cjs/compiled/components/menu.compiled.css +19 -0
- package/dist/cjs/compiled/components/menu.js +491 -0
- package/dist/cjs/compiled/components/multi-value.compiled.css +56 -0
- package/dist/cjs/compiled/components/multi-value.js +199 -0
- package/dist/cjs/compiled/components/option.compiled.css +22 -0
- package/dist/cjs/compiled/components/option.js +57 -0
- package/dist/cjs/compiled/components/placeholder.compiled.css +7 -0
- package/dist/cjs/compiled/components/placeholder.js +45 -0
- package/dist/cjs/compiled/components/single-value.compiled.css +13 -0
- package/dist/cjs/compiled/components/single-value.js +46 -0
- package/dist/cjs/components/containers.js +12 -72
- package/dist/cjs/components/control.js +11 -96
- package/dist/cjs/components/group.js +15 -53
- package/dist/cjs/components/indicators.js +15 -107
- package/dist/cjs/components/input.js +12 -81
- package/dist/cjs/components/internal/a11y-text.js +6 -25
- package/dist/cjs/components/internal/dummy-input.js +8 -36
- package/dist/cjs/components/internal/notify-open-layer-observer.js +1 -0
- package/dist/cjs/components/internal/required-input.js +7 -31
- package/dist/cjs/components/internal/scroll-manager.js +19 -17
- package/dist/cjs/components/live-region.js +6 -164
- package/dist/cjs/components/menu.js +24 -399
- package/dist/cjs/components/multi-value.js +21 -197
- package/dist/cjs/components/option.js +11 -68
- package/dist/cjs/components/placeholder.js +11 -20
- package/dist/cjs/components/single-value.js +11 -26
- package/dist/cjs/emotion/components/containers.js +2 -0
- package/dist/cjs/emotion/components/control.js +2 -0
- package/dist/cjs/emotion/components/group.js +1 -0
- package/dist/cjs/emotion/components/indicators.js +1 -0
- package/dist/cjs/emotion/components/input.js +1 -1
- package/dist/cjs/emotion/components/internal/a11y-text.js +1 -0
- package/dist/cjs/emotion/components/internal/dummy-input.js +1 -0
- package/dist/cjs/emotion/components/internal/required-input.js +2 -0
- package/dist/cjs/emotion/components/internal/scroll-manager.js +2 -0
- package/dist/cjs/emotion/components/live-region.js +1 -1
- package/dist/cjs/emotion/components/menu.js +1 -1
- package/dist/cjs/emotion/components/multi-value.js +1 -1
- package/dist/cjs/emotion/components/option.js +2 -0
- package/dist/cjs/emotion/components/placeholder.js +2 -0
- package/dist/cjs/emotion/components/single-value.js +2 -0
- package/dist/cjs/utils.js +2 -1
- package/dist/es2019/compiled/components/containers.compiled.css +26 -0
- package/dist/es2019/compiled/components/containers.js +115 -0
- package/dist/es2019/compiled/components/control.compiled.css +51 -0
- package/dist/es2019/compiled/components/control.js +58 -0
- package/dist/es2019/compiled/components/group.compiled.css +12 -0
- package/dist/es2019/compiled/components/group.js +72 -0
- package/dist/es2019/compiled/components/indicators.compiled.css +24 -0
- package/dist/es2019/compiled/components/indicators.js +144 -0
- package/dist/es2019/compiled/components/input.compiled.css +49 -0
- package/dist/es2019/compiled/components/input.js +59 -0
- package/dist/es2019/compiled/components/internal/a11y-text.compiled.css +15 -0
- package/dist/es2019/compiled/components/internal/a11y-text.js +11 -0
- package/dist/es2019/compiled/components/internal/dummy-input.compiled.css +17 -0
- package/dist/es2019/compiled/components/internal/dummy-input.js +19 -0
- package/dist/es2019/compiled/components/internal/required-input.compiled.css +8 -0
- package/dist/es2019/compiled/components/internal/required-input.js +23 -0
- package/dist/es2019/compiled/components/live-region.js +171 -0
- package/dist/es2019/compiled/components/menu.compiled.css +19 -0
- package/dist/es2019/compiled/components/menu.js +478 -0
- package/dist/es2019/compiled/components/multi-value.compiled.css +56 -0
- package/dist/es2019/compiled/components/multi-value.js +190 -0
- package/dist/es2019/compiled/components/option.compiled.css +22 -0
- package/dist/es2019/compiled/components/option.js +48 -0
- package/dist/es2019/compiled/components/placeholder.compiled.css +7 -0
- package/dist/es2019/compiled/components/placeholder.js +36 -0
- package/dist/es2019/compiled/components/single-value.compiled.css +13 -0
- package/dist/es2019/compiled/components/single-value.js +37 -0
- package/dist/es2019/components/containers.js +10 -87
- package/dist/es2019/components/control.js +8 -103
- package/dist/es2019/components/group.js +9 -54
- package/dist/es2019/components/indicators.js +11 -113
- package/dist/es2019/components/input.js +7 -83
- package/dist/es2019/components/internal/a11y-text.js +6 -26
- package/dist/es2019/components/internal/dummy-input.js +7 -36
- package/dist/es2019/components/internal/notify-open-layer-observer.js +1 -0
- package/dist/es2019/components/internal/required-input.js +6 -32
- package/dist/es2019/components/internal/scroll-manager.js +16 -16
- package/dist/es2019/components/live-region.js +5 -168
- package/dist/es2019/components/menu.js +14 -412
- package/dist/es2019/components/multi-value.js +12 -216
- package/dist/es2019/components/option.js +7 -75
- package/dist/es2019/components/placeholder.js +7 -25
- package/dist/es2019/components/single-value.js +7 -31
- package/dist/es2019/emotion/components/containers.js +1 -0
- package/dist/es2019/emotion/components/control.js +1 -0
- package/dist/es2019/emotion/components/group.js +1 -0
- package/dist/es2019/emotion/components/indicators.js +1 -0
- package/dist/es2019/emotion/components/input.js +1 -0
- package/dist/es2019/emotion/components/internal/a11y-text.js +1 -0
- package/dist/es2019/emotion/components/internal/dummy-input.js +1 -0
- package/dist/es2019/emotion/components/internal/required-input.js +1 -0
- package/dist/es2019/emotion/components/internal/scroll-manager.js +2 -0
- package/dist/es2019/emotion/components/live-region.js +2 -0
- package/dist/es2019/emotion/components/menu.js +2 -0
- package/dist/es2019/emotion/components/multi-value.js +1 -0
- package/dist/es2019/emotion/components/option.js +1 -0
- package/dist/es2019/emotion/components/placeholder.js +1 -0
- package/dist/es2019/emotion/components/single-value.js +1 -0
- package/dist/es2019/utils.js +1 -0
- package/dist/esm/compiled/components/containers.compiled.css +26 -0
- package/dist/esm/compiled/components/containers.js +110 -0
- package/dist/esm/compiled/components/control.compiled.css +51 -0
- package/dist/esm/compiled/components/control.js +57 -0
- package/dist/esm/compiled/components/group.compiled.css +12 -0
- package/dist/esm/compiled/components/group.js +71 -0
- package/dist/esm/compiled/components/indicators.compiled.css +24 -0
- package/dist/esm/compiled/components/indicators.js +148 -0
- package/dist/esm/compiled/components/input.compiled.css +49 -0
- package/dist/esm/compiled/components/input.js +59 -0
- package/dist/esm/compiled/components/internal/a11y-text.compiled.css +15 -0
- package/dist/esm/compiled/components/internal/a11y-text.js +13 -0
- package/dist/esm/compiled/components/internal/dummy-input.compiled.css +17 -0
- package/dist/esm/compiled/components/internal/dummy-input.js +20 -0
- package/dist/esm/compiled/components/internal/required-input.compiled.css +8 -0
- package/dist/esm/compiled/components/internal/required-input.js +24 -0
- package/dist/esm/compiled/components/live-region.js +168 -0
- package/dist/esm/compiled/components/menu.compiled.css +19 -0
- package/dist/esm/compiled/components/menu.js +485 -0
- package/dist/esm/compiled/components/multi-value.compiled.css +56 -0
- package/dist/esm/compiled/components/multi-value.js +187 -0
- package/dist/esm/compiled/components/option.compiled.css +22 -0
- package/dist/esm/compiled/components/option.js +47 -0
- package/dist/esm/compiled/components/placeholder.compiled.css +7 -0
- package/dist/esm/compiled/components/placeholder.js +35 -0
- package/dist/esm/compiled/components/single-value.compiled.css +13 -0
- package/dist/esm/compiled/components/single-value.js +36 -0
- package/dist/esm/components/containers.js +12 -73
- package/dist/esm/components/control.js +8 -97
- package/dist/esm/components/group.js +11 -54
- package/dist/esm/components/indicators.js +15 -109
- package/dist/esm/components/input.js +8 -83
- package/dist/esm/components/internal/a11y-text.js +6 -26
- package/dist/esm/components/internal/dummy-input.js +7 -37
- package/dist/esm/components/internal/notify-open-layer-observer.js +1 -0
- package/dist/esm/components/internal/required-input.js +7 -32
- package/dist/esm/components/internal/scroll-manager.js +16 -16
- package/dist/esm/components/live-region.js +5 -163
- package/dist/esm/components/menu.js +21 -401
- package/dist/esm/components/multi-value.js +17 -199
- package/dist/esm/components/option.js +8 -69
- package/dist/esm/components/placeholder.js +8 -21
- package/dist/esm/components/single-value.js +8 -27
- package/dist/esm/emotion/components/containers.js +1 -0
- package/dist/esm/emotion/components/control.js +1 -0
- package/dist/esm/emotion/components/group.js +1 -0
- package/dist/esm/emotion/components/indicators.js +1 -0
- package/dist/esm/emotion/components/input.js +1 -0
- package/dist/esm/emotion/components/internal/a11y-text.js +1 -0
- package/dist/esm/emotion/components/internal/dummy-input.js +1 -0
- package/dist/esm/emotion/components/internal/required-input.js +1 -0
- package/dist/esm/emotion/components/internal/scroll-manager.js +2 -0
- package/dist/esm/emotion/components/live-region.js +2 -0
- package/dist/esm/emotion/components/menu.js +2 -0
- package/dist/esm/emotion/components/multi-value.js +1 -0
- package/dist/esm/emotion/components/option.js +1 -0
- package/dist/esm/emotion/components/placeholder.js +1 -0
- package/dist/esm/emotion/components/single-value.js +1 -0
- package/dist/esm/utils.js +2 -1
- package/dist/types/compiled/components/containers.d.ts +53 -0
- package/dist/types/compiled/components/control.d.ts +41 -0
- package/dist/types/compiled/components/group.d.ts +54 -0
- package/dist/types/compiled/components/indicators.d.ts +72 -0
- package/dist/types/compiled/components/input.d.ts +36 -0
- package/dist/types/compiled/components/internal/a11y-text.d.ts +3 -0
- package/dist/types/compiled/components/internal/dummy-input.d.ts +8 -0
- package/dist/types/compiled/components/internal/required-input.d.ts +10 -0
- package/dist/types/compiled/components/live-region.d.ts +19 -0
- package/dist/types/compiled/components/menu.d.ts +115 -0
- package/dist/types/compiled/components/multi-value.d.ts +57 -0
- package/dist/types/compiled/components/option.d.ts +48 -0
- package/dist/types/compiled/components/placeholder.d.ts +21 -0
- package/dist/types/compiled/components/single-value.d.ts +27 -0
- package/dist/types/components/containers.d.ts +6 -11
- package/dist/types/components/control.d.ts +4 -9
- package/dist/types/components/group.d.ts +8 -10
- package/dist/types/components/index.d.ts +21 -21
- package/dist/types/components/indicators.d.ts +7 -12
- package/dist/types/components/input.d.ts +3 -8
- package/dist/types/components/internal/a11y-text.d.ts +2 -7
- package/dist/types/components/internal/dummy-input.d.ts +3 -8
- package/dist/types/components/internal/required-input.d.ts +0 -4
- package/dist/types/components/internal/scroll-manager.d.ts +2 -7
- package/dist/types/components/live-region.d.ts +2 -8
- package/dist/types/components/menu.d.ts +10 -15
- package/dist/types/components/multi-value.d.ts +19 -13
- package/dist/types/components/option.d.ts +3 -8
- package/dist/types/components/placeholder.d.ts +3 -8
- package/dist/types/components/single-value.d.ts +3 -8
- package/dist/types/select.d.ts +21 -21
- package/dist/types/types.d.ts +3 -0
- package/dist/types-ts4.5/compiled/components/containers.d.ts +53 -0
- package/dist/types-ts4.5/compiled/components/control.d.ts +41 -0
- package/dist/types-ts4.5/compiled/components/group.d.ts +54 -0
- package/dist/types-ts4.5/compiled/components/indicators.d.ts +72 -0
- package/dist/types-ts4.5/compiled/components/input.d.ts +36 -0
- package/dist/types-ts4.5/compiled/components/internal/a11y-text.d.ts +3 -0
- package/dist/types-ts4.5/compiled/components/internal/dummy-input.d.ts +8 -0
- package/dist/types-ts4.5/compiled/components/internal/required-input.d.ts +10 -0
- package/dist/types-ts4.5/compiled/components/live-region.d.ts +19 -0
- package/dist/types-ts4.5/compiled/components/menu.d.ts +115 -0
- package/dist/types-ts4.5/compiled/components/multi-value.d.ts +57 -0
- package/dist/types-ts4.5/compiled/components/option.d.ts +48 -0
- package/dist/types-ts4.5/compiled/components/placeholder.d.ts +21 -0
- package/dist/types-ts4.5/compiled/components/single-value.d.ts +27 -0
- package/dist/types-ts4.5/components/containers.d.ts +6 -11
- package/dist/types-ts4.5/components/control.d.ts +4 -9
- package/dist/types-ts4.5/components/group.d.ts +8 -10
- package/dist/types-ts4.5/components/index.d.ts +21 -21
- package/dist/types-ts4.5/components/indicators.d.ts +7 -12
- package/dist/types-ts4.5/components/input.d.ts +3 -8
- package/dist/types-ts4.5/components/internal/a11y-text.d.ts +2 -7
- package/dist/types-ts4.5/components/internal/dummy-input.d.ts +3 -8
- package/dist/types-ts4.5/components/internal/required-input.d.ts +0 -4
- package/dist/types-ts4.5/components/internal/scroll-manager.d.ts +2 -7
- package/dist/types-ts4.5/components/live-region.d.ts +2 -8
- package/dist/types-ts4.5/components/menu.d.ts +10 -15
- package/dist/types-ts4.5/components/multi-value.d.ts +19 -13
- package/dist/types-ts4.5/components/option.d.ts +3 -8
- package/dist/types-ts4.5/components/placeholder.d.ts +3 -8
- package/dist/types-ts4.5/components/single-value.d.ts +3 -8
- package/dist/types-ts4.5/select.d.ts +21 -21
- package/dist/types-ts4.5/types.d.ts +3 -0
- package/package.json +11 -3
- package/dist/cjs/emotion/components/index.js +0 -52
- package/dist/cjs/emotion/components/internal/notify-open-layer-observer.js +0 -21
- package/dist/es2019/emotion/components/index.js +0 -41
- package/dist/es2019/emotion/components/internal/notify-open-layer-observer.js +0 -16
- package/dist/esm/emotion/components/index.js +0 -43
- package/dist/esm/emotion/components/internal/notify-open-layer-observer.js +0 -15
- package/dist/types/emotion/components/index.d.ts +0 -67
- package/dist/types/emotion/components/internal/notify-open-layer-observer.d.ts +0 -11
- package/dist/types-ts4.5/emotion/components/index.d.ts +0 -67
- package/dist/types-ts4.5/emotion/components/internal/notify-open-layer-observer.d.ts +0 -11
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* required-input.tsx generated by @compiled/babel-plugin v0.36.1 */
|
|
2
|
+
import "./required-input.compiled.css";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
+
import __noop from '@atlaskit/ds-lib/noop';
|
|
6
|
+
const styles = null;
|
|
7
|
+
const RequiredInput = ({
|
|
8
|
+
name,
|
|
9
|
+
onFocus
|
|
10
|
+
}) => /*#__PURE__*/React.createElement("input", {
|
|
11
|
+
required: true,
|
|
12
|
+
name: name,
|
|
13
|
+
tabIndex: -1,
|
|
14
|
+
"aria-hidden": "true",
|
|
15
|
+
onFocus: onFocus,
|
|
16
|
+
// Prevent `Switching from uncontrolled to controlled` error
|
|
17
|
+
value: "",
|
|
18
|
+
onChange: __noop,
|
|
19
|
+
className: ax(["_1bsb1osq _kqswstnw _u7coidpf _rjxpidpf _1e02idpf _jqf61a21 _tzy4idpf _lcxvglyw"])
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
23
|
+
export default RequiredInput;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import React, { Fragment, useMemo, useRef } from 'react';
|
|
2
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
|
+
import { defaultAriaLiveMessages } from '../../accessibility';
|
|
4
|
+
import A11yText from './internal/a11y-text';
|
|
5
|
+
|
|
6
|
+
// ==============================
|
|
7
|
+
// Root Container
|
|
8
|
+
// ==============================
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
11
|
+
const LiveRegion = props => {
|
|
12
|
+
const {
|
|
13
|
+
ariaSelection,
|
|
14
|
+
focusedOption,
|
|
15
|
+
focusedValue,
|
|
16
|
+
focusableOptions,
|
|
17
|
+
isFocused,
|
|
18
|
+
selectValue,
|
|
19
|
+
selectProps,
|
|
20
|
+
id,
|
|
21
|
+
isAppleDevice
|
|
22
|
+
} = props;
|
|
23
|
+
const {
|
|
24
|
+
ariaLiveMessages,
|
|
25
|
+
getOptionLabel,
|
|
26
|
+
inputValue,
|
|
27
|
+
isMulti,
|
|
28
|
+
isOptionDisabled,
|
|
29
|
+
isSearchable,
|
|
30
|
+
label,
|
|
31
|
+
menuIsOpen,
|
|
32
|
+
options,
|
|
33
|
+
screenReaderStatus,
|
|
34
|
+
tabSelectsValue,
|
|
35
|
+
isLoading
|
|
36
|
+
} = selectProps;
|
|
37
|
+
const ariaLabel = selectProps['aria-label'] || label;
|
|
38
|
+
const ariaLive = selectProps['aria-live'];
|
|
39
|
+
|
|
40
|
+
// for safari, we will use minimum support from aria-live region
|
|
41
|
+
const isA11yImprovementEnabled = fg('design_system_select-a11y-improvement') && !isAppleDevice;
|
|
42
|
+
|
|
43
|
+
// Update aria live message configuration when prop changes
|
|
44
|
+
const messages = useMemo(() => ({
|
|
45
|
+
...defaultAriaLiveMessages,
|
|
46
|
+
...(ariaLiveMessages || {})
|
|
47
|
+
}), [ariaLiveMessages]);
|
|
48
|
+
|
|
49
|
+
// Update aria live selected option when prop changes
|
|
50
|
+
const ariaSelected = useMemo(() => {
|
|
51
|
+
let message = '';
|
|
52
|
+
if (isA11yImprovementEnabled && menuIsOpen) {
|
|
53
|
+
// we don't need to have selected message when the menu is open
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
if (ariaSelection && messages.onChange) {
|
|
57
|
+
const {
|
|
58
|
+
option,
|
|
59
|
+
options: selectedOptions,
|
|
60
|
+
removedValue,
|
|
61
|
+
removedValues,
|
|
62
|
+
value
|
|
63
|
+
} = ariaSelection;
|
|
64
|
+
// select-option when !isMulti does not return option so we assume selected option is value
|
|
65
|
+
const asOption = val => !Array.isArray(val) ? val : null;
|
|
66
|
+
|
|
67
|
+
// If there is just one item from the action then get its label
|
|
68
|
+
const selected = removedValue || option || asOption(value);
|
|
69
|
+
const label = selected ? getOptionLabel(selected) : '';
|
|
70
|
+
|
|
71
|
+
// If there are multiple items from the action then return an array of labels
|
|
72
|
+
const multiSelected = selectedOptions || removedValues || undefined;
|
|
73
|
+
const labels = multiSelected ? multiSelected.map(getOptionLabel) : [];
|
|
74
|
+
if (isA11yImprovementEnabled && !label && !labels.length) {
|
|
75
|
+
// return empty string if no labels provided
|
|
76
|
+
return '';
|
|
77
|
+
}
|
|
78
|
+
const onChangeProps = {
|
|
79
|
+
// multiSelected items are usually items that have already been selected
|
|
80
|
+
// or set by the user as a default value so we assume they are not disabled
|
|
81
|
+
isDisabled: selected && isOptionDisabled(selected, selectValue),
|
|
82
|
+
label,
|
|
83
|
+
labels,
|
|
84
|
+
...ariaSelection
|
|
85
|
+
};
|
|
86
|
+
message = messages.onChange(onChangeProps);
|
|
87
|
+
}
|
|
88
|
+
return message;
|
|
89
|
+
}, [ariaSelection, messages, isOptionDisabled, selectValue, getOptionLabel, isA11yImprovementEnabled, menuIsOpen]);
|
|
90
|
+
const prevInputValue = useRef('');
|
|
91
|
+
const ariaFocused = useMemo(() => {
|
|
92
|
+
let focusMsg = '';
|
|
93
|
+
const focused = focusedOption || focusedValue;
|
|
94
|
+
const isSelected = !!(focusedOption && selectValue && selectValue.includes(focusedOption));
|
|
95
|
+
if (inputValue === prevInputValue.current && isA11yImprovementEnabled) {
|
|
96
|
+
// only announce focus option when searching when ff is on and the input value changed
|
|
97
|
+
// for safari, we will announce for all
|
|
98
|
+
return '';
|
|
99
|
+
}
|
|
100
|
+
if (focused && messages.onFocus) {
|
|
101
|
+
const onFocusProps = {
|
|
102
|
+
focused,
|
|
103
|
+
label: getOptionLabel(focused),
|
|
104
|
+
isDisabled: isOptionDisabled(focused, selectValue),
|
|
105
|
+
isSelected,
|
|
106
|
+
options: focusableOptions,
|
|
107
|
+
context: focused === focusedOption ? 'menu' : 'value',
|
|
108
|
+
selectValue,
|
|
109
|
+
isMulti
|
|
110
|
+
};
|
|
111
|
+
focusMsg = messages.onFocus(onFocusProps);
|
|
112
|
+
}
|
|
113
|
+
prevInputValue.current = inputValue;
|
|
114
|
+
return focusMsg;
|
|
115
|
+
}, [inputValue, focusedOption, focusedValue, getOptionLabel, isOptionDisabled, messages, focusableOptions, selectValue, isA11yImprovementEnabled, isMulti]);
|
|
116
|
+
const ariaResults = useMemo(() => {
|
|
117
|
+
let resultsMsg = '';
|
|
118
|
+
if (menuIsOpen && options.length && !isLoading && messages.onFilter) {
|
|
119
|
+
const resultsMessage = screenReaderStatus({
|
|
120
|
+
count: focusableOptions.length
|
|
121
|
+
});
|
|
122
|
+
resultsMsg = messages.onFilter({
|
|
123
|
+
inputValue,
|
|
124
|
+
resultsMessage
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return resultsMsg;
|
|
128
|
+
}, [focusableOptions, inputValue, menuIsOpen, messages, options, screenReaderStatus, isLoading]);
|
|
129
|
+
const isInitialFocus = (ariaSelection === null || ariaSelection === void 0 ? void 0 : ariaSelection.action) === 'initial-input-focus';
|
|
130
|
+
const ariaGuidance = useMemo(() => {
|
|
131
|
+
if (fg('design_system_select-a11y-improvement')) {
|
|
132
|
+
// don't announce guidance at all when ff is on
|
|
133
|
+
return '';
|
|
134
|
+
}
|
|
135
|
+
let guidanceMsg = '';
|
|
136
|
+
if (messages.guidance) {
|
|
137
|
+
const context = focusedValue ? 'value' : menuIsOpen ? 'menu' : 'input';
|
|
138
|
+
guidanceMsg = messages.guidance({
|
|
139
|
+
'aria-label': ariaLabel,
|
|
140
|
+
context,
|
|
141
|
+
isDisabled: focusedOption && isOptionDisabled(focusedOption, selectValue),
|
|
142
|
+
isMulti,
|
|
143
|
+
isSearchable,
|
|
144
|
+
tabSelectsValue,
|
|
145
|
+
isInitialFocus
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return guidanceMsg;
|
|
149
|
+
}, [ariaLabel, focusedOption, focusedValue, isMulti, isOptionDisabled, isSearchable, menuIsOpen, messages, selectValue, tabSelectsValue, isInitialFocus]);
|
|
150
|
+
const ScreenReaderText = /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
151
|
+
id: "aria-selection"
|
|
152
|
+
}, ariaSelected), /*#__PURE__*/React.createElement("span", {
|
|
153
|
+
id: "aria-results"
|
|
154
|
+
}, ariaResults), !fg('design_system_select-a11y-improvement') && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
155
|
+
id: "aria-focused"
|
|
156
|
+
}, ariaFocused), /*#__PURE__*/React.createElement("span", {
|
|
157
|
+
id: "aria-guidance"
|
|
158
|
+
}, ariaGuidance)));
|
|
159
|
+
return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(A11yText, {
|
|
160
|
+
id: id
|
|
161
|
+
}, isInitialFocus && ScreenReaderText), /*#__PURE__*/React.createElement(A11yText, {
|
|
162
|
+
"aria-live": ariaLive // Should be undefined by default unless a specific use case requires it
|
|
163
|
+
,
|
|
164
|
+
"aria-atomic": fg('design_system_select-a11y-improvement') ? undefined : 'false',
|
|
165
|
+
"aria-relevant": fg('design_system_select-a11y-improvement') ? undefined : 'additions text',
|
|
166
|
+
role: fg('design_system_select-a11y-improvement') ? 'status' : 'log'
|
|
167
|
+
}, isFocused && !isInitialFocus && ScreenReaderText));
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
171
|
+
export default LiveRegion;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
._2rkoglpi{border-radius:var(--ds-border-radius,4px)}._154i1osq{top:100%}
|
|
3
|
+
._16qsd0yg{box-shadow:var(--ds-shadow-overlay,0 0 0 1px rgba(0,0,0,.1),0 4px 11px rgba(0,0,0,.1))}
|
|
4
|
+
._18m91wug{overflow-y:auto}
|
|
5
|
+
._19pku2gc{margin-top:var(--ds-space-100,8px)}
|
|
6
|
+
._1bsb1osq{width:100%}
|
|
7
|
+
._1pbykb7n{z-index:1}
|
|
8
|
+
._1q51u2gc{padding-block-start:var(--ds-space-100,8px)}
|
|
9
|
+
._85i5u2gc{padding-block-end:var(--ds-space-100,8px)}
|
|
10
|
+
._8am5i4x0{-webkit-overflow-scrolling:touch}
|
|
11
|
+
._94n51osq{bottom:100%}
|
|
12
|
+
._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
|
|
13
|
+
._bozgutpp{padding-inline-start:var(--ds-space-150,9pt)}
|
|
14
|
+
._jqf689mz{label:menu}
|
|
15
|
+
._kqswh2mm{position:relative}
|
|
16
|
+
._kqswstnw{position:absolute}
|
|
17
|
+
._otyru2gc{margin-bottom:var(--ds-space-100,8px)}
|
|
18
|
+
._y3gn1h6o{text-align:center}
|
|
19
|
+
._y4tiutpp{padding-inline-end:var(--ds-space-150,9pt)}
|
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
/* menu.tsx generated by @compiled/babel-plugin v0.36.1 */
|
|
2
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import "./menu.compiled.css";
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
6
|
+
import { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';
|
|
7
|
+
import { cx } from '@compiled/react';
|
|
8
|
+
import { autoUpdate } from '@floating-ui/dom';
|
|
9
|
+
import { createPortal } from 'react-dom';
|
|
10
|
+
import useLayoutEffect from 'use-isomorphic-layout-effect';
|
|
11
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
12
|
+
import { Text } from '@atlaskit/primitives/compiled';
|
|
13
|
+
import { animatedScrollTo, getBoundingClientObj, getScrollParent, getScrollTop, getStyleProps, normalizedHeight, scrollTo } from '../../utils';
|
|
14
|
+
|
|
15
|
+
// ==============================
|
|
16
|
+
// Menu
|
|
17
|
+
// ==============================
|
|
18
|
+
|
|
19
|
+
// Get Menu Placement
|
|
20
|
+
// ------------------------------
|
|
21
|
+
|
|
22
|
+
function getMenuPlacement({
|
|
23
|
+
maxHeight: preferredMaxHeight,
|
|
24
|
+
menuEl,
|
|
25
|
+
minHeight,
|
|
26
|
+
placement: preferredPlacement,
|
|
27
|
+
shouldScroll,
|
|
28
|
+
isFixedPosition,
|
|
29
|
+
controlHeight
|
|
30
|
+
}) {
|
|
31
|
+
const scrollParent = getScrollParent(menuEl);
|
|
32
|
+
const defaultState = {
|
|
33
|
+
placement: 'bottom',
|
|
34
|
+
maxHeight: preferredMaxHeight
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// something went wrong, return default state
|
|
38
|
+
if (!menuEl || !menuEl.offsetParent) {
|
|
39
|
+
return defaultState;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// we can't trust `scrollParent.scrollHeight` --> it may increase when
|
|
43
|
+
// the menu is rendered
|
|
44
|
+
const {
|
|
45
|
+
height: scrollHeight,
|
|
46
|
+
top: scrollParentTop
|
|
47
|
+
} = scrollParent.getBoundingClientRect();
|
|
48
|
+
const {
|
|
49
|
+
bottom: menuBottom,
|
|
50
|
+
height: menuHeight,
|
|
51
|
+
top: menuTop
|
|
52
|
+
} = menuEl.getBoundingClientRect();
|
|
53
|
+
const {
|
|
54
|
+
top: containerTop
|
|
55
|
+
} = menuEl.offsetParent.getBoundingClientRect();
|
|
56
|
+
const viewHeight = isFixedPosition ? window.innerHeight : normalizedHeight(scrollParent);
|
|
57
|
+
const scrollTop = getScrollTop(scrollParent);
|
|
58
|
+
// use menuTop - scrollParentTop for the actual top space of menu in the scroll container
|
|
59
|
+
const menuTopFromParent = fg('design-system-select-fix-placement') ? menuTop - scrollParentTop : menuTop;
|
|
60
|
+
const marginBottom = parseInt(getComputedStyle(menuEl).marginBottom, 10);
|
|
61
|
+
const marginTop = parseInt(getComputedStyle(menuEl).marginTop, 10);
|
|
62
|
+
const viewSpaceAbove = containerTop - marginTop;
|
|
63
|
+
const viewSpaceBelow = viewHeight - menuTopFromParent;
|
|
64
|
+
const scrollSpaceAbove = viewSpaceAbove + scrollTop;
|
|
65
|
+
const scrollSpaceBelow = scrollHeight - scrollTop - menuTopFromParent;
|
|
66
|
+
const scrollDown = menuBottom - viewHeight + scrollTop + marginBottom;
|
|
67
|
+
const scrollUp = scrollTop + menuTop - marginTop;
|
|
68
|
+
const scrollDuration = 160;
|
|
69
|
+
switch (preferredPlacement) {
|
|
70
|
+
case 'auto':
|
|
71
|
+
case 'bottom':
|
|
72
|
+
// 1: the menu will fit, do nothing
|
|
73
|
+
if (viewSpaceBelow >= menuHeight) {
|
|
74
|
+
return {
|
|
75
|
+
placement: 'bottom',
|
|
76
|
+
maxHeight: preferredMaxHeight
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 2: the menu will fit, if scrolled
|
|
81
|
+
if (scrollSpaceBelow >= menuHeight && !isFixedPosition) {
|
|
82
|
+
if (shouldScroll) {
|
|
83
|
+
animatedScrollTo(scrollParent, scrollDown, scrollDuration);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
placement: 'bottom',
|
|
87
|
+
maxHeight: preferredMaxHeight
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 3: the menu will fit, if constrained
|
|
92
|
+
if (!isFixedPosition && scrollSpaceBelow >= minHeight || isFixedPosition && viewSpaceBelow >= minHeight) {
|
|
93
|
+
if (shouldScroll) {
|
|
94
|
+
animatedScrollTo(scrollParent, scrollDown, scrollDuration);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// we want to provide as much of the menu as possible to the user,
|
|
98
|
+
// so give them whatever is available below rather than the minHeight.
|
|
99
|
+
const constrainedHeight = isFixedPosition ? viewSpaceBelow - marginBottom : scrollSpaceBelow - marginBottom;
|
|
100
|
+
return {
|
|
101
|
+
placement: 'bottom',
|
|
102
|
+
maxHeight: constrainedHeight
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 4. Forked beviour when there isn't enough space below
|
|
107
|
+
|
|
108
|
+
// AUTO: flip the menu, render above
|
|
109
|
+
if (preferredPlacement === 'auto' || isFixedPosition) {
|
|
110
|
+
// may need to be constrained after flipping
|
|
111
|
+
let constrainedHeight = preferredMaxHeight;
|
|
112
|
+
const spaceAbove = isFixedPosition ? viewSpaceAbove : scrollSpaceAbove;
|
|
113
|
+
if (spaceAbove >= minHeight) {
|
|
114
|
+
constrainedHeight = Math.min(spaceAbove - marginBottom - controlHeight, preferredMaxHeight);
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
placement: 'top',
|
|
118
|
+
maxHeight: constrainedHeight
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// BOTTOM: allow browser to increase scrollable area and immediately set scroll
|
|
123
|
+
if (preferredPlacement === 'bottom') {
|
|
124
|
+
if (shouldScroll) {
|
|
125
|
+
scrollTo(scrollParent, scrollDown);
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
placement: 'bottom',
|
|
129
|
+
maxHeight: preferredMaxHeight
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
case 'top':
|
|
134
|
+
// 1: the menu will fit, do nothing
|
|
135
|
+
if (viewSpaceAbove >= menuHeight) {
|
|
136
|
+
return {
|
|
137
|
+
placement: 'top',
|
|
138
|
+
maxHeight: preferredMaxHeight
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// 2: the menu will fit, if scrolled
|
|
143
|
+
if (scrollSpaceAbove >= menuHeight && !isFixedPosition) {
|
|
144
|
+
if (shouldScroll) {
|
|
145
|
+
animatedScrollTo(scrollParent, scrollUp, scrollDuration);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
placement: 'top',
|
|
149
|
+
maxHeight: preferredMaxHeight
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 3: the menu will fit, if constrained
|
|
154
|
+
if (!isFixedPosition && scrollSpaceAbove >= minHeight || isFixedPosition && viewSpaceAbove >= minHeight) {
|
|
155
|
+
let constrainedHeight = preferredMaxHeight;
|
|
156
|
+
|
|
157
|
+
// we want to provide as much of the menu as possible to the user,
|
|
158
|
+
// so give them whatever is available below rather than the minHeight.
|
|
159
|
+
if (!isFixedPosition && scrollSpaceAbove >= minHeight || isFixedPosition && viewSpaceAbove >= minHeight) {
|
|
160
|
+
constrainedHeight = isFixedPosition ? viewSpaceAbove - marginTop : scrollSpaceAbove - marginTop;
|
|
161
|
+
}
|
|
162
|
+
if (shouldScroll) {
|
|
163
|
+
animatedScrollTo(scrollParent, scrollUp, scrollDuration);
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
placement: 'top',
|
|
167
|
+
maxHeight: constrainedHeight
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 4. not enough space, the browser WILL NOT increase scrollable area when
|
|
172
|
+
// absolutely positioned element rendered above the viewport (only below).
|
|
173
|
+
// Flip the menu, render below
|
|
174
|
+
return {
|
|
175
|
+
placement: 'bottom',
|
|
176
|
+
maxHeight: preferredMaxHeight
|
|
177
|
+
};
|
|
178
|
+
default:
|
|
179
|
+
throw new Error(`Invalid placement provided "${preferredPlacement}".`);
|
|
180
|
+
}
|
|
181
|
+
return defaultState;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Menu Component
|
|
185
|
+
// ------------------------------
|
|
186
|
+
|
|
187
|
+
const coercePlacement = p => p === 'auto' ? 'bottom' : p;
|
|
188
|
+
const menuStyles = {
|
|
189
|
+
root: "_2rkoglpi _jqf689mz _kqswstnw _1bsb1osq _1pbykb7n _otyru2gc _19pku2gc _bfhk1bhr _16qsd0yg",
|
|
190
|
+
bottom: "_154i1osq",
|
|
191
|
+
top: "_94n51osq"
|
|
192
|
+
};
|
|
193
|
+
export const menuCSS = () => ({});
|
|
194
|
+
const PortalPlacementContext = /*#__PURE__*/createContext(null);
|
|
195
|
+
|
|
196
|
+
// NOTE: internal only
|
|
197
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
198
|
+
export const MenuPlacer = props => {
|
|
199
|
+
const {
|
|
200
|
+
children,
|
|
201
|
+
minMenuHeight,
|
|
202
|
+
maxMenuHeight,
|
|
203
|
+
menuPlacement,
|
|
204
|
+
menuPosition,
|
|
205
|
+
menuShouldScrollIntoView
|
|
206
|
+
} = props;
|
|
207
|
+
const {
|
|
208
|
+
setPortalPlacement
|
|
209
|
+
} = useContext(PortalPlacementContext) || {};
|
|
210
|
+
const ref = useRef(null);
|
|
211
|
+
const [maxHeight, setMaxHeight] = useState(maxMenuHeight);
|
|
212
|
+
const [placement, setPlacement] = useState(null);
|
|
213
|
+
// The minimum height of the control
|
|
214
|
+
const controlHeight = 38;
|
|
215
|
+
useLayoutEffect(() => {
|
|
216
|
+
const menuEl = ref.current;
|
|
217
|
+
if (!menuEl) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// DO NOT scroll if position is fixed
|
|
222
|
+
const isFixedPosition = menuPosition === 'fixed';
|
|
223
|
+
const shouldScroll = menuShouldScrollIntoView && !isFixedPosition;
|
|
224
|
+
const state = getMenuPlacement({
|
|
225
|
+
maxHeight: maxMenuHeight,
|
|
226
|
+
menuEl,
|
|
227
|
+
minHeight: minMenuHeight,
|
|
228
|
+
placement: menuPlacement,
|
|
229
|
+
shouldScroll,
|
|
230
|
+
isFixedPosition,
|
|
231
|
+
controlHeight
|
|
232
|
+
});
|
|
233
|
+
setMaxHeight(state.maxHeight);
|
|
234
|
+
setPlacement(state.placement);
|
|
235
|
+
setPortalPlacement === null || setPortalPlacement === void 0 ? void 0 : setPortalPlacement(state.placement);
|
|
236
|
+
}, [maxMenuHeight, menuPlacement, menuPosition, menuShouldScrollIntoView, minMenuHeight, setPortalPlacement, controlHeight]);
|
|
237
|
+
return children({
|
|
238
|
+
ref,
|
|
239
|
+
placerProps: {
|
|
240
|
+
...props,
|
|
241
|
+
placement: placement || coercePlacement(menuPlacement),
|
|
242
|
+
maxHeight
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
const Menu = props => {
|
|
247
|
+
const {
|
|
248
|
+
children,
|
|
249
|
+
innerRef,
|
|
250
|
+
innerProps,
|
|
251
|
+
placement = 'bottom',
|
|
252
|
+
xcss
|
|
253
|
+
} = props;
|
|
254
|
+
const {
|
|
255
|
+
css,
|
|
256
|
+
className
|
|
257
|
+
} = getStyleProps(props, 'menu', {
|
|
258
|
+
menu: true
|
|
259
|
+
});
|
|
260
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
261
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/ui-styling-standard/local-cx-xcss, @compiled/local-cx-xcss
|
|
262
|
+
className: ax([menuStyles.root, menuStyles[placement], cx(xcss, className)])
|
|
263
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
264
|
+
,
|
|
265
|
+
style: css,
|
|
266
|
+
ref: innerRef
|
|
267
|
+
}, innerProps), children);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
271
|
+
export default Menu;
|
|
272
|
+
|
|
273
|
+
// ==============================
|
|
274
|
+
// Menu List
|
|
275
|
+
// ==============================
|
|
276
|
+
|
|
277
|
+
export const menuListCSS = () => ({});
|
|
278
|
+
const menuListStyles = null;
|
|
279
|
+
|
|
280
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
281
|
+
export const MenuList = props => {
|
|
282
|
+
const {
|
|
283
|
+
children,
|
|
284
|
+
innerProps,
|
|
285
|
+
innerRef,
|
|
286
|
+
isMulti,
|
|
287
|
+
maxHeight,
|
|
288
|
+
xcss
|
|
289
|
+
} = props;
|
|
290
|
+
const {
|
|
291
|
+
css,
|
|
292
|
+
className
|
|
293
|
+
} = getStyleProps(props, 'menuList', {
|
|
294
|
+
'menu-list': true,
|
|
295
|
+
'menu-list--is-multi': isMulti
|
|
296
|
+
});
|
|
297
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
298
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/ui-styling-standard/local-cx-xcss, @compiled/local-cx-xcss
|
|
299
|
+
className: ax(["_kqswh2mm _18m91wug _85i5u2gc _1q51u2gc _8am5i4x0", cx(className, xcss)])
|
|
300
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
301
|
+
,
|
|
302
|
+
style: {
|
|
303
|
+
...css,
|
|
304
|
+
maxHeight: maxHeight
|
|
305
|
+
},
|
|
306
|
+
ref: innerRef
|
|
307
|
+
}, innerProps, {
|
|
308
|
+
tabIndex: -1
|
|
309
|
+
}), children);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
// ==============================
|
|
313
|
+
// Menu Notices
|
|
314
|
+
// ==============================
|
|
315
|
+
|
|
316
|
+
const noticeCSS = () => ({});
|
|
317
|
+
const noticeStyles = null;
|
|
318
|
+
export const noOptionsMessageCSS = noticeCSS;
|
|
319
|
+
export const loadingMessageCSS = noticeCSS;
|
|
320
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
321
|
+
export const NoOptionsMessage = ({
|
|
322
|
+
children = 'No options',
|
|
323
|
+
innerProps,
|
|
324
|
+
xcss,
|
|
325
|
+
...restProps
|
|
326
|
+
}) => {
|
|
327
|
+
const {
|
|
328
|
+
css,
|
|
329
|
+
className
|
|
330
|
+
} = getStyleProps({
|
|
331
|
+
...restProps,
|
|
332
|
+
children,
|
|
333
|
+
innerProps
|
|
334
|
+
}, 'noOptionsMessage', {
|
|
335
|
+
'menu-notice': true,
|
|
336
|
+
'menu-notice--no-options': true
|
|
337
|
+
});
|
|
338
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
339
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/ui-styling-standard/local-cx-xcss, @compiled/local-cx-xcss
|
|
340
|
+
className: ax(["_85i5u2gc _1q51u2gc _y4tiutpp _bozgutpp _y3gn1h6o", cx(className, xcss)])
|
|
341
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
342
|
+
,
|
|
343
|
+
style: css
|
|
344
|
+
// eslint-disable-next-line jsx-a11y/role-has-required-aria-props
|
|
345
|
+
,
|
|
346
|
+
role: "option"
|
|
347
|
+
}, innerProps), /*#__PURE__*/React.createElement(Text, {
|
|
348
|
+
color: "color.text.subtle"
|
|
349
|
+
}, children));
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
353
|
+
export const LoadingMessage = ({
|
|
354
|
+
children = 'Loading...',
|
|
355
|
+
innerProps,
|
|
356
|
+
xcss,
|
|
357
|
+
...restProps
|
|
358
|
+
}) => {
|
|
359
|
+
const {
|
|
360
|
+
css,
|
|
361
|
+
className
|
|
362
|
+
} = getStyleProps({
|
|
363
|
+
...restProps,
|
|
364
|
+
children,
|
|
365
|
+
innerProps
|
|
366
|
+
}, 'loadingMessage', {
|
|
367
|
+
'menu-notice': true,
|
|
368
|
+
'menu-notice--loading': true
|
|
369
|
+
});
|
|
370
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
371
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/ui-styling-standard/local-cx-xcss, @compiled/local-cx-xcss
|
|
372
|
+
className: ax(["_85i5u2gc _1q51u2gc _y4tiutpp _bozgutpp _y3gn1h6o", cx(className, xcss)])
|
|
373
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
374
|
+
,
|
|
375
|
+
style: css
|
|
376
|
+
}, innerProps, {
|
|
377
|
+
// eslint-disable-next-line jsx-a11y/role-has-required-aria-props
|
|
378
|
+
role: "option"
|
|
379
|
+
}), /*#__PURE__*/React.createElement(Text, {
|
|
380
|
+
color: "color.text.subtle"
|
|
381
|
+
}, children));
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// ==============================
|
|
385
|
+
// Menu Portal
|
|
386
|
+
// ==============================
|
|
387
|
+
|
|
388
|
+
export const menuPortalCSS = () => ({});
|
|
389
|
+
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
390
|
+
export const MenuPortal = props => {
|
|
391
|
+
const {
|
|
392
|
+
appendTo,
|
|
393
|
+
children,
|
|
394
|
+
controlElement,
|
|
395
|
+
innerProps,
|
|
396
|
+
menuPlacement,
|
|
397
|
+
menuPosition,
|
|
398
|
+
xcss
|
|
399
|
+
} = props;
|
|
400
|
+
const menuPortalRef = useRef(null);
|
|
401
|
+
const cleanupRef = useRef(null);
|
|
402
|
+
const [placement, setPortalPlacement] = useState(coercePlacement(menuPlacement));
|
|
403
|
+
const portalPlacementContext = useMemo(() => ({
|
|
404
|
+
setPortalPlacement
|
|
405
|
+
}), []);
|
|
406
|
+
const [computedPosition, setComputedPosition] = useState(null);
|
|
407
|
+
const updateComputedPosition = useCallback(() => {
|
|
408
|
+
if (!controlElement) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const rect = getBoundingClientObj(controlElement);
|
|
412
|
+
const scrollDistance = menuPosition === 'fixed' ? 0 : window.pageYOffset;
|
|
413
|
+
const offset = rect[placement] + scrollDistance;
|
|
414
|
+
if (offset !== (computedPosition === null || computedPosition === void 0 ? void 0 : computedPosition.offset) || rect.left !== (computedPosition === null || computedPosition === void 0 ? void 0 : computedPosition.rect.left) || rect.width !== (computedPosition === null || computedPosition === void 0 ? void 0 : computedPosition.rect.width)) {
|
|
415
|
+
setComputedPosition({
|
|
416
|
+
offset,
|
|
417
|
+
rect
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}, [controlElement, menuPosition, placement, computedPosition === null || computedPosition === void 0 ? void 0 : computedPosition.offset, computedPosition === null || computedPosition === void 0 ? void 0 : computedPosition.rect.left, computedPosition === null || computedPosition === void 0 ? void 0 : computedPosition.rect.width]);
|
|
421
|
+
useLayoutEffect(() => {
|
|
422
|
+
updateComputedPosition();
|
|
423
|
+
}, [updateComputedPosition]);
|
|
424
|
+
const runAutoUpdate = useCallback(() => {
|
|
425
|
+
if (typeof cleanupRef.current === 'function') {
|
|
426
|
+
cleanupRef.current();
|
|
427
|
+
cleanupRef.current = null;
|
|
428
|
+
}
|
|
429
|
+
if (controlElement && menuPortalRef.current) {
|
|
430
|
+
cleanupRef.current = autoUpdate(controlElement, menuPortalRef.current, updateComputedPosition, {
|
|
431
|
+
elementResize: 'ResizeObserver' in window
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
}, [controlElement, updateComputedPosition]);
|
|
435
|
+
useLayoutEffect(() => {
|
|
436
|
+
runAutoUpdate();
|
|
437
|
+
}, [runAutoUpdate]);
|
|
438
|
+
const setMenuPortalElement = useCallback(menuPortalElement => {
|
|
439
|
+
menuPortalRef.current = menuPortalElement;
|
|
440
|
+
runAutoUpdate();
|
|
441
|
+
}, [runAutoUpdate]);
|
|
442
|
+
|
|
443
|
+
// bail early if required elements aren't present
|
|
444
|
+
if (!appendTo && menuPosition !== 'fixed' || !computedPosition) {
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
const {
|
|
448
|
+
css,
|
|
449
|
+
className
|
|
450
|
+
} = getStyleProps({
|
|
451
|
+
...props,
|
|
452
|
+
offset: computedPosition.offset,
|
|
453
|
+
position: menuPosition,
|
|
454
|
+
rect: computedPosition.rect
|
|
455
|
+
}, 'menuPortal', {
|
|
456
|
+
'menu-portal': true
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
// same wrapper element whether fixed or portalled
|
|
460
|
+
const menuWrapper = /*#__PURE__*/React.createElement("div", _extends({
|
|
461
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/ui-styling-standard/local-cx-xcss, @compiled/local-cx-xcss
|
|
462
|
+
className: cx(className, xcss),
|
|
463
|
+
ref: setMenuPortalElement,
|
|
464
|
+
style: {
|
|
465
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
466
|
+
zIndex: 9999,
|
|
467
|
+
left: computedPosition.rect.left,
|
|
468
|
+
position: menuPosition,
|
|
469
|
+
top: computedPosition.offset,
|
|
470
|
+
width: computedPosition.rect.width,
|
|
471
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
472
|
+
...css
|
|
473
|
+
}
|
|
474
|
+
}, innerProps), children);
|
|
475
|
+
return /*#__PURE__*/React.createElement(PortalPlacementContext.Provider, {
|
|
476
|
+
value: portalPlacementContext
|
|
477
|
+
}, appendTo ? /*#__PURE__*/createPortal(menuWrapper, appendTo) : menuWrapper);
|
|
478
|
+
};
|