@carbon/react 1.77.0 → 1.78.0-rc.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/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +945 -858
- package/es/components/Accordion/AccordionItem.js +1 -1
- package/es/components/BadgeIndicator/index.d.ts +23 -0
- package/es/components/BadgeIndicator/index.js +45 -0
- package/es/components/Breadcrumb/Breadcrumb.d.ts +5 -0
- package/es/components/Breadcrumb/Breadcrumb.js +8 -2
- package/es/components/Button/Button.d.ts +9 -0
- package/es/components/Button/Button.js +13 -0
- package/es/components/ComboBox/ComboBox.js +13 -9
- package/es/components/Dropdown/Dropdown.d.ts +1 -1
- package/es/components/Dropdown/Dropdown.js +3 -2
- package/es/components/FileUploader/FileUploader.js +1 -1
- package/es/components/FileUploader/FileUploaderItem.js +1 -1
- package/es/components/IconButton/index.d.ts +7 -1
- package/es/components/IconButton/index.js +18 -2
- package/es/components/IconIndicator/index.d.ts +1 -1
- package/es/components/InlineLoading/InlineLoading.js +2 -5
- package/es/components/Menu/MenuItem.js +1 -1
- package/es/components/Modal/Modal.d.ts +3 -3
- package/es/components/Modal/Modal.js +9 -3
- package/es/components/Modal/next/index.d.ts +1 -5
- package/es/components/MultiSelect/MultiSelect.js +3 -2
- package/es/components/MultiSelect/MultiSelectPropTypes.d.ts +5 -2
- package/es/components/MultiSelect/tools/sorting.js +8 -7
- package/es/components/Notification/Notification.js +1 -1
- package/es/components/NumberInput/NumberInput.js +12 -12
- package/es/components/OverflowMenu/OverflowMenu.d.ts +8 -20
- package/es/components/OverflowMenu/OverflowMenu.js +7 -9
- package/es/components/OverflowMenuItem/OverflowMenuItem.js +1 -1
- package/es/components/ProgressIndicator/ProgressIndicator.js +1 -1
- package/es/components/RadioTile/RadioTile.js +1 -1
- package/es/components/Select/Select.js +11 -2
- package/es/components/ShapeIndicator/index.d.ts +29 -0
- package/es/components/ShapeIndicator/index.js +92 -0
- package/es/components/Tabs/Tabs.d.ts +6 -4
- package/es/components/Tabs/Tabs.js +27 -8
- package/es/components/Tag/OperationalTag.d.ts +1 -36
- package/es/components/Tag/OperationalTag.js +7 -5
- package/es/components/Text/Text.d.ts +11 -9
- package/es/components/Text/Text.js +6 -6
- package/es/components/Text/TextDirection.d.ts +7 -9
- package/es/components/Text/TextDirection.js +5 -2
- package/es/components/Text/TextDirectionContext.d.ts +14 -0
- package/es/components/Text/TextDirectionContext.js +6 -2
- package/es/components/Text/createTextComponent.d.ts +5 -5
- package/es/components/Text/createTextComponent.js +5 -4
- package/es/components/Text/index.d.ts +6 -7
- package/es/components/Text/index.js +3 -2
- package/es/components/Tile/Tile.d.ts +6 -0
- package/es/components/Tile/Tile.js +5 -9
- package/es/components/Toggletip/index.d.ts +3 -2
- package/es/components/Tooltip/DefinitionTooltip.d.ts +4 -0
- package/es/components/Tooltip/DefinitionTooltip.js +7 -1
- package/es/components/Tooltip/Tooltip.d.ts +5 -66
- package/es/components/Tooltip/Tooltip.js +26 -26
- package/es/components/UIShell/HeaderGlobalAction.d.ts +9 -0
- package/es/components/UIShell/HeaderGlobalAction.js +16 -1
- package/es/index.d.ts +4 -1
- package/es/index.js +2 -1
- package/es/internal/FloatingMenu.d.ts +83 -0
- package/es/internal/FloatingMenu.js +216 -408
- package/es/internal/wrapFocus.js +1 -1
- package/lib/components/Accordion/AccordionItem.js +1 -1
- package/lib/components/BadgeIndicator/index.d.ts +23 -0
- package/lib/components/BadgeIndicator/index.js +56 -0
- package/lib/components/Breadcrumb/Breadcrumb.d.ts +5 -0
- package/lib/components/Breadcrumb/Breadcrumb.js +8 -2
- package/lib/components/Button/Button.d.ts +9 -0
- package/lib/components/Button/Button.js +13 -0
- package/lib/components/ComboBox/ComboBox.js +13 -9
- package/lib/components/Dropdown/Dropdown.d.ts +1 -1
- package/lib/components/Dropdown/Dropdown.js +2 -1
- package/lib/components/FileUploader/FileUploader.js +1 -1
- package/lib/components/FileUploader/FileUploaderItem.js +1 -1
- package/lib/components/IconButton/index.d.ts +7 -1
- package/lib/components/IconButton/index.js +18 -2
- package/lib/components/IconIndicator/index.d.ts +1 -1
- package/lib/components/InlineLoading/InlineLoading.js +2 -5
- package/lib/components/Menu/MenuItem.js +1 -1
- package/lib/components/Modal/Modal.d.ts +3 -3
- package/lib/components/Modal/Modal.js +9 -3
- package/lib/components/Modal/next/index.d.ts +1 -5
- package/lib/components/MultiSelect/MultiSelect.js +2 -1
- package/lib/components/MultiSelect/MultiSelectPropTypes.d.ts +5 -2
- package/lib/components/MultiSelect/tools/sorting.js +8 -7
- package/lib/components/Notification/Notification.js +1 -1
- package/lib/components/NumberInput/NumberInput.js +12 -12
- package/lib/components/OverflowMenu/OverflowMenu.d.ts +8 -20
- package/lib/components/OverflowMenu/OverflowMenu.js +7 -9
- package/lib/components/OverflowMenuItem/OverflowMenuItem.js +1 -1
- package/lib/components/ProgressIndicator/ProgressIndicator.js +1 -1
- package/lib/components/RadioTile/RadioTile.js +1 -1
- package/lib/components/Select/Select.js +11 -2
- package/lib/components/ShapeIndicator/index.d.ts +29 -0
- package/lib/components/ShapeIndicator/index.js +104 -0
- package/lib/components/Tabs/Tabs.d.ts +6 -4
- package/lib/components/Tabs/Tabs.js +42 -23
- package/lib/components/Tag/OperationalTag.d.ts +1 -36
- package/lib/components/Tag/OperationalTag.js +6 -4
- package/lib/components/Text/Text.d.ts +11 -9
- package/lib/components/Text/Text.js +5 -5
- package/lib/components/Text/TextDirection.d.ts +7 -9
- package/lib/components/Text/TextDirection.js +5 -2
- package/lib/components/Text/TextDirectionContext.d.ts +14 -0
- package/lib/components/Text/TextDirectionContext.js +6 -2
- package/lib/components/Text/createTextComponent.d.ts +5 -5
- package/lib/components/Text/createTextComponent.js +5 -4
- package/lib/components/Text/index.d.ts +6 -7
- package/lib/components/Text/index.js +4 -3
- package/lib/components/Tile/Tile.d.ts +6 -0
- package/lib/components/Tile/Tile.js +5 -9
- package/lib/components/Toggletip/index.d.ts +3 -2
- package/lib/components/Tooltip/DefinitionTooltip.d.ts +4 -0
- package/lib/components/Tooltip/DefinitionTooltip.js +7 -1
- package/lib/components/Tooltip/Tooltip.d.ts +5 -66
- package/lib/components/Tooltip/Tooltip.js +26 -26
- package/lib/components/UIShell/HeaderGlobalAction.d.ts +9 -0
- package/lib/components/UIShell/HeaderGlobalAction.js +16 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.js +42 -40
- package/lib/internal/FloatingMenu.d.ts +83 -0
- package/lib/internal/FloatingMenu.js +216 -409
- package/lib/internal/wrapFocus.js +1 -1
- package/package.json +5 -5
- package/scss/components/badge-indicator/_badge-indicator.scss +9 -0
- package/scss/components/badge-indicator/_index.scss +9 -0
|
@@ -9,17 +9,15 @@
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
11
11
|
|
|
12
|
-
var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
|
|
13
|
-
var PropTypes = require('prop-types');
|
|
14
12
|
var React = require('react');
|
|
13
|
+
var FeatureFlags = require('@carbon/feature-flags');
|
|
15
14
|
var ReactDOM = require('react-dom');
|
|
16
15
|
var window = require('window-or-global');
|
|
17
16
|
var OptimizedResize = require('./OptimizedResize.js');
|
|
18
17
|
var navigation = require('./keyboard/navigation.js');
|
|
18
|
+
var usePrefix = require('./usePrefix.js');
|
|
19
19
|
var warning = require('./warning.js');
|
|
20
20
|
var wrapFocus = require('./wrapFocus.js');
|
|
21
|
-
var usePrefix = require('./usePrefix.js');
|
|
22
|
-
var FeatureFlags = require('@carbon/feature-flags');
|
|
23
21
|
var match = require('./keyboard/match.js');
|
|
24
22
|
var keys = require('./keyboard/keys.js');
|
|
25
23
|
|
|
@@ -43,85 +41,27 @@ function _interopNamespace(e) {
|
|
|
43
41
|
return Object.freeze(n);
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
|
|
47
44
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
45
|
+
var FeatureFlags__namespace = /*#__PURE__*/_interopNamespace(FeatureFlags);
|
|
48
46
|
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
|
|
49
47
|
var window__default = /*#__PURE__*/_interopDefaultLegacy(window);
|
|
50
|
-
var FeatureFlags__namespace = /*#__PURE__*/_interopNamespace(FeatureFlags);
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* The structure for the position of floating menu.
|
|
54
|
-
* @typedef {object} FloatingMenu~position
|
|
55
|
-
* @property {number} left The left position.
|
|
56
|
-
* @property {number} top The top position.
|
|
57
|
-
* @property {number} right The right position.
|
|
58
|
-
* @property {number} bottom The bottom position.
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* The structure for the size of floating menu.
|
|
63
|
-
* @typedef {object} FloatingMenu~size
|
|
64
|
-
* @property {number} width The width.
|
|
65
|
-
* @property {number} height The height.
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* The structure for the position offset of floating menu.
|
|
70
|
-
* @typedef {object} FloatingMenu~offset
|
|
71
|
-
* @property {number} top The top position.
|
|
72
|
-
* @property {number} left The left position.
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* The structure for the target container.
|
|
77
|
-
* @typedef {object} FloatingMenu~container
|
|
78
|
-
* @property {DOMRect} rect Return of element.getBoundingClientRect()
|
|
79
|
-
* @property {string} position Position style (static, absolute, relative...)
|
|
80
|
-
*/
|
|
81
48
|
|
|
82
49
|
const DIRECTION_LEFT = 'left';
|
|
83
50
|
const DIRECTION_TOP = 'top';
|
|
84
51
|
const DIRECTION_RIGHT = 'right';
|
|
85
52
|
const DIRECTION_BOTTOM = 'bottom';
|
|
86
|
-
|
|
87
53
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* @returns `true` if the parent component wants to change in the adjustment of the floating menu position.
|
|
91
|
-
* @private
|
|
92
|
-
*/
|
|
93
|
-
const hasChangeInOffset = function () {
|
|
94
|
-
let oldMenuOffset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
95
|
-
let menuOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
96
|
-
if (typeof oldMenuOffset !== typeof menuOffset) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
if (Object(menuOffset) === menuOffset && typeof menuOffset !== 'function') {
|
|
100
|
-
return oldMenuOffset.top !== menuOffset.top || oldMenuOffset.left !== menuOffset.left;
|
|
101
|
-
}
|
|
102
|
-
return oldMenuOffset !== menuOffset;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @param {object} params The parameters.
|
|
107
|
-
* @param {FloatingMenu~size} params.menuSize The size of the menu.
|
|
108
|
-
* @param {FloatingMenu~position} params.refPosition The position of the triggering element.
|
|
109
|
-
* @param {FloatingMenu~offset} [params.offset={ left: 0, top: 0 }] The position offset of the menu.
|
|
110
|
-
* @param {string} [params.direction=bottom] The menu direction.
|
|
111
|
-
* @param {number} [params.scrollX=0] The scroll position of the viewport.
|
|
112
|
-
* @param {number} [params.scrollY=0] The scroll position of the viewport.
|
|
113
|
-
* @param {FloatingMenu~container} [params.container] The size and position type of target element.
|
|
114
|
-
* @returns {FloatingMenu~offset} The position of the menu, relative to the top-left corner of the viewport.
|
|
115
|
-
* @private
|
|
54
|
+
* Computes the floating menu's position based on the menu size, trigger element
|
|
55
|
+
* position, offset, direction, and container.
|
|
116
56
|
*/
|
|
117
57
|
const getFloatingPosition = _ref => {
|
|
118
58
|
let {
|
|
119
59
|
menuSize,
|
|
120
|
-
refPosition
|
|
121
|
-
offset
|
|
122
|
-
direction
|
|
123
|
-
scrollX
|
|
124
|
-
scrollY
|
|
60
|
+
refPosition,
|
|
61
|
+
offset,
|
|
62
|
+
direction,
|
|
63
|
+
scrollX,
|
|
64
|
+
scrollY,
|
|
125
65
|
container
|
|
126
66
|
} = _ref;
|
|
127
67
|
const {
|
|
@@ -130,8 +70,8 @@ const getFloatingPosition = _ref => {
|
|
|
130
70
|
right: refRight = 0,
|
|
131
71
|
bottom: refBottom = 0
|
|
132
72
|
} = refPosition;
|
|
133
|
-
const
|
|
134
|
-
const
|
|
73
|
+
const effectiveScrollX = container.position !== 'static' ? 0 : scrollX;
|
|
74
|
+
const effectiveScrollY = container.position !== 'static' ? 0 : scrollY;
|
|
135
75
|
const relativeDiff = {
|
|
136
76
|
top: container.position !== 'static' ? container.rect.top : 0,
|
|
137
77
|
left: container.position !== 'static' ? container.rect.left : 0
|
|
@@ -146,370 +86,237 @@ const getFloatingPosition = _ref => {
|
|
|
146
86
|
} = offset;
|
|
147
87
|
const refCenterHorizontal = (refLeft + refRight) / 2;
|
|
148
88
|
const refCenterVertical = (refTop + refBottom) / 2;
|
|
149
|
-
|
|
89
|
+
const positions = {
|
|
150
90
|
[DIRECTION_LEFT]: () => ({
|
|
151
|
-
left: refLeft - width +
|
|
152
|
-
top: refCenterVertical - height / 2 +
|
|
91
|
+
left: refLeft - width + effectiveScrollX - left - relativeDiff.left,
|
|
92
|
+
top: refCenterVertical - height / 2 + effectiveScrollY + top - 9 - relativeDiff.top
|
|
153
93
|
}),
|
|
154
94
|
[DIRECTION_TOP]: () => ({
|
|
155
|
-
left: refCenterHorizontal - width / 2 +
|
|
156
|
-
top: refTop - height +
|
|
95
|
+
left: refCenterHorizontal - width / 2 + effectiveScrollX + left - relativeDiff.left,
|
|
96
|
+
top: refTop - height + effectiveScrollY - top - relativeDiff.top
|
|
157
97
|
}),
|
|
158
98
|
[DIRECTION_RIGHT]: () => ({
|
|
159
|
-
left: refRight +
|
|
160
|
-
top: refCenterVertical - height / 2 +
|
|
99
|
+
left: refRight + effectiveScrollX + left - relativeDiff.left,
|
|
100
|
+
top: refCenterVertical - height / 2 + effectiveScrollY + top + 3 - relativeDiff.top
|
|
161
101
|
}),
|
|
162
102
|
[DIRECTION_BOTTOM]: () => ({
|
|
163
|
-
left: refCenterHorizontal - width / 2 +
|
|
164
|
-
top: refBottom +
|
|
103
|
+
left: refCenterHorizontal - width / 2 + effectiveScrollX + left - relativeDiff.left,
|
|
104
|
+
top: refBottom + effectiveScrollY + top - relativeDiff.top
|
|
165
105
|
})
|
|
166
|
-
}
|
|
106
|
+
};
|
|
107
|
+
return positions[direction]();
|
|
167
108
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
*/
|
|
193
|
-
_rollupPluginBabelHelpers.defineProperty(this, "_menuContainer", null);
|
|
194
|
-
/**
|
|
195
|
-
* The cached reference to the menu body.
|
|
196
|
-
* The reference is set via callback ref instead of object ref,
|
|
197
|
-
* in order to hook the event when the element ref gets available,
|
|
198
|
-
* which can be at a different timing from `cDM()`, presumably with SSR scenario.
|
|
199
|
-
* @type {Element}
|
|
200
|
-
* @private
|
|
201
|
-
*/
|
|
202
|
-
_rollupPluginBabelHelpers.defineProperty(this, "_menuBody", null);
|
|
203
|
-
/**
|
|
204
|
-
* Focus sentinel refs for focus trap behavior
|
|
205
|
-
*/
|
|
206
|
-
_rollupPluginBabelHelpers.defineProperty(this, "startSentinel", /*#__PURE__*/React__default["default"].createRef());
|
|
207
|
-
_rollupPluginBabelHelpers.defineProperty(this, "endSentinel", /*#__PURE__*/React__default["default"].createRef());
|
|
208
|
-
/**
|
|
209
|
-
* Calculates the position in the viewport of floating menu,
|
|
210
|
-
* once this component is mounted or updated upon change in the following props:
|
|
211
|
-
*
|
|
212
|
-
* * `menuOffset` (The adjustment that should be applied to the calculated floating menu's position)
|
|
213
|
-
* * `menuDirection` (Where the floating menu menu should be placed relative to the trigger button)
|
|
214
|
-
*
|
|
215
|
-
* @private
|
|
216
|
-
*/
|
|
217
|
-
_rollupPluginBabelHelpers.defineProperty(this, "_updateMenuSize", function () {
|
|
218
|
-
let prevProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
219
|
-
let isAdjustment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
220
|
-
const menuBody = _this._menuBody;
|
|
109
|
+
const FloatingMenu = _ref2 => {
|
|
110
|
+
let {
|
|
111
|
+
children,
|
|
112
|
+
flipped,
|
|
113
|
+
focusTrap,
|
|
114
|
+
menuDirection = DIRECTION_BOTTOM,
|
|
115
|
+
menuOffset = {},
|
|
116
|
+
menuRef: externalMenuRef,
|
|
117
|
+
onPlace,
|
|
118
|
+
selectorPrimaryFocus,
|
|
119
|
+
styles,
|
|
120
|
+
target = () => document.body,
|
|
121
|
+
triggerRef,
|
|
122
|
+
updateOrientation
|
|
123
|
+
} = _ref2;
|
|
124
|
+
const prefix = React.useContext(usePrefix.PrefixContext);
|
|
125
|
+
const [floatingPosition, setFloatingPosition] = React.useState(undefined);
|
|
126
|
+
const menuBodyRef = React.useRef(null);
|
|
127
|
+
const startSentinelRef = React.useRef(null);
|
|
128
|
+
const endSentinelRef = React.useRef(null);
|
|
129
|
+
const placeInProgressRef = React.useRef(false);
|
|
130
|
+
const updateMenuPosition = React.useCallback(isAdjustment => {
|
|
131
|
+
const menuBody = menuBodyRef.current;
|
|
132
|
+
if (!menuBody) {
|
|
221
133
|
process.env.NODE_ENV !== "production" ? warning.warning(menuBody, 'The DOM node for menu body for calculating its position is not available. Skipping...') : void 0;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const {
|
|
240
|
-
current: triggerEl
|
|
241
|
-
} = triggerRef;
|
|
242
|
-
const menuSize = menuBody.getBoundingClientRect();
|
|
243
|
-
const refPosition = triggerEl && triggerEl.getBoundingClientRect();
|
|
244
|
-
const offset = typeof menuOffset !== 'function' ? menuOffset : menuOffset(menuBody, menuDirection, triggerEl, flipped);
|
|
245
|
-
|
|
246
|
-
// Optional function to allow parent component to check
|
|
247
|
-
// if the orientation needs to be changed based on params
|
|
248
|
-
if (updateOrientation) {
|
|
249
|
-
updateOrientation({
|
|
250
|
-
menuSize,
|
|
251
|
-
refPosition,
|
|
252
|
-
direction: menuDirection,
|
|
253
|
-
offset,
|
|
254
|
-
scrollX: window__default["default"].pageXOffset,
|
|
255
|
-
scrollY: window__default["default"].pageYOffset,
|
|
256
|
-
container: {
|
|
257
|
-
rect: _this.props.target().getBoundingClientRect(),
|
|
258
|
-
position: getComputedStyle(_this.props.target()).position
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
// Skips if either in the following condition:
|
|
263
|
-
// a) Menu body has `display:none`
|
|
264
|
-
// b) `menuOffset` as a callback returns `undefined` (The callback saw that it couldn't calculate the value)
|
|
265
|
-
if (menuSize.width > 0 && menuSize.height > 0 || !offset) {
|
|
266
|
-
_this.setState({
|
|
267
|
-
floatingPosition: getFloatingPosition({
|
|
268
|
-
menuSize,
|
|
269
|
-
refPosition,
|
|
270
|
-
direction: menuDirection,
|
|
271
|
-
offset,
|
|
272
|
-
scrollX: window__default["default"].pageXOffset,
|
|
273
|
-
scrollY: window__default["default"].pageYOffset,
|
|
274
|
-
container: {
|
|
275
|
-
rect: _this.props.target().getBoundingClientRect(),
|
|
276
|
-
position: getComputedStyle(_this.props.target()).position
|
|
277
|
-
}
|
|
278
|
-
})
|
|
279
|
-
}, () => {
|
|
280
|
-
if (!isAdjustment) {
|
|
281
|
-
const newMenuSize = menuBody.getBoundingClientRect();
|
|
282
|
-
if (newMenuSize !== menuSize) {
|
|
283
|
-
_this._updateMenuSize(_this.props, true);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const triggerEl = triggerRef.current;
|
|
137
|
+
const menuSize = menuBody.getBoundingClientRect();
|
|
138
|
+
const refPosition = triggerEl ? triggerEl.getBoundingClientRect() : undefined;
|
|
139
|
+
const offsetValue = typeof menuOffset === 'function' ? menuOffset(menuBody, menuDirection, triggerEl, flipped) : menuOffset;
|
|
140
|
+
if (updateOrientation) {
|
|
141
|
+
updateOrientation({
|
|
142
|
+
menuSize,
|
|
143
|
+
refPosition,
|
|
144
|
+
direction: menuDirection,
|
|
145
|
+
offset: offsetValue,
|
|
146
|
+
scrollX: window__default["default"].pageXOffset,
|
|
147
|
+
scrollY: window__default["default"].pageYOffset,
|
|
148
|
+
container: {
|
|
149
|
+
rect: target().getBoundingClientRect(),
|
|
150
|
+
position: getComputedStyle(target()).position
|
|
287
151
|
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
process.env.NODE_ENV !== "production" ? warning.warning(focusableNode === null, 'Floating Menus must have at least a programmatically focusable child. ' + 'This can be accomplished by adding tabIndex="-1" to the content element.') : void 0;
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
/**
|
|
312
|
-
* A callback for called when menu body is mounted or unmounted.
|
|
313
|
-
* @param {Element} menuBody The menu body being mounted. `null` if the menu body is being unmounted.
|
|
314
|
-
*/
|
|
315
|
-
_rollupPluginBabelHelpers.defineProperty(this, "_menuRef", menuBody => {
|
|
316
|
-
const {
|
|
317
|
-
menuRef
|
|
318
|
-
} = this.props;
|
|
319
|
-
this._placeInProgress = !!menuBody;
|
|
320
|
-
menuRef && menuRef(this._menuBody = menuBody);
|
|
321
|
-
if (menuBody) {
|
|
322
|
-
this._updateMenuSize();
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
/**
|
|
326
|
-
* @returns The child nodes, with styles containing the floating menu position.
|
|
327
|
-
* @private
|
|
328
|
-
*/
|
|
329
|
-
_rollupPluginBabelHelpers.defineProperty(this, "_getChildrenWithProps", () => {
|
|
330
|
-
const {
|
|
331
|
-
styles,
|
|
332
|
-
children
|
|
333
|
-
} = this.props;
|
|
334
|
-
const {
|
|
335
|
-
floatingPosition: pos
|
|
336
|
-
} = this.state;
|
|
337
|
-
// If no pos available, we need to hide the element (offscreen to the left)
|
|
338
|
-
// This is done so we can measure the content before positioning it correctly.
|
|
339
|
-
const positioningStyle = pos ? {
|
|
340
|
-
left: `${pos.left}px`,
|
|
341
|
-
top: `${pos.top}px`,
|
|
342
|
-
right: 'auto'
|
|
343
|
-
} : {
|
|
344
|
-
visibility: 'hidden',
|
|
345
|
-
top: '0px'
|
|
346
|
-
};
|
|
347
|
-
return /*#__PURE__*/React__default["default"].cloneElement(children, {
|
|
348
|
-
ref: this._menuRef,
|
|
349
|
-
style: {
|
|
350
|
-
...styles,
|
|
351
|
-
...positioningStyle,
|
|
352
|
-
position: 'absolute',
|
|
353
|
-
opacity: 1
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Only set position if the menu has a valid size or if no offset is provided.
|
|
156
|
+
if (menuSize.width > 0 && menuSize.height > 0 || !offsetValue) {
|
|
157
|
+
const newFloatingPosition = getFloatingPosition({
|
|
158
|
+
menuSize,
|
|
159
|
+
refPosition: refPosition ?? {
|
|
160
|
+
left: 0,
|
|
161
|
+
top: 0,
|
|
162
|
+
right: 0,
|
|
163
|
+
bottom: 0
|
|
164
|
+
},
|
|
165
|
+
offset: offsetValue,
|
|
166
|
+
direction: menuDirection,
|
|
167
|
+
scrollX: window__default["default"].pageXOffset,
|
|
168
|
+
scrollY: window__default["default"].pageYOffset,
|
|
169
|
+
container: {
|
|
170
|
+
rect: target().getBoundingClientRect(),
|
|
171
|
+
position: getComputedStyle(target()).position
|
|
354
172
|
}
|
|
355
173
|
});
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
* @param {Element} event.target previously focused node
|
|
361
|
-
* @param {Element} event.relatedTarget current focused node
|
|
362
|
-
*/
|
|
363
|
-
_rollupPluginBabelHelpers.defineProperty(this, "handleBlur", _ref2 => {
|
|
364
|
-
let {
|
|
365
|
-
target: oldActiveNode,
|
|
366
|
-
relatedTarget: currentActiveNode
|
|
367
|
-
} = _ref2;
|
|
368
|
-
if (currentActiveNode && oldActiveNode) {
|
|
369
|
-
const {
|
|
370
|
-
current: startSentinelNode
|
|
371
|
-
} = this.startSentinel;
|
|
372
|
-
const {
|
|
373
|
-
current: endSentinelNode
|
|
374
|
-
} = this.endSentinel;
|
|
375
|
-
wrapFocus["default"]({
|
|
376
|
-
bodyNode: this._menuBody,
|
|
377
|
-
startSentinelNode,
|
|
378
|
-
endSentinelNode,
|
|
379
|
-
currentActiveNode,
|
|
380
|
-
oldActiveNode
|
|
381
|
-
});
|
|
174
|
+
|
|
175
|
+
// Only update if the position has actually changed.
|
|
176
|
+
if (!floatingPosition || floatingPosition.left !== newFloatingPosition.left || floatingPosition.top !== newFloatingPosition.top) {
|
|
177
|
+
setFloatingPosition(newFloatingPosition);
|
|
382
178
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
currentActiveNode: event.target,
|
|
393
|
-
event
|
|
394
|
-
});
|
|
179
|
+
|
|
180
|
+
// Re-check after setting the position if not already adjusting.
|
|
181
|
+
if (!isAdjustment) {
|
|
182
|
+
const newMenuSize = menuBody.getBoundingClientRect();
|
|
183
|
+
// TODO: Was there a bug in the old code? How could one `DOMRect` be
|
|
184
|
+
// compared to another using `!==`?
|
|
185
|
+
if (newMenuSize.width !== menuSize.width || newMenuSize.height !== menuSize.height) {
|
|
186
|
+
updateMenuPosition(true);
|
|
187
|
+
}
|
|
395
188
|
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
189
|
+
}
|
|
190
|
+
}, [triggerRef, menuOffset, menuDirection, flipped, target, updateOrientation, floatingPosition]);
|
|
191
|
+
const focusMenuContent = menuBody => {
|
|
192
|
+
const primaryFocusNode = selectorPrimaryFocus ? menuBody.querySelector(selectorPrimaryFocus) : null;
|
|
193
|
+
const tabbableNode = menuBody.querySelector(navigation.selectorTabbable);
|
|
194
|
+
const focusableNode = menuBody.querySelector(navigation.selectorFocusable);
|
|
195
|
+
const focusTarget = primaryFocusNode ||
|
|
196
|
+
// User defined focusable node
|
|
197
|
+
tabbableNode ||
|
|
198
|
+
// First sequentially focusable node
|
|
199
|
+
focusableNode ||
|
|
200
|
+
// First programmatic focusable node
|
|
201
|
+
menuBody;
|
|
202
|
+
focusTarget.focus();
|
|
203
|
+
if (focusTarget === menuBody && process.env.NODE_ENV !== "production") {
|
|
204
|
+
process.env.NODE_ENV !== "production" ? warning.warning(focusableNode === null, 'Floating Menus must have at least a programmatically focusable child. This can be accomplished by adding tabIndex="-1" to the content element.') : void 0;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
const handleMenuRef = node => {
|
|
208
|
+
menuBodyRef.current = node;
|
|
209
|
+
placeInProgressRef.current = !!node;
|
|
210
|
+
if (externalMenuRef) {
|
|
211
|
+
externalMenuRef(node);
|
|
212
|
+
}
|
|
213
|
+
if (node) {
|
|
214
|
+
updateMenuPosition();
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// When the menu has been placed, focus the content and call onPlace.
|
|
219
|
+
React.useEffect(() => {
|
|
220
|
+
if (placeInProgressRef.current && floatingPosition && menuBodyRef.current) {
|
|
221
|
+
if (!menuBodyRef.current.contains(document.activeElement)) {
|
|
222
|
+
focusMenuContent(menuBodyRef.current);
|
|
414
223
|
}
|
|
415
224
|
if (typeof onPlace === 'function') {
|
|
416
|
-
onPlace(
|
|
417
|
-
this._placeInProgress = false;
|
|
225
|
+
onPlace(menuBodyRef.current);
|
|
418
226
|
}
|
|
227
|
+
placeInProgressRef.current = false;
|
|
419
228
|
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}, !focusTrapWithoutSentinels && /*#__PURE__*/React__default["default"].createElement("span", {
|
|
438
|
-
ref: this.startSentinel,
|
|
439
|
-
tabIndex: "0",
|
|
440
|
-
role: "link",
|
|
441
|
-
className: `${prefix}--visually-hidden`
|
|
442
|
-
}, "Focus sentinel"), this._getChildrenWithProps(), !focusTrapWithoutSentinels && /*#__PURE__*/React__default["default"].createElement("span", {
|
|
443
|
-
ref: this.endSentinel,
|
|
444
|
-
tabIndex: "0",
|
|
445
|
-
role: "link",
|
|
446
|
-
className: `${prefix}--visually-hidden`
|
|
447
|
-
}, "Focus sentinel")), !target ? document.body : target());
|
|
448
|
-
}
|
|
449
|
-
return null;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
_rollupPluginBabelHelpers.defineProperty(FloatingMenu, "contextType", usePrefix.PrefixContext);
|
|
453
|
-
_rollupPluginBabelHelpers.defineProperty(FloatingMenu, "propTypes", {
|
|
454
|
-
/**
|
|
455
|
-
* Contents to put into the floating menu.
|
|
456
|
-
*/
|
|
457
|
-
children: PropTypes__default["default"].object,
|
|
458
|
-
/**
|
|
459
|
-
* `true` if the menu alignment should be flipped.
|
|
460
|
-
*/
|
|
461
|
-
flipped: PropTypes__default["default"].bool,
|
|
462
|
-
/**
|
|
463
|
-
* Enable or disable focus trap behavior
|
|
464
|
-
*/
|
|
465
|
-
focusTrap: PropTypes__default["default"].bool,
|
|
466
|
-
/**
|
|
467
|
-
* Where to put the tooltip, relative to the trigger button.
|
|
468
|
-
*/
|
|
469
|
-
menuDirection: PropTypes__default["default"].oneOf([DIRECTION_LEFT, DIRECTION_TOP, DIRECTION_RIGHT, DIRECTION_BOTTOM]),
|
|
470
|
-
/**
|
|
471
|
-
* The adjustment of the floating menu position, considering the position of dropdown arrow, etc.
|
|
472
|
-
*/
|
|
473
|
-
menuOffset: PropTypes__default["default"].oneOfType([PropTypes__default["default"].shape({
|
|
474
|
-
top: PropTypes__default["default"].number,
|
|
475
|
-
left: PropTypes__default["default"].number
|
|
476
|
-
}), PropTypes__default["default"].func]),
|
|
477
|
-
/**
|
|
478
|
-
* The callback called when the menu body has been mounted to/will be unmounted from the DOM.
|
|
479
|
-
*/
|
|
480
|
-
menuRef: PropTypes__default["default"].func,
|
|
481
|
-
/**
|
|
482
|
-
* The callback called when the menu body has been mounted and positioned.
|
|
483
|
-
*/
|
|
484
|
-
onPlace: PropTypes__default["default"].func,
|
|
485
|
-
/**
|
|
486
|
-
* Specify a CSS selector that matches the DOM element that should
|
|
487
|
-
* be focused when the Modal opens
|
|
488
|
-
*/
|
|
489
|
-
selectorPrimaryFocus: PropTypes__default["default"].string,
|
|
490
|
-
/**
|
|
491
|
-
* The additional styles to put to the floating menu.
|
|
492
|
-
*/
|
|
493
|
-
styles: PropTypes__default["default"].object,
|
|
229
|
+
}, [floatingPosition, onPlace]);
|
|
230
|
+
|
|
231
|
+
// Attach a resize listener.
|
|
232
|
+
React.useEffect(() => {
|
|
233
|
+
const resizeHandler = OptimizedResize["default"].add(() => {
|
|
234
|
+
updateMenuPosition();
|
|
235
|
+
});
|
|
236
|
+
return () => {
|
|
237
|
+
resizeHandler.release();
|
|
238
|
+
};
|
|
239
|
+
}, [triggerRef, menuOffset, menuDirection, flipped, target, updateOrientation]);
|
|
240
|
+
|
|
241
|
+
// Update menu position when key props change.
|
|
242
|
+
React.useEffect(() => {
|
|
243
|
+
updateMenuPosition();
|
|
244
|
+
}, [menuOffset, menuDirection, flipped, triggerRef, target, updateOrientation]);
|
|
245
|
+
|
|
494
246
|
/**
|
|
495
|
-
*
|
|
247
|
+
* Clones the child element to add a `ref` and positioning styles.
|
|
496
248
|
*/
|
|
497
|
-
|
|
249
|
+
const getChildrenWithProps = () => {
|
|
250
|
+
const pos = floatingPosition;
|
|
251
|
+
const positioningStyle = pos ? {
|
|
252
|
+
left: `${pos.left}px`,
|
|
253
|
+
top: `${pos.top}px`,
|
|
254
|
+
right: 'auto'
|
|
255
|
+
} : {
|
|
256
|
+
visibility: 'hidden',
|
|
257
|
+
top: '0px'
|
|
258
|
+
};
|
|
259
|
+
return /*#__PURE__*/React.cloneElement(children, {
|
|
260
|
+
ref: handleMenuRef,
|
|
261
|
+
style: {
|
|
262
|
+
...styles,
|
|
263
|
+
...positioningStyle,
|
|
264
|
+
position: 'absolute',
|
|
265
|
+
opacity: 1
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
|
|
498
270
|
/**
|
|
499
|
-
*
|
|
271
|
+
* Blur handler used when focus trapping is enabled.
|
|
500
272
|
*/
|
|
501
|
-
|
|
502
|
-
current
|
|
503
|
-
|
|
273
|
+
const handleBlur = event => {
|
|
274
|
+
if (menuBodyRef.current && startSentinelRef.current && endSentinelRef.current) {
|
|
275
|
+
wrapFocus["default"]({
|
|
276
|
+
bodyNode: menuBodyRef.current,
|
|
277
|
+
startTrapNode: startSentinelRef.current,
|
|
278
|
+
endTrapNode: endSentinelRef.current,
|
|
279
|
+
currentActiveNode: event.relatedTarget,
|
|
280
|
+
oldActiveNode: event.target
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
504
285
|
/**
|
|
505
|
-
*
|
|
286
|
+
* Keydown handler for focus wrapping when experimental focus trap is enabled.
|
|
506
287
|
*/
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
288
|
+
const handleKeyDown = event => {
|
|
289
|
+
if (match.match(event, keys.Tab) && menuBodyRef.current) {
|
|
290
|
+
wrapFocus.wrapFocusWithoutSentinels({
|
|
291
|
+
containerNode: menuBodyRef.current,
|
|
292
|
+
currentActiveNode: event.target,
|
|
293
|
+
event
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
const focusTrapWithoutSentinels = FeatureFlags__namespace.enabled('enable-experimental-focus-wrap-without-sentinels');
|
|
298
|
+
if (typeof document !== 'undefined') {
|
|
299
|
+
const portalTarget = target ? target() : document.body;
|
|
300
|
+
return /*#__PURE__*/ReactDOM__default["default"].createPortal(/*#__PURE__*/React__default["default"].createElement("div", {
|
|
301
|
+
onBlur: focusTrap && !focusTrapWithoutSentinels ? handleBlur : undefined,
|
|
302
|
+
onKeyDown: focusTrapWithoutSentinels ? handleKeyDown : undefined
|
|
303
|
+
}, !focusTrapWithoutSentinels && /*#__PURE__*/React__default["default"].createElement("span", {
|
|
304
|
+
ref: startSentinelRef,
|
|
305
|
+
tabIndex: 0,
|
|
306
|
+
role: "link",
|
|
307
|
+
className: `${prefix}--visually-hidden`
|
|
308
|
+
}, "Focus sentinel"), getChildrenWithProps(), !focusTrapWithoutSentinels && /*#__PURE__*/React__default["default"].createElement("span", {
|
|
309
|
+
ref: endSentinelRef,
|
|
310
|
+
tabIndex: 0,
|
|
311
|
+
role: "link",
|
|
312
|
+
className: `${prefix}--visually-hidden`
|
|
313
|
+
}, "Focus sentinel")), portalTarget);
|
|
314
|
+
}
|
|
315
|
+
return null;
|
|
316
|
+
};
|
|
510
317
|
|
|
511
318
|
exports.DIRECTION_BOTTOM = DIRECTION_BOTTOM;
|
|
512
319
|
exports.DIRECTION_LEFT = DIRECTION_LEFT;
|
|
513
320
|
exports.DIRECTION_RIGHT = DIRECTION_RIGHT;
|
|
514
321
|
exports.DIRECTION_TOP = DIRECTION_TOP;
|
|
515
|
-
exports
|
|
322
|
+
exports.FloatingMenu = FloatingMenu;
|