@carbon/react 1.100.0 → 1.101.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 +953 -953
- 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.js +25 -12
- 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.js +4 -4
- package/es/components/ExpandableSearch/ExpandableSearch.js +1 -1
- package/es/components/FileUploader/FileUploaderItem.d.ts +1 -1
- package/es/components/FileUploader/FileUploaderItem.js +3 -2
- package/es/components/ListBox/test-helpers.d.ts +71 -0
- 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 +8 -6
- package/es/components/MultiSelect/MultiSelect.js +8 -4
- package/es/components/Notification/Notification.js +2 -1
- package/es/components/NumberInput/NumberInput.d.ts +1 -1
- package/es/components/NumberInput/NumberInput.js +6 -5
- 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/Popover/index.js +1 -1
- package/es/components/ProgressIndicator/ProgressIndicator.d.ts +1 -1
- package/es/components/ProgressIndicator/ProgressIndicator.js +1 -1
- package/es/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
- package/es/components/Search/Search.d.ts +1 -1
- package/es/components/Search/Search.js +1 -1
- package/es/components/Select/Select.js +3 -2
- 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 +2 -2
- package/es/components/TextArea/TextArea.js +7 -6
- 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/TimePicker/TimePicker.js +2 -2
- package/es/components/Tooltip/DefinitionTooltip.d.ts +1 -1
- package/es/components/Tooltip/DefinitionTooltip.js +3 -2
- 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.js +25 -12
- 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.js +4 -4
- package/lib/components/ExpandableSearch/ExpandableSearch.js +1 -1
- package/lib/components/FileUploader/FileUploaderItem.d.ts +1 -1
- package/lib/components/FileUploader/FileUploaderItem.js +2 -1
- package/lib/components/ListBox/test-helpers.d.ts +71 -0
- 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 +7 -5
- package/lib/components/MultiSelect/MultiSelect.js +7 -3
- package/lib/components/Notification/Notification.js +2 -1
- package/lib/components/NumberInput/NumberInput.d.ts +1 -1
- package/lib/components/NumberInput/NumberInput.js +6 -5
- 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/Popover/index.js +1 -1
- package/lib/components/ProgressIndicator/ProgressIndicator.d.ts +1 -1
- package/lib/components/ProgressIndicator/ProgressIndicator.js +1 -1
- package/lib/components/RadioButtonGroup/RadioButtonGroup.js +4 -3
- package/lib/components/Search/Search.d.ts +1 -1
- package/lib/components/Search/Search.js +1 -1
- package/lib/components/Select/Select.js +3 -2
- 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 +2 -2
- package/lib/components/TextArea/TextArea.js +7 -6
- 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/TimePicker/TimePicker.js +2 -2
- package/lib/components/Tooltip/DefinitionTooltip.d.ts +1 -1
- package/lib/components/Tooltip/DefinitionTooltip.js +3 -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 +9 -9
|
@@ -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(() => {
|
|
@@ -620,7 +622,7 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
620
622
|
if (evt?.target.classList.contains(`${prefix}--tag__close-icon`) || evt?.target.classList.contains(`${prefix}--list-box__selection`)) {
|
|
621
623
|
setIsFocused(false);
|
|
622
624
|
} else {
|
|
623
|
-
setIsFocused(evt?.type === 'focus'
|
|
625
|
+
setIsFocused(evt?.type === 'focus');
|
|
624
626
|
}
|
|
625
627
|
};
|
|
626
628
|
const mergedRef = mergeRefs(textInput, inputProp.ref);
|
|
@@ -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,
|
|
@@ -386,8 +387,11 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
386
387
|
[`${prefix}--list-box__field--wrapper--input-focused`]: inputFocused
|
|
387
388
|
});
|
|
388
389
|
const handleFocus = evt => {
|
|
389
|
-
|
|
390
|
-
|
|
390
|
+
if (evt.target.classList.contains(`${prefix}--tag__close-icon`)) {
|
|
391
|
+
setIsFocused(false);
|
|
392
|
+
} else {
|
|
393
|
+
setIsFocused(evt.type === 'focus');
|
|
394
|
+
}
|
|
391
395
|
};
|
|
392
396
|
const readOnlyEventHandlers = readOnly ? {
|
|
393
397
|
onClick: evt => {
|
|
@@ -572,7 +572,8 @@ function ActionableNotification({
|
|
|
572
572
|
role: "link",
|
|
573
573
|
className: `${prefix}--visually-hidden`
|
|
574
574
|
}, "Focus sentinel"), /*#__PURE__*/React.createElement("div", {
|
|
575
|
-
ref: innerModal
|
|
575
|
+
ref: innerModal,
|
|
576
|
+
className: `${prefix}--actionable-notification__focus-wrapper`
|
|
576
577
|
}, /*#__PURE__*/React.createElement("div", {
|
|
577
578
|
className: `${prefix}--actionable-notification__details`
|
|
578
579
|
}, /*#__PURE__*/React.createElement(NotificationIcon, {
|
|
@@ -445,7 +445,7 @@ const NumberInput = /*#__PURE__*/React.forwardRef((props, forwardRef) => {
|
|
|
445
445
|
if ('type' in evt.target && evt.target.type === 'button') {
|
|
446
446
|
setIsFocused(false);
|
|
447
447
|
} else {
|
|
448
|
-
setIsFocused(evt.type === 'focus'
|
|
448
|
+
setIsFocused(evt.type === 'focus');
|
|
449
449
|
}
|
|
450
450
|
};
|
|
451
451
|
const outerElementClasses = cx(`${prefix}--form-item`, {
|
|
@@ -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`);
|
|
@@ -40,7 +40,7 @@ const Popover = /*#__PURE__*/React.forwardRef(function PopoverRenderFunction({
|
|
|
40
40
|
autoAlign = false,
|
|
41
41
|
autoAlignBoundary,
|
|
42
42
|
backgroundToken = 'layer',
|
|
43
|
-
caret = isTabTip
|
|
43
|
+
caret = !isTabTip,
|
|
44
44
|
className: customClassName,
|
|
45
45
|
children,
|
|
46
46
|
border = false,
|
|
@@ -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`
|
|
@@ -47,7 +47,7 @@ const Search = /*#__PURE__*/React.forwardRef(({
|
|
|
47
47
|
value,
|
|
48
48
|
...rest
|
|
49
49
|
}, forwardRef) => {
|
|
50
|
-
const hasPropValue = value || defaultValue
|
|
50
|
+
const hasPropValue = Boolean(value || defaultValue);
|
|
51
51
|
const prefix = usePrefix();
|
|
52
52
|
const {
|
|
53
53
|
isFluid
|
|
@@ -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
|
|
@@ -106,7 +107,7 @@ const Select = /*#__PURE__*/forwardRef(({
|
|
|
106
107
|
ariaProps['aria-describedby'] = helper ? normalizedProps.helperId : undefined;
|
|
107
108
|
}
|
|
108
109
|
const handleFocus = evt => {
|
|
109
|
-
setIsFocused(evt.type === 'focus'
|
|
110
|
+
setIsFocused(evt.type === 'focus');
|
|
110
111
|
};
|
|
111
112
|
const handleChange = evt => {
|
|
112
113
|
const selectedOption = evt?.target?.options[evt.target.selectedIndex];
|
|
@@ -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
|
|
@@ -10,14 +10,13 @@ import { Close, ChevronLeft, ChevronRight } from '@carbon/icons-react';
|
|
|
10
10
|
import { breakpoints } from '@carbon/layout';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import PropTypes from 'prop-types';
|
|
13
|
-
import React, { forwardRef, createContext, useRef, useState, useMemo, isValidElement, useCallback, useEffect } from 'react';
|
|
13
|
+
import React, { forwardRef, createContext, useRef, useState, useMemo, isValidElement, Children, cloneElement, useCallback, useEffect } from 'react';
|
|
14
14
|
import '../Grid/FlexGrid.js';
|
|
15
15
|
import { Grid as GridAsGridComponent } from '../Grid/Grid.js';
|
|
16
16
|
import '../Grid/Row.js';
|
|
17
17
|
import '../Grid/Column.js';
|
|
18
18
|
import '../Grid/ColumnHang.js';
|
|
19
19
|
import '../Grid/GridContext.js';
|
|
20
|
-
import { isElement } from 'react-is';
|
|
21
20
|
import '../Tooltip/DefinitionTooltip.js';
|
|
22
21
|
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
23
22
|
import { useControllableState } from '../../internal/useControllableState.js';
|
|
@@ -34,6 +33,7 @@ import { useMatchMedia } from '../../internal/useMatchMedia.js';
|
|
|
34
33
|
import { Text } from '../Text/Text.js';
|
|
35
34
|
import '../Text/TextDirection.js';
|
|
36
35
|
import { BadgeIndicator } from '../BadgeIndicator/index.js';
|
|
36
|
+
import { isComponentElement } from '../../internal/utils.js';
|
|
37
37
|
import { debounce } from '../../node_modules/es-toolkit/dist/compat/function/debounce.js';
|
|
38
38
|
|
|
39
39
|
var _ChevronLeft, _ChevronRight, _BadgeIndicator;
|
|
@@ -269,14 +269,7 @@ function TabList({
|
|
|
269
269
|
const nextButton = useRef(null);
|
|
270
270
|
const [isScrollable, setIsScrollable] = useState(false);
|
|
271
271
|
const [scrollLeft, setScrollLeft] = useState(0);
|
|
272
|
-
|
|
273
|
-
if (contained) {
|
|
274
|
-
hasSecondaryLabelTabs = React.Children.toArray(children).some(child => {
|
|
275
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452
|
|
276
|
-
const _child = child;
|
|
277
|
-
return /*#__PURE__*/React.isValidElement(child) && !!_child.props.secondaryLabel;
|
|
278
|
-
});
|
|
279
|
-
}
|
|
272
|
+
const hasSecondaryLabelTabs = contained && Children.toArray(children).some(child => isComponentElement(child, Tab) && typeof child.props.secondaryLabel !== 'undefined');
|
|
280
273
|
const isLg = useMatchMedia(lgMediaQuery);
|
|
281
274
|
const distributeWidth = fullWidth && contained && isLg && React.Children.toArray(children).length < 9;
|
|
282
275
|
const className = cx(`${prefix}--tabs`, {
|
|
@@ -487,17 +480,16 @@ function TabList({
|
|
|
487
480
|
onScroll: debouncedOnScroll,
|
|
488
481
|
onKeyDown: onKeyDown,
|
|
489
482
|
onBlur: handleBlur
|
|
490
|
-
}),
|
|
491
|
-
return !
|
|
483
|
+
}), Children.map(children, (child, index) => {
|
|
484
|
+
return ! /*#__PURE__*/isValidElement(child) ? null : /*#__PURE__*/React.createElement(TabContext.Provider, {
|
|
492
485
|
value: {
|
|
493
486
|
index,
|
|
494
487
|
hasSecondaryLabel: hasSecondaryLabelTabs,
|
|
495
488
|
contained
|
|
496
489
|
}
|
|
497
|
-
}, /*#__PURE__*/
|
|
498
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452
|
|
499
|
-
child, {
|
|
490
|
+
}, /*#__PURE__*/cloneElement(child, {
|
|
500
491
|
ref: node => {
|
|
492
|
+
if (!node) return;
|
|
501
493
|
tabs.current[index] = node;
|
|
502
494
|
}
|
|
503
495
|
}));
|
|
@@ -641,8 +633,7 @@ function TabListVertical({
|
|
|
641
633
|
if (containerTop && containerHeight) {
|
|
642
634
|
// scrolls so selected tab is in view
|
|
643
635
|
if (selectedPositionTop - halfTabHeight < containerTop || selectedPositionTop - containerTop + verticalTabHeight + halfTabHeight > containerHeight) {
|
|
644
|
-
|
|
645
|
-
ref.current && ref.current.scrollTo({
|
|
636
|
+
ref.current?.scrollTo({
|
|
646
637
|
top: (selectedIndex - 1) * verticalTabHeight,
|
|
647
638
|
behavior: 'smooth'
|
|
648
639
|
});
|
|
@@ -690,16 +681,15 @@ function TabListVertical({
|
|
|
690
681
|
className: `${prefix}--tab--list`,
|
|
691
682
|
onKeyDown: onKeyDown,
|
|
692
683
|
onBlur: handleBlur
|
|
693
|
-
}),
|
|
694
|
-
return !
|
|
684
|
+
}), Children.map(children, (child, index) => {
|
|
685
|
+
return ! /*#__PURE__*/isValidElement(child) ? null : /*#__PURE__*/React.createElement(TabContext.Provider, {
|
|
695
686
|
value: {
|
|
696
687
|
index,
|
|
697
688
|
hasSecondaryLabel: false
|
|
698
689
|
}
|
|
699
|
-
}, /*#__PURE__*/
|
|
700
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- https://github.com/carbon-design-system/carbon/issues/20452
|
|
701
|
-
child, {
|
|
690
|
+
}, /*#__PURE__*/cloneElement(child, {
|
|
702
691
|
ref: node => {
|
|
692
|
+
if (!node) return;
|
|
703
693
|
tabs.current[index] = node;
|
|
704
694
|
}
|
|
705
695
|
}));
|
|
@@ -1045,7 +1035,11 @@ const IconTab = /*#__PURE__*/React.forwardRef(({
|
|
|
1045
1035
|
const value = useMemo(() => ({
|
|
1046
1036
|
badgeIndicator
|
|
1047
1037
|
}), [badgeIndicator]);
|
|
1048
|
-
const hasSize20 = /*#__PURE__*/isValidElement(children) &&
|
|
1038
|
+
const hasSize20 = /*#__PURE__*/isValidElement(children) &&
|
|
1039
|
+
// TODO: The interface allows `size` to be a string. Should this case be
|
|
1040
|
+
// handled here, or should the prop type be restricted to `number`
|
|
1041
|
+
// instead?
|
|
1042
|
+
children.props.size === 20;
|
|
1049
1043
|
const classNames = cx(`${prefix}--tabs__nav-item--icon-only`, customClassName, {
|
|
1050
1044
|
[`${prefix}--tabs__nav-item--icon-only__20`]: hasSize20
|
|
1051
1045
|
});
|
|
@@ -1176,10 +1170,10 @@ function TabPanels({
|
|
|
1176
1170
|
});
|
|
1177
1171
|
}
|
|
1178
1172
|
});
|
|
1179
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null,
|
|
1180
|
-
return !
|
|
1173
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, Children.map(children, (child, index) => {
|
|
1174
|
+
return ! /*#__PURE__*/isValidElement(child) ? null : /*#__PURE__*/React.createElement(TabPanelContext.Provider, {
|
|
1181
1175
|
value: index
|
|
1182
|
-
}, /*#__PURE__*/
|
|
1176
|
+
}, /*#__PURE__*/cloneElement(child, {
|
|
1183
1177
|
ref: element => {
|
|
1184
1178
|
refs.current[index] = element;
|
|
1185
1179
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
|
-
import React, { forwardRef, useRef, useState,
|
|
10
|
+
import React, { forwardRef, useRef, useState, cloneElement } from 'react';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { useId } from '../../internal/useId.js';
|
|
13
13
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -22,6 +22,7 @@ import { isEllipsisActive } from './isEllipsisActive.js';
|
|
|
22
22
|
import { mergeRefs } from '../../tools/mergeRefs.js';
|
|
23
23
|
import { AILabel } from '../AILabel/index.js';
|
|
24
24
|
import { isComponentElement } from '../../internal/utils.js';
|
|
25
|
+
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
25
26
|
|
|
26
27
|
var _Close;
|
|
27
28
|
// eslint-disable-next-line react/display-name -- https://github.com/carbon-design-system/carbon/issues/20452
|
|
@@ -48,7 +49,7 @@ const DismissibleTag = /*#__PURE__*/forwardRef(({
|
|
|
48
49
|
const tagId = id || `tag-${useId()}`;
|
|
49
50
|
const tagClasses = cx(`${prefix}--tag--filter`, className);
|
|
50
51
|
const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
|
|
51
|
-
|
|
52
|
+
useIsomorphicEffect(() => {
|
|
52
53
|
const newElement = tagLabelRef.current?.getElementsByClassName(`${prefix}--tag__label`)[0];
|
|
53
54
|
setIsEllipsisApplied(isEllipsisActive(newElement));
|
|
54
55
|
}, [prefix, tagLabelRef]);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
|
-
import React, { forwardRef, useRef, useState
|
|
10
|
+
import React, { forwardRef, useRef, useState } from 'react';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { useId } from '../../internal/useId.js';
|
|
13
13
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -18,6 +18,7 @@ import { Text } from '../Text/Text.js';
|
|
|
18
18
|
import '../Text/TextDirection.js';
|
|
19
19
|
import { isEllipsisActive } from './isEllipsisActive.js';
|
|
20
20
|
import { mergeRefs } from '../../tools/mergeRefs.js';
|
|
21
|
+
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
21
22
|
|
|
22
23
|
const TYPES = {
|
|
23
24
|
red: 'Red',
|
|
@@ -48,7 +49,7 @@ const OperationalTag = /*#__PURE__*/forwardRef(({
|
|
|
48
49
|
const tagId = id || `tag-${useId()}`;
|
|
49
50
|
const tagClasses = cx(`${prefix}--tag--operational`, className);
|
|
50
51
|
const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
|
|
51
|
-
|
|
52
|
+
useIsomorphicEffect(() => {
|
|
52
53
|
const newElement = tagRef.current?.getElementsByClassName(`${prefix}--tag__label`)[0];
|
|
53
54
|
setIsEllipsisApplied(isEllipsisActive(newElement));
|
|
54
55
|
}, [prefix, tagRef]);
|