@carbon/react 1.100.0-rc.0 → 1.101.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 +933 -933
- package/es/components/AILabel/index.d.ts +1 -1
- package/es/components/AILabel/index.js +1 -12
- package/es/components/Checkbox/Checkbox.js +5 -3
- package/es/components/CheckboxGroup/CheckboxGroup.js +4 -3
- package/es/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/es/components/ComboBox/ComboBox.d.ts +3 -4
- package/es/components/ComboBox/ComboBox.js +20 -18
- package/es/components/ComboButton/index.d.ts +1 -1
- package/es/components/ComboButton/index.js +3 -2
- package/es/components/ComposedModal/ComposedModal.js +17 -22
- package/es/components/ComposedModal/ModalHeader.d.ts +2 -2
- package/es/components/ComposedModal/ModalHeader.js +1 -1
- package/es/components/Copy/Copy.d.ts +1 -1
- package/es/components/CopyButton/CopyButton.d.ts +1 -1
- package/es/components/DataTable/DataTable.d.ts +2 -0
- package/es/components/DataTable/DataTable.js +6 -5
- package/es/components/DataTable/Table.d.ts +1 -1
- package/es/components/DataTable/Table.js +10 -4
- package/es/components/DataTable/state/sorting.d.ts +4 -2
- package/es/components/Dropdown/Dropdown.d.ts +3 -4
- package/es/components/Dropdown/Dropdown.js +16 -13
- package/es/components/FileUploader/FileUploaderItem.d.ts +1 -1
- package/es/components/FileUploader/FileUploaderItem.js +3 -2
- package/es/components/FluidComboBox/FluidComboBox.d.ts +2 -7
- package/es/components/FluidComboBox/FluidComboBox.js +1 -2
- package/es/components/FluidDropdown/FluidDropdown.d.ts +1 -6
- package/es/components/FluidDropdown/FluidDropdown.js +1 -2
- package/es/components/FluidMultiSelect/FluidMultiSelect.d.ts +1 -6
- package/es/components/FluidMultiSelect/FluidMultiSelect.js +1 -2
- package/es/components/InlineLoading/InlineLoading.js +5 -11
- package/es/components/Menu/Menu.js +8 -4
- package/es/components/Menu/MenuItem.d.ts +5 -1
- package/es/components/Menu/MenuItem.js +11 -1
- package/es/components/MenuButton/index.d.ts +1 -1
- package/es/components/MenuButton/index.js +3 -2
- package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +7 -5
- package/es/components/MultiSelect/MultiSelect.d.ts +3 -4
- package/es/components/MultiSelect/MultiSelect.js +10 -13
- package/es/components/Notification/Notification.js +5 -3
- package/es/components/NumberInput/NumberInput.d.ts +1 -1
- package/es/components/NumberInput/NumberInput.js +5 -4
- package/es/components/OverflowMenu/OverflowMenu.d.ts +1 -0
- package/es/components/OverflowMenu/OverflowMenu.js +8 -4
- package/es/components/PageHeader/PageHeader.d.ts +1 -1
- package/es/components/PageHeader/PageHeader.js +5 -5
- package/es/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
- package/es/components/Select/Select.js +2 -1
- package/es/components/StructuredList/StructuredList.d.ts +1 -1
- package/es/components/StructuredList/StructuredList.js +2 -4
- package/es/components/Tabs/Tabs.d.ts +2 -2
- package/es/components/Tabs/Tabs.js +20 -26
- package/es/components/Tag/DismissibleTag.js +3 -2
- package/es/components/Tag/OperationalTag.js +3 -2
- package/es/components/Tag/SelectableTag.js +3 -2
- package/es/components/Tag/Tag.js +3 -2
- package/es/components/TextArea/TextArea.d.ts +1 -1
- package/es/components/TextArea/TextArea.js +7 -8
- package/es/components/TextInput/ControlledPasswordInput.js +7 -6
- package/es/components/TextInput/PasswordInput.js +5 -6
- package/es/components/TextInput/TextInput.js +4 -4
- package/es/components/Tile/Tile.d.ts +1 -1
- package/es/components/Tile/Tile.js +37 -69
- package/es/components/TimePicker/TimePicker.js +2 -2
- package/es/components/Tooltip/DefinitionTooltip.d.ts +1 -1
- package/es/components/Tooltip/DefinitionTooltip.js +3 -2
- package/es/components/UIShell/SideNav.d.ts +0 -1
- package/es/components/UIShell/SideNav.js +12 -3
- package/es/internal/useId.js +3 -4
- package/es/internal/usePresence.js +3 -2
- package/es/internal/useResizeObserver.d.ts +1 -1
- package/es/internal/useResizeObserver.js +5 -7
- package/es/tools/events.d.ts +1 -1
- package/lib/components/AILabel/index.d.ts +1 -1
- package/lib/components/AILabel/index.js +1 -12
- package/lib/components/Checkbox/Checkbox.js +5 -3
- package/lib/components/CheckboxGroup/CheckboxGroup.js +4 -3
- package/lib/components/CodeSnippet/CodeSnippet.d.ts +1 -1
- package/lib/components/ComboBox/ComboBox.d.ts +3 -4
- package/lib/components/ComboBox/ComboBox.js +20 -18
- package/lib/components/ComboButton/index.d.ts +1 -1
- package/lib/components/ComboButton/index.js +2 -1
- package/lib/components/ComposedModal/ComposedModal.js +16 -21
- package/lib/components/ComposedModal/ModalHeader.d.ts +2 -2
- package/lib/components/ComposedModal/ModalHeader.js +1 -1
- package/lib/components/Copy/Copy.d.ts +1 -1
- package/lib/components/CopyButton/CopyButton.d.ts +1 -1
- package/lib/components/DataTable/DataTable.d.ts +2 -0
- package/lib/components/DataTable/DataTable.js +6 -5
- package/lib/components/DataTable/Table.d.ts +1 -1
- package/lib/components/DataTable/Table.js +10 -4
- package/lib/components/DataTable/state/sorting.d.ts +4 -2
- package/lib/components/Dropdown/Dropdown.d.ts +3 -4
- package/lib/components/Dropdown/Dropdown.js +16 -13
- package/lib/components/FileUploader/FileUploaderItem.d.ts +1 -1
- package/lib/components/FileUploader/FileUploaderItem.js +2 -1
- package/lib/components/FluidComboBox/FluidComboBox.d.ts +2 -7
- package/lib/components/FluidComboBox/FluidComboBox.js +1 -2
- package/lib/components/FluidDropdown/FluidDropdown.d.ts +1 -6
- package/lib/components/FluidDropdown/FluidDropdown.js +1 -2
- package/lib/components/FluidMultiSelect/FluidMultiSelect.d.ts +1 -6
- package/lib/components/FluidMultiSelect/FluidMultiSelect.js +1 -2
- package/lib/components/InlineLoading/InlineLoading.js +5 -11
- package/lib/components/Menu/Menu.js +7 -3
- package/lib/components/Menu/MenuItem.d.ts +5 -1
- package/lib/components/Menu/MenuItem.js +11 -1
- package/lib/components/MenuButton/index.d.ts +1 -1
- package/lib/components/MenuButton/index.js +2 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +6 -4
- package/lib/components/MultiSelect/MultiSelect.d.ts +3 -4
- package/lib/components/MultiSelect/MultiSelect.js +9 -12
- package/lib/components/Notification/Notification.js +5 -3
- package/lib/components/NumberInput/NumberInput.d.ts +1 -1
- package/lib/components/NumberInput/NumberInput.js +5 -4
- package/lib/components/OverflowMenu/OverflowMenu.d.ts +1 -0
- package/lib/components/OverflowMenu/OverflowMenu.js +7 -3
- package/lib/components/PageHeader/PageHeader.d.ts +1 -1
- package/lib/components/PageHeader/PageHeader.js +4 -4
- package/lib/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
- package/lib/components/Select/Select.js +2 -1
- package/lib/components/StructuredList/StructuredList.d.ts +1 -1
- package/lib/components/StructuredList/StructuredList.js +2 -4
- package/lib/components/Tabs/Tabs.d.ts +2 -2
- package/lib/components/Tabs/Tabs.js +15 -21
- package/lib/components/Tag/DismissibleTag.js +2 -1
- package/lib/components/Tag/OperationalTag.js +2 -1
- package/lib/components/Tag/SelectableTag.js +2 -1
- package/lib/components/Tag/Tag.js +2 -1
- package/lib/components/TextArea/TextArea.d.ts +1 -1
- package/lib/components/TextArea/TextArea.js +7 -8
- package/lib/components/TextInput/ControlledPasswordInput.js +7 -6
- package/lib/components/TextInput/PasswordInput.js +5 -6
- package/lib/components/TextInput/TextInput.js +4 -4
- package/lib/components/Tile/Tile.d.ts +1 -1
- package/lib/components/Tile/Tile.js +35 -67
- package/lib/components/TimePicker/TimePicker.js +2 -2
- package/lib/components/Tooltip/DefinitionTooltip.d.ts +1 -1
- package/lib/components/Tooltip/DefinitionTooltip.js +3 -2
- package/lib/components/UIShell/SideNav.d.ts +0 -1
- package/lib/components/UIShell/SideNav.js +11 -2
- package/lib/internal/useId.js +2 -3
- package/lib/internal/usePresence.js +2 -1
- package/lib/internal/useResizeObserver.d.ts +1 -1
- package/lib/internal/useResizeObserver.js +4 -6
- package/lib/tools/events.d.ts +1 -1
- package/package.json +8 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright IBM Corp. 2022,
|
|
2
|
+
* Copyright IBM Corp. 2022, 2026
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -43,11 +43,6 @@ export interface FluidDropdownProps<ItemType> extends DropdownProps<ItemType>, P
|
|
|
43
43
|
* Specify if the `FluidDropdown` should render its menu items in condensed mode
|
|
44
44
|
*/
|
|
45
45
|
isCondensed?: boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Function to render items as custom components instead of strings.
|
|
48
|
-
* Defaults to null and is overridden by a getter
|
|
49
|
-
*/
|
|
50
|
-
itemToElement?: React.JSXElementConstructor<ItemType> | null;
|
|
51
46
|
/**
|
|
52
47
|
* Helper function passed to downshift that allows the library to render a
|
|
53
48
|
* given item to a string label. By default, it extracts the `label` field
|
|
@@ -67,8 +67,7 @@ FluidDropdown.propTypes = {
|
|
|
67
67
|
*/
|
|
68
68
|
isCondensed: PropTypes.bool,
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
71
|
-
* Defaults to null and is overridden by a getter
|
|
70
|
+
* Renders an item as a custom React node instead of a string.
|
|
72
71
|
*/
|
|
73
72
|
itemToElement: PropTypes.func,
|
|
74
73
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright IBM Corp. 2022,
|
|
2
|
+
* Copyright IBM Corp. 2022, 2026
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -66,11 +66,6 @@ export interface FluidMultiSelectProps<ItemType> extends MultiSelectProps<ItemTy
|
|
|
66
66
|
* @deprecated This prop is deprecated in favor of new component called FluidFilterableMultiSelect and will be removed in the next major release
|
|
67
67
|
*/
|
|
68
68
|
isFilterable?: boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Function to render items as custom components instead of strings.
|
|
71
|
-
* Defaults to null and is overridden by a getter
|
|
72
|
-
*/
|
|
73
|
-
itemToElement?: React.JSXElementConstructor<ItemType>;
|
|
74
69
|
/**
|
|
75
70
|
* Helper function passed to downshift that allows the library to render a
|
|
76
71
|
* given item to a string label. By default, it extracts the `label` field
|
|
@@ -106,8 +106,7 @@ FluidMultiSelect.propTypes = {
|
|
|
106
106
|
*/
|
|
107
107
|
isFilterable: PropTypes.bool,
|
|
108
108
|
/**
|
|
109
|
-
*
|
|
110
|
-
* Defaults to null and is overridden by a getter
|
|
109
|
+
* Renders an item as a custom React node instead of a string.
|
|
111
110
|
*/
|
|
112
111
|
itemToElement: PropTypes.func,
|
|
113
112
|
/**
|
|
@@ -52,7 +52,10 @@ const InlineLoading = ({
|
|
|
52
52
|
className: `${prefix}--inline-loading__checkmark-container`
|
|
53
53
|
}, /*#__PURE__*/React.createElement("title", null, iconLabel));
|
|
54
54
|
}
|
|
55
|
-
if (status === 'active') {
|
|
55
|
+
if (status === 'inactive' || status === 'active') {
|
|
56
|
+
if (status === 'inactive') {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
56
59
|
if (!iconDescription) {
|
|
57
60
|
iconLabel = 'loading';
|
|
58
61
|
}
|
|
@@ -63,15 +66,6 @@ const InlineLoading = ({
|
|
|
63
66
|
active: status === 'active'
|
|
64
67
|
});
|
|
65
68
|
}
|
|
66
|
-
if (status === 'inactive') {
|
|
67
|
-
if (!iconDescription) {
|
|
68
|
-
iconLabel = 'not loading';
|
|
69
|
-
}
|
|
70
|
-
return /*#__PURE__*/React.createElement("title", {
|
|
71
|
-
className: `${prefix}--inline-loading__inactive-status`
|
|
72
|
-
}, iconLabel);
|
|
73
|
-
}
|
|
74
|
-
return undefined;
|
|
75
69
|
};
|
|
76
70
|
const loadingText = description && /*#__PURE__*/React.createElement("div", {
|
|
77
71
|
className: `${prefix}--inline-loading__text`
|
|
@@ -83,7 +77,7 @@ const InlineLoading = ({
|
|
|
83
77
|
return /*#__PURE__*/React.createElement("div", _extends({
|
|
84
78
|
className: loadingClasses
|
|
85
79
|
}, rest, {
|
|
86
|
-
"aria-live": rest['aria-live'] ?? 'assertive'
|
|
80
|
+
"aria-live": rest['aria-live'] ?? (status === 'inactive' ? 'off' : 'assertive')
|
|
87
81
|
}), loadingAnimation, loadingText);
|
|
88
82
|
};
|
|
89
83
|
InlineLoading.propTypes = {
|
|
@@ -10,7 +10,7 @@ import cx from 'classnames';
|
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
11
|
import React, { forwardRef, useRef, useContext, useReducer, useMemo, useState, useEffect } from 'react';
|
|
12
12
|
import { createPortal } from 'react-dom';
|
|
13
|
-
import { Escape, ArrowLeft, ArrowUp, ArrowDown } from '../../internal/keyboard/keys.js';
|
|
13
|
+
import { Escape, Tab, ArrowLeft, ArrowUp, ArrowDown } from '../../internal/keyboard/keys.js';
|
|
14
14
|
import { match } from '../../internal/keyboard/match.js';
|
|
15
15
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
16
16
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -48,6 +48,8 @@ const Menu = /*#__PURE__*/forwardRef(function Menu({
|
|
|
48
48
|
const [childState, childDispatch] = useReducer(menuReducer, {
|
|
49
49
|
...context.state,
|
|
50
50
|
isRoot: false,
|
|
51
|
+
hasIcons: false,
|
|
52
|
+
hasSelectableItems: false,
|
|
51
53
|
size,
|
|
52
54
|
requestCloseRoot: isRoot ? handleClose : context.state.requestCloseRoot
|
|
53
55
|
});
|
|
@@ -110,9 +112,9 @@ const Menu = /*#__PURE__*/forwardRef(function Menu({
|
|
|
110
112
|
function handleKeyDown(e) {
|
|
111
113
|
e.stopPropagation();
|
|
112
114
|
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
// If the user presses escape or tab, or this is a submenu and the user presses ArrowLeft, close it.
|
|
116
|
+
if ((match(e, Escape) || match(e, Tab) || !isRoot && match(e, ArrowLeft)) && onClose) {
|
|
117
|
+
e.preventDefault();
|
|
116
118
|
handleClose();
|
|
117
119
|
} else {
|
|
118
120
|
focusItem(e);
|
|
@@ -246,6 +248,8 @@ const Menu = /*#__PURE__*/forwardRef(function Menu({
|
|
|
246
248
|
}
|
|
247
249
|
return [fitValue(ranges.x, 'x') ?? -1, fitValue(ranges.y, 'y') ?? -1];
|
|
248
250
|
}
|
|
251
|
+
|
|
252
|
+
// When a menu is opened, focus the first item.
|
|
249
253
|
useEffect(() => {
|
|
250
254
|
if (open) {
|
|
251
255
|
const raf = requestAnimationFrame(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright IBM Corp. 2023,
|
|
2
|
+
* Copyright IBM Corp. 2023, 2026
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -14,6 +14,10 @@ export interface MenuItemProps extends LiHTMLAttributes<HTMLLIElement> {
|
|
|
14
14
|
* Additional CSS class names.
|
|
15
15
|
*/
|
|
16
16
|
className?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Specify the message read by screen readers for the danger menu item variant
|
|
19
|
+
*/
|
|
20
|
+
dangerDescription?: string;
|
|
17
21
|
/**
|
|
18
22
|
* Specify whether the MenuItem is disabled or not.
|
|
19
23
|
*/
|
|
@@ -16,6 +16,7 @@ import { match } from '../../internal/keyboard/match.js';
|
|
|
16
16
|
import { useControllableState } from '../../internal/useControllableState.js';
|
|
17
17
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
18
18
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
19
|
+
import { useId } from '../../internal/useId.js';
|
|
19
20
|
import { Menu } from './Menu.js';
|
|
20
21
|
import { MenuContext } from './MenuContext.js';
|
|
21
22
|
import '../LayoutDirection/LayoutDirection.js';
|
|
@@ -28,6 +29,7 @@ var _Checkmark, _CaretLeft, _CaretRight;
|
|
|
28
29
|
const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
|
|
29
30
|
children,
|
|
30
31
|
className,
|
|
32
|
+
dangerDescription = 'danger',
|
|
31
33
|
disabled,
|
|
32
34
|
kind = 'default',
|
|
33
35
|
label,
|
|
@@ -164,6 +166,7 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
|
|
|
164
166
|
}
|
|
165
167
|
});
|
|
166
168
|
}, [floatingStyles, refs.floating]);
|
|
169
|
+
const assistiveId = useId('danger-description');
|
|
167
170
|
return /*#__PURE__*/React.createElement(FloatingFocusManager, {
|
|
168
171
|
context: floatingContext,
|
|
169
172
|
order: ['reference', 'floating'],
|
|
@@ -188,7 +191,10 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
|
|
|
188
191
|
}, IconElement && /*#__PURE__*/React.createElement(IconElement, null)), /*#__PURE__*/React.createElement(Text, {
|
|
189
192
|
as: "div",
|
|
190
193
|
className: `${prefix}--menu-item__label`
|
|
191
|
-
}, label),
|
|
194
|
+
}, label), isDanger && /*#__PURE__*/React.createElement("span", {
|
|
195
|
+
id: assistiveId,
|
|
196
|
+
className: `${prefix}--visually-hidden`
|
|
197
|
+
}, dangerDescription), shortcut && !hasChildren && /*#__PURE__*/React.createElement("div", {
|
|
192
198
|
className: `${prefix}--menu-item__shortcut`
|
|
193
199
|
}, shortcut), hasChildren && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
194
200
|
className: `${prefix}--menu-item__shortcut`
|
|
@@ -211,6 +217,10 @@ MenuItem.propTypes = {
|
|
|
211
217
|
* Additional CSS class names.
|
|
212
218
|
*/
|
|
213
219
|
className: PropTypes.string,
|
|
220
|
+
/**
|
|
221
|
+
* Specify the message read by screen readers for the danger menu item variant
|
|
222
|
+
*/
|
|
223
|
+
dangerDescription: PropTypes.string,
|
|
214
224
|
/**
|
|
215
225
|
* Specify whether the MenuItem is disabled or not.
|
|
216
226
|
*/
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React, { forwardRef, useRef
|
|
9
|
+
import React, { forwardRef, useRef } from 'react';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { ChevronDown } from '@carbon/icons-react';
|
|
@@ -17,6 +17,7 @@ import '../Menu/MenuItem.js';
|
|
|
17
17
|
import { useAttachedMenu } from '../../internal/useAttachedMenu.js';
|
|
18
18
|
import { useId } from '../../internal/useId.js';
|
|
19
19
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
20
|
+
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
20
21
|
import { flip, size, useFloating, autoUpdate } from '@floating-ui/react';
|
|
21
22
|
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
22
23
|
import { mergeRefs } from '../../tools/mergeRefs.js';
|
|
@@ -95,7 +96,7 @@ const MenuButton = /*#__PURE__*/forwardRef(({
|
|
|
95
96
|
handleMousedown,
|
|
96
97
|
handleClose
|
|
97
98
|
} = useAttachedMenu(triggerRef);
|
|
98
|
-
|
|
99
|
+
useIsomorphicEffect(() => {
|
|
99
100
|
Object.keys(floatingStyles).forEach(style => {
|
|
100
101
|
if (refs.floating.current) {
|
|
101
102
|
let value = floatingStyles[style];
|
|
@@ -11,7 +11,7 @@ import cx from 'classnames';
|
|
|
11
11
|
import Downshift, { useCombobox, useMultipleSelection } from 'downshift';
|
|
12
12
|
import isEqual from 'react-fast-compare';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
|
-
import React, { forwardRef, useContext, useRef, useState, useMemo, useCallback,
|
|
14
|
+
import React, { forwardRef, useContext, useRef, useState, useMemo, useCallback, useEffect, cloneElement } from 'react';
|
|
15
15
|
import { defaultFilterItems } from './filter.js';
|
|
16
16
|
import { sortingPropTypes } from './MultiSelectPropTypes.js';
|
|
17
17
|
import ListBox from '../ListBox/index.js';
|
|
@@ -34,6 +34,7 @@ import { AILabel } from '../AILabel/index.js';
|
|
|
34
34
|
import { defaultItemToString } from '../../internal/defaultItemToString.js';
|
|
35
35
|
import { isComponentElement } from '../../internal/utils.js';
|
|
36
36
|
import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps.js';
|
|
37
|
+
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
37
38
|
import { ListBoxTypePropType, ListBoxSizePropType } from '../ListBox/ListBoxPropTypes.js';
|
|
38
39
|
|
|
39
40
|
const {
|
|
@@ -189,7 +190,7 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
189
190
|
}), hide()],
|
|
190
191
|
whileElementsMounted: autoUpdate
|
|
191
192
|
} : {});
|
|
192
|
-
|
|
193
|
+
useIsomorphicEffect(() => {
|
|
193
194
|
if (autoAlign) {
|
|
194
195
|
const updatedFloatingStyles = {
|
|
195
196
|
...floatingStyles,
|
|
@@ -259,7 +260,8 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
259
260
|
[`${prefix}--list-box__wrapper--decorator`]: decorator,
|
|
260
261
|
[`${prefix}--autoalign`]: autoAlign
|
|
261
262
|
});
|
|
262
|
-
const
|
|
263
|
+
const hasHelper = typeof helperText !== 'undefined' && helperText !== null;
|
|
264
|
+
const helperId = !hasHelper ? undefined : `filterablemultiselect-helper-text-${filterableMultiSelectInstanceId}`;
|
|
263
265
|
const labelId = `${id}-label`;
|
|
264
266
|
const titleClasses = cx({
|
|
265
267
|
[`${prefix}--label`]: true,
|
|
@@ -275,10 +277,10 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
275
277
|
[`${prefix}--text-input--empty`]: !inputValue,
|
|
276
278
|
[`${prefix}--text-input--light`]: light
|
|
277
279
|
});
|
|
278
|
-
const helper =
|
|
280
|
+
const helper = hasHelper && /*#__PURE__*/React.createElement("div", {
|
|
279
281
|
id: helperId,
|
|
280
282
|
className: helperClasses
|
|
281
|
-
}, helperText)
|
|
283
|
+
}, helperText);
|
|
282
284
|
const menuId = `${id}__menu`;
|
|
283
285
|
const inputId = `${id}-input`;
|
|
284
286
|
useEffect(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright IBM Corp. 2016,
|
|
2
|
+
* Copyright IBM Corp. 2016, 2026
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -82,10 +82,9 @@ export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<Item
|
|
|
82
82
|
*/
|
|
83
83
|
invalidText?: ReactNode;
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
86
|
-
* Defaults to null and is overridden by a getter
|
|
85
|
+
* Renders an item as a custom React node instead of a string.
|
|
87
86
|
*/
|
|
88
|
-
itemToElement?:
|
|
87
|
+
itemToElement?: ((item: ItemType) => NonNullable<ReactNode>) | null;
|
|
89
88
|
/**
|
|
90
89
|
* Helper function passed to downshift that allows the library to render a
|
|
91
90
|
* given item to a string label. By default, it extracts the `label` field
|
|
@@ -11,7 +11,7 @@ import cx from 'classnames';
|
|
|
11
11
|
import { useSelect } from 'downshift';
|
|
12
12
|
import isEqual from 'react-fast-compare';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
|
-
import React, { useMemo, useContext, useState,
|
|
14
|
+
import React, { useMemo, useContext, useState, useRef, isValidElement, useCallback, cloneElement } from 'react';
|
|
15
15
|
import ListBox from '../ListBox/index.js';
|
|
16
16
|
import { sortingPropTypes } from './MultiSelectPropTypes.js';
|
|
17
17
|
import { defaultSortItems, defaultCompareItems } from './tools/sorting.js';
|
|
@@ -33,6 +33,7 @@ import { AILabel } from '../AILabel/index.js';
|
|
|
33
33
|
import { defaultItemToString } from '../../internal/defaultItemToString.js';
|
|
34
34
|
import { isComponentElement } from '../../internal/utils.js';
|
|
35
35
|
import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps.js';
|
|
36
|
+
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
36
37
|
import { ListBoxTypePropType, ListBoxSizePropType } from '../ListBox/ListBoxPropTypes.js';
|
|
37
38
|
|
|
38
39
|
const {
|
|
@@ -143,7 +144,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
143
144
|
}), autoAlign && hide()],
|
|
144
145
|
whileElementsMounted: autoUpdate
|
|
145
146
|
} : {});
|
|
146
|
-
|
|
147
|
+
useIsomorphicEffect(() => {
|
|
147
148
|
if (enableFloatingStyles) {
|
|
148
149
|
const updatedFloatingStyles = {
|
|
149
150
|
...floatingStyles,
|
|
@@ -294,10 +295,6 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
294
295
|
[`${prefix}--autoalign`]: enableFloatingStyles,
|
|
295
296
|
[`${prefix}--multi-select--selectall`]: selectAll
|
|
296
297
|
});
|
|
297
|
-
|
|
298
|
-
// needs to be capitalized for react to render it correctly
|
|
299
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
300
|
-
const ItemToElement = itemToElement;
|
|
301
298
|
if (selectionFeedback === 'fixed') {
|
|
302
299
|
sortOptions.selectedItems = [];
|
|
303
300
|
} else if (selectionFeedback === 'top-after-reopen') {
|
|
@@ -390,8 +387,11 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
390
387
|
[`${prefix}--list-box__field--wrapper--input-focused`]: inputFocused
|
|
391
388
|
});
|
|
392
389
|
const handleFocus = evt => {
|
|
393
|
-
|
|
394
|
-
|
|
390
|
+
if (evt.target.classList.contains(`${prefix}--tag__close-icon`)) {
|
|
391
|
+
setIsFocused(false);
|
|
392
|
+
} else {
|
|
393
|
+
setIsFocused(evt.type === 'focus' ? true : false);
|
|
394
|
+
}
|
|
395
395
|
};
|
|
396
396
|
const readOnlyEventHandlers = readOnly ? {
|
|
397
397
|
onClick: evt => {
|
|
@@ -526,9 +526,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
526
526
|
className: `${prefix}--checkbox-wrapper`
|
|
527
527
|
}, /*#__PURE__*/React.createElement(Checkbox, {
|
|
528
528
|
id: `${itemProps.id}__checkbox`,
|
|
529
|
-
labelText: itemToElement ?
|
|
530
|
-
key: itemProps.id
|
|
531
|
-
}, item)) : itemText,
|
|
529
|
+
labelText: itemToElement ? itemToElement(item) : itemText,
|
|
532
530
|
checked: isChecked,
|
|
533
531
|
title: useTitleInItem ? itemText : undefined,
|
|
534
532
|
indeterminate: isIndeterminate,
|
|
@@ -619,8 +617,7 @@ MultiSelect.propTypes = {
|
|
|
619
617
|
*/
|
|
620
618
|
invalidText: PropTypes.node,
|
|
621
619
|
/**
|
|
622
|
-
*
|
|
623
|
-
* Defaults to null and is overridden by a getter
|
|
620
|
+
* Renders an item as a custom React node instead of a string.
|
|
624
621
|
*/
|
|
625
622
|
itemToElement: PropTypes.func,
|
|
626
623
|
/**
|
|
@@ -572,6 +572,9 @@ function ActionableNotification({
|
|
|
572
572
|
role: "link",
|
|
573
573
|
className: `${prefix}--visually-hidden`
|
|
574
574
|
}, "Focus sentinel"), /*#__PURE__*/React.createElement("div", {
|
|
575
|
+
ref: innerModal,
|
|
576
|
+
className: `${prefix}--actionable-notification__focus-wrapper`
|
|
577
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
575
578
|
className: `${prefix}--actionable-notification__details`
|
|
576
579
|
}, /*#__PURE__*/React.createElement(NotificationIcon, {
|
|
577
580
|
notificationType: inline ? 'inline' : 'toast',
|
|
@@ -593,8 +596,7 @@ function ActionableNotification({
|
|
|
593
596
|
as: "div",
|
|
594
597
|
className: `${prefix}--actionable-notification__caption`
|
|
595
598
|
}, caption), children))), /*#__PURE__*/React.createElement("div", {
|
|
596
|
-
className: `${prefix}--actionable-notification__button-wrapper
|
|
597
|
-
ref: innerModal
|
|
599
|
+
className: `${prefix}--actionable-notification__button-wrapper`
|
|
598
600
|
}, actionButtonLabel && /*#__PURE__*/React.createElement(NotificationActionButton, {
|
|
599
601
|
onClick: onActionButtonClick,
|
|
600
602
|
inline: inline
|
|
@@ -602,7 +604,7 @@ function ActionableNotification({
|
|
|
602
604
|
"aria-label": deprecatedAriaLabel || ariaLabel,
|
|
603
605
|
notificationType: "actionable",
|
|
604
606
|
onClick: handleCloseButtonClick
|
|
605
|
-
})), !focusTrapWithoutSentinels && /*#__PURE__*/React.createElement("span", {
|
|
607
|
+
}))), !focusTrapWithoutSentinels && /*#__PURE__*/React.createElement("span", {
|
|
606
608
|
ref: endTrap,
|
|
607
609
|
tabIndex: 0,
|
|
608
610
|
role: "link",
|
|
@@ -564,10 +564,11 @@ const NumberInput = /*#__PURE__*/React.forwardRef((props, forwardRef) => {
|
|
|
564
564
|
onKeyUp: onKeyUp,
|
|
565
565
|
onKeyDown: e => {
|
|
566
566
|
if (type === 'text') {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
567
|
+
if (match(e, ArrowUp)) {
|
|
568
|
+
handleStep(e, 'up');
|
|
569
|
+
} else if (match(e, ArrowDown)) {
|
|
570
|
+
handleStep(e, 'down');
|
|
571
|
+
}
|
|
571
572
|
}
|
|
572
573
|
if (rest?.onKeyDown) {
|
|
573
574
|
rest?.onKeyDown(e);
|
|
@@ -44,6 +44,7 @@ export interface OverflowMenuProps extends Omit<IconButtonProps, 'type' | 'aria-
|
|
|
44
44
|
*/
|
|
45
45
|
flipped?: boolean;
|
|
46
46
|
/**
|
|
47
|
+
* @deprecated Tab key is handled with event handler so no need for focus trap.
|
|
47
48
|
* Enable or disable focus trap behavior
|
|
48
49
|
*/
|
|
49
50
|
focusTrap?: boolean;
|
|
@@ -12,7 +12,7 @@ import cx from 'classnames';
|
|
|
12
12
|
import invariant from 'invariant';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
14
|
import { DIRECTION_TOP, DIRECTION_BOTTOM, FloatingMenu } from '../../internal/FloatingMenu.js';
|
|
15
|
-
import { ArrowUp, ArrowRight, ArrowDown, ArrowLeft, Escape } from '../../internal/keyboard/keys.js';
|
|
15
|
+
import { ArrowUp, ArrowRight, ArrowDown, ArrowLeft, Escape, Tab } from '../../internal/keyboard/keys.js';
|
|
16
16
|
import { matches } from '../../internal/keyboard/match.js';
|
|
17
17
|
import { noopFn } from '../../internal/noopFn.js';
|
|
18
18
|
import { PrefixContext } from '../../internal/usePrefix.js';
|
|
@@ -97,7 +97,7 @@ const OverflowMenu = /*#__PURE__*/forwardRef(({
|
|
|
97
97
|
className,
|
|
98
98
|
direction = DIRECTION_BOTTOM,
|
|
99
99
|
flipped = false,
|
|
100
|
-
focusTrap =
|
|
100
|
+
focusTrap = false,
|
|
101
101
|
iconClass,
|
|
102
102
|
iconDescription = 'Options',
|
|
103
103
|
id,
|
|
@@ -200,12 +200,15 @@ const OverflowMenu = /*#__PURE__*/forwardRef(({
|
|
|
200
200
|
evt.preventDefault();
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
// Close the overflow menu on escape
|
|
204
|
-
if (matches(evt, [Escape])) {
|
|
203
|
+
// Close the overflow menu on escape or tab.
|
|
204
|
+
if (matches(evt, [Escape, Tab])) {
|
|
205
205
|
closeMenuOnEscape();
|
|
206
206
|
|
|
207
207
|
// Stop the esc keypress from bubbling out and closing something it shouldn't
|
|
208
208
|
evt.stopPropagation();
|
|
209
|
+
|
|
210
|
+
// Stop the tab key from making the browser focus somewhere else.
|
|
211
|
+
evt.preventDefault();
|
|
209
212
|
}
|
|
210
213
|
};
|
|
211
214
|
|
|
@@ -390,6 +393,7 @@ OverflowMenu.propTypes = {
|
|
|
390
393
|
*/
|
|
391
394
|
flipped: PropTypes.bool,
|
|
392
395
|
/**
|
|
396
|
+
* @deprecated Tab key is handled with event handler so no need for focus trap.
|
|
393
397
|
* Enable or disable focus trap behavior
|
|
394
398
|
*/
|
|
395
399
|
focusTrap: PropTypes.bool,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React, { useRef, useState,
|
|
9
|
+
import React, { useRef, useState, useMemo, useEffect, useCallback } from 'react';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -35,6 +35,7 @@ import '../Grid/Row.js';
|
|
|
35
35
|
import Column from '../Grid/Column.js';
|
|
36
36
|
import '../Grid/ColumnHang.js';
|
|
37
37
|
import '../Grid/GridContext.js';
|
|
38
|
+
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* ----------
|
|
@@ -130,9 +131,8 @@ const PageHeaderContent = /*#__PURE__*/React.forwardRef(({
|
|
|
130
131
|
setIsEllipsisApplied(element.offsetHeight < element.scrollHeight);
|
|
131
132
|
return element.offsetHeight < element.scrollHeight;
|
|
132
133
|
};
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
titleRef.current && isEllipsisActive(titleRef.current);
|
|
134
|
+
useIsomorphicEffect(() => {
|
|
135
|
+
if (titleRef.current) isEllipsisActive(titleRef.current);
|
|
136
136
|
}, [title]);
|
|
137
137
|
return /*#__PURE__*/React.createElement("div", _extends({
|
|
138
138
|
className: classNames,
|
|
@@ -220,7 +220,7 @@ const PageHeaderContentPageActions = ({
|
|
|
220
220
|
|
|
221
221
|
// need to set the grid columns width based on the menu button's width
|
|
222
222
|
// to avoid overlapping when resizing
|
|
223
|
-
|
|
223
|
+
useIsomorphicEffect(() => {
|
|
224
224
|
if (menuButtonVisibility && offsetRef.current) {
|
|
225
225
|
const width = offsetRef.current.offsetWidth;
|
|
226
226
|
document.documentElement.style.setProperty('--pageheader-title-grid-width', `${width}px`);
|
|
@@ -97,11 +97,12 @@ const RadioButtonGroup = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
97
97
|
const helperClasses = cx(`${prefix}--form__helper-text`, {
|
|
98
98
|
[`${prefix}--form__helper-text--disabled`]: disabled
|
|
99
99
|
});
|
|
100
|
-
const
|
|
101
|
-
const
|
|
100
|
+
const hasHelper = typeof helperText !== 'undefined' && helperText !== null;
|
|
101
|
+
const helperId = !hasHelper ? undefined : `radio-button-group-helper-text-${radioButtonGroupInstanceId}`;
|
|
102
|
+
const helper = hasHelper && /*#__PURE__*/React.createElement("div", {
|
|
102
103
|
id: helperId,
|
|
103
104
|
className: helperClasses
|
|
104
|
-
}, helperText)
|
|
105
|
+
}, helperText);
|
|
105
106
|
const divRef = useRef(null);
|
|
106
107
|
|
|
107
108
|
// AILabel is always size `mini`
|
|
@@ -94,7 +94,8 @@ const Select = /*#__PURE__*/forwardRef(({
|
|
|
94
94
|
const helperTextClasses = cx(`${prefix}--form__helper-text`, {
|
|
95
95
|
[`${prefix}--form__helper-text--disabled`]: normalizedProps.disabled
|
|
96
96
|
});
|
|
97
|
-
const
|
|
97
|
+
const hasHelper = typeof helperText !== 'undefined' && helperText !== null;
|
|
98
|
+
const helper = hasHelper ? /*#__PURE__*/React.createElement(Text, {
|
|
98
99
|
as: "div",
|
|
99
100
|
id: normalizedProps.helperId,
|
|
100
101
|
className: helperTextClasses
|
|
@@ -184,8 +184,7 @@ function StructuredListRow(props) {
|
|
|
184
184
|
ref: itemRef,
|
|
185
185
|
onClick: event => {
|
|
186
186
|
setSelectedRow?.(rowId);
|
|
187
|
-
|
|
188
|
-
onClick && onClick(event);
|
|
187
|
+
onClick?.(event);
|
|
189
188
|
if (selection) {
|
|
190
189
|
// focus items only when selection is enabled
|
|
191
190
|
setHasFocusWithin(true);
|
|
@@ -264,8 +263,7 @@ function StructuredListInput(props) {
|
|
|
264
263
|
value: row?.id ?? '',
|
|
265
264
|
onChange: event => {
|
|
266
265
|
setSelectedRow?.(event.target.value);
|
|
267
|
-
|
|
268
|
-
onChange && onChange(event);
|
|
266
|
+
onChange?.(event);
|
|
269
267
|
},
|
|
270
268
|
id: id ?? defaultId,
|
|
271
269
|
className: classes,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright IBM Corp. 2016,
|
|
2
|
+
* Copyright IBM Corp. 2016, 2026
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import React, { type
|
|
8
|
+
import React, { type ComponentType, type HTMLAttributes, type HTMLElementType, type KeyboardEvent, type MouseEvent, type ReactNode } from 'react';
|
|
9
9
|
type DivAttributes = HTMLAttributes<HTMLDivElement>;
|
|
10
10
|
/**
|
|
11
11
|
* Tabs
|