@carbon/react 1.100.0-rc.0 → 1.100.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 +973 -973
- package/es/components/ComboBox/ComboBox.d.ts +3 -4
- package/es/components/ComboBox/ComboBox.js +2 -8
- package/es/components/Dropdown/Dropdown.d.ts +3 -4
- package/es/components/Dropdown/Dropdown.js +16 -13
- 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/MultiSelect/MultiSelect.d.ts +3 -4
- package/es/components/MultiSelect/MultiSelect.js +2 -9
- package/es/components/Notification/Notification.js +4 -3
- package/es/components/TextArea/TextArea.js +1 -3
- package/es/components/Tile/Tile.d.ts +1 -1
- package/es/components/Tile/Tile.js +37 -69
- package/es/components/UIShell/SideNav.d.ts +0 -1
- package/es/components/UIShell/SideNav.js +12 -3
- package/lib/components/ComboBox/ComboBox.d.ts +3 -4
- package/lib/components/ComboBox/ComboBox.js +2 -8
- package/lib/components/Dropdown/Dropdown.d.ts +3 -4
- package/lib/components/Dropdown/Dropdown.js +16 -13
- 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/MultiSelect/MultiSelect.d.ts +3 -4
- package/lib/components/MultiSelect/MultiSelect.js +2 -9
- package/lib/components/Notification/Notification.js +4 -3
- package/lib/components/TextArea/TextArea.js +1 -3
- package/lib/components/Tile/Tile.d.ts +1 -1
- package/lib/components/Tile/Tile.js +35 -67
- package/lib/components/UIShell/SideNav.d.ts +0 -1
- package/lib/components/UIShell/SideNav.js +11 -2
- package/package.json +7 -7
|
@@ -454,9 +454,6 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
454
454
|
[`${prefix}--combo-box--input--focus`]: isFocused
|
|
455
455
|
});
|
|
456
456
|
|
|
457
|
-
// needs to be Capitalized for react to render it correctly
|
|
458
|
-
const ItemToElement = itemToElement;
|
|
459
|
-
|
|
460
457
|
// AILabel always size `mini`
|
|
461
458
|
const candidate = slug ?? decorator;
|
|
462
459
|
const candidateIsAILabel = utils.isComponentElement(candidate, index$1.AILabel);
|
|
@@ -788,9 +785,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
788
785
|
isHighlighted: highlightedIndex === index,
|
|
789
786
|
title: title,
|
|
790
787
|
disabled: disabled
|
|
791
|
-
}, modifiedItemProps),
|
|
792
|
-
key: itemProps.id
|
|
793
|
-
}, item)) : itemToString(item), isEqual(currentSelectedItem, item) && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
|
|
788
|
+
}, modifiedItemProps), itemToElement ? itemToElement(item) : itemToString(item), isEqual(currentSelectedItem, item) && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
|
|
794
789
|
className: `${prefix}--list-box__menu-item__selected-icon`
|
|
795
790
|
}));
|
|
796
791
|
}) : null)), helperText && !invalid && !warn && !isFluid && /*#__PURE__*/React.createElement(Text.Text, {
|
|
@@ -886,8 +881,7 @@ ComboBox.propTypes = {
|
|
|
886
881
|
*/
|
|
887
882
|
invalidText: PropTypes.node,
|
|
888
883
|
/**
|
|
889
|
-
*
|
|
890
|
-
* Defaults to null and is overridden by a getter
|
|
884
|
+
* Renders an item as a custom React node instead of a string.
|
|
891
885
|
*/
|
|
892
886
|
itemToElement: PropTypes.func,
|
|
893
887
|
/**
|
|
@@ -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.
|
|
@@ -78,10 +78,9 @@ export interface DropdownProps<ItemType> extends Omit<HTMLAttributes<HTMLDivElem
|
|
|
78
78
|
*/
|
|
79
79
|
invalidText?: ReactNode;
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
* Defaults to null and is overridden by a getter
|
|
81
|
+
* Renders an item as a custom React node instead of a string.
|
|
83
82
|
*/
|
|
84
|
-
itemToElement?:
|
|
83
|
+
itemToElement?: ((item: ItemType) => NonNullable<ReactNode>) | null;
|
|
85
84
|
/**
|
|
86
85
|
* Helper function passed to downshift that allows the library to render a
|
|
87
86
|
* given item to a string label. By default, it extracts the `label` field
|
|
@@ -256,9 +256,6 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
|
|
|
256
256
|
[`${prefix}--list-box__wrapper--slug`]: slug,
|
|
257
257
|
[`${prefix}--list-box__wrapper--decorator`]: decorator
|
|
258
258
|
});
|
|
259
|
-
|
|
260
|
-
// needs to be Capitalized for react to render it correctly
|
|
261
|
-
const ItemToElement = itemToElement;
|
|
262
259
|
const toggleButtonProps = getToggleButtonProps({
|
|
263
260
|
'aria-label': ariaLabel || deprecatedAriaLabel
|
|
264
261
|
});
|
|
@@ -274,10 +271,20 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
|
|
|
274
271
|
const [currTimer, setCurrTimer] = React.useState();
|
|
275
272
|
const [isTyping, setIsTyping] = React.useState(false);
|
|
276
273
|
const onKeyDownHandler = React.useCallback(evt => {
|
|
277
|
-
|
|
274
|
+
const navigationKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
|
|
275
|
+
|
|
276
|
+
// If the key is not a navigation key, the user is typing
|
|
277
|
+
if (!navigationKeys.includes(evt.key)) {
|
|
278
278
|
setIsTyping(true);
|
|
279
|
-
|
|
280
|
-
|
|
279
|
+
// Reset the timer for typing timeout
|
|
280
|
+
if (currTimer) {
|
|
281
|
+
clearTimeout(currTimer);
|
|
282
|
+
}
|
|
283
|
+
setCurrTimer(setTimeout(() => {
|
|
284
|
+
setIsTyping(false);
|
|
285
|
+
}, 3000));
|
|
286
|
+
} else if (isTyping && evt.key === ' ') {
|
|
287
|
+
// If user is typing and presses space, reset the timer
|
|
281
288
|
if (currTimer) {
|
|
282
289
|
clearTimeout(currTimer);
|
|
283
290
|
}
|
|
@@ -381,21 +388,18 @@ const Dropdown = /*#__PURE__*/React.forwardRef(({
|
|
|
381
388
|
})), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
|
|
382
389
|
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
383
390
|
}, normalizedDecorator) : '', /*#__PURE__*/React.createElement(index$2.default.Menu, menuProps, isOpen && items.map((item, index) => {
|
|
384
|
-
const isObject = item !== null && typeof item === 'object';
|
|
385
391
|
const itemProps = getItemProps({
|
|
386
392
|
item,
|
|
387
393
|
index
|
|
388
394
|
});
|
|
389
|
-
const title =
|
|
395
|
+
const title = itemToString(item);
|
|
390
396
|
return /*#__PURE__*/React.createElement(index$2.default.MenuItem, _rollupPluginBabelHelpers.extends({
|
|
391
397
|
key: itemProps.id,
|
|
392
398
|
isActive: selectedItem === item,
|
|
393
399
|
isHighlighted: highlightedIndex === index,
|
|
394
400
|
title: title,
|
|
395
401
|
disabled: itemProps['aria-disabled']
|
|
396
|
-
}, itemProps),
|
|
397
|
-
key: itemProps.id
|
|
398
|
-
}, item)) : itemToString(item), selectedItem === item && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
|
|
402
|
+
}, itemProps), itemToElement ? itemToElement(item) : itemToString(item), selectedItem === item && /*#__PURE__*/React.createElement(iconsReact.Checkmark, {
|
|
399
403
|
className: `${prefix}--list-box__menu-item__selected-icon`
|
|
400
404
|
}));
|
|
401
405
|
}))), !inline && !isFluid && !normalizedProps.validation && helper, !inline && !isFluid && normalizedProps.validation);
|
|
@@ -475,8 +479,7 @@ Dropdown.propTypes = {
|
|
|
475
479
|
*/
|
|
476
480
|
invalidText: PropTypes.node,
|
|
477
481
|
/**
|
|
478
|
-
*
|
|
479
|
-
* Defaults to null and is overridden by a getter
|
|
482
|
+
* Renders an item as a custom React node instead of a string.
|
|
480
483
|
*/
|
|
481
484
|
itemToElement: PropTypes.func,
|
|
482
485
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
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.
|
|
6
6
|
*/
|
|
7
|
-
import React, {
|
|
7
|
+
import React, { type ComponentProps } from 'react';
|
|
8
8
|
import ComboBox from '../ComboBox';
|
|
9
9
|
import { ComboBoxProps } from '../ComboBox/ComboBox';
|
|
10
10
|
type ItemToStringHandler<ItemType> = (item: ItemType | null) => string;
|
|
@@ -46,11 +46,6 @@ export interface FluidComboBoxProps<ItemType> extends ComboBoxProps<ItemType>, P
|
|
|
46
46
|
* Specify if the `FluidComboBox` should render its menu items in condensed mode
|
|
47
47
|
*/
|
|
48
48
|
isCondensed?: boolean;
|
|
49
|
-
/**
|
|
50
|
-
* Function to render items as custom components instead of strings.
|
|
51
|
-
* Defaults to null and is overridden by a getter
|
|
52
|
-
*/
|
|
53
|
-
itemToElement?: ComponentType<ItemType> | null;
|
|
54
49
|
/**
|
|
55
50
|
* Helper function passed to downshift that allows the library to render a
|
|
56
51
|
* given item to a string label. By default, it extracts the `label` field
|
|
@@ -70,8 +70,7 @@ FluidComboBox.propTypes = {
|
|
|
70
70
|
*/
|
|
71
71
|
isCondensed: PropTypes.bool,
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
74
|
-
* Defaults to null and is overridden by a getter
|
|
73
|
+
* Renders an item as a custom React node instead of a string.
|
|
75
74
|
*/
|
|
76
75
|
itemToElement: PropTypes.func,
|
|
77
76
|
/**
|
|
@@ -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
|
|
@@ -71,8 +71,7 @@ FluidDropdown.propTypes = {
|
|
|
71
71
|
*/
|
|
72
72
|
isCondensed: PropTypes.bool,
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
75
|
-
* Defaults to null and is overridden by a getter
|
|
74
|
+
* Renders an item as a custom React node instead of a string.
|
|
76
75
|
*/
|
|
77
76
|
itemToElement: PropTypes.func,
|
|
78
77
|
/**
|
|
@@ -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
|
|
@@ -110,8 +110,7 @@ FluidMultiSelect.propTypes = {
|
|
|
110
110
|
*/
|
|
111
111
|
isFilterable: PropTypes.bool,
|
|
112
112
|
/**
|
|
113
|
-
*
|
|
114
|
-
* Defaults to null and is overridden by a getter
|
|
113
|
+
* Renders an item as a custom React node instead of a string.
|
|
115
114
|
*/
|
|
116
115
|
itemToElement: PropTypes.func,
|
|
117
116
|
/**
|
|
@@ -56,7 +56,10 @@ const InlineLoading = ({
|
|
|
56
56
|
className: `${prefix}--inline-loading__checkmark-container`
|
|
57
57
|
}, /*#__PURE__*/React.createElement("title", null, iconLabel));
|
|
58
58
|
}
|
|
59
|
-
if (status === 'active') {
|
|
59
|
+
if (status === 'inactive' || status === 'active') {
|
|
60
|
+
if (status === 'inactive') {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
60
63
|
if (!iconDescription) {
|
|
61
64
|
iconLabel = 'loading';
|
|
62
65
|
}
|
|
@@ -67,15 +70,6 @@ const InlineLoading = ({
|
|
|
67
70
|
active: status === 'active'
|
|
68
71
|
});
|
|
69
72
|
}
|
|
70
|
-
if (status === 'inactive') {
|
|
71
|
-
if (!iconDescription) {
|
|
72
|
-
iconLabel = 'not loading';
|
|
73
|
-
}
|
|
74
|
-
return /*#__PURE__*/React.createElement("title", {
|
|
75
|
-
className: `${prefix}--inline-loading__inactive-status`
|
|
76
|
-
}, iconLabel);
|
|
77
|
-
}
|
|
78
|
-
return undefined;
|
|
79
73
|
};
|
|
80
74
|
const loadingText = description && /*#__PURE__*/React.createElement("div", {
|
|
81
75
|
className: `${prefix}--inline-loading__text`
|
|
@@ -87,7 +81,7 @@ const InlineLoading = ({
|
|
|
87
81
|
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
|
|
88
82
|
className: loadingClasses
|
|
89
83
|
}, rest, {
|
|
90
|
-
"aria-live": rest['aria-live'] ?? 'assertive'
|
|
84
|
+
"aria-live": rest['aria-live'] ?? (status === 'inactive' ? 'off' : 'assertive')
|
|
91
85
|
}), loadingAnimation, loadingText);
|
|
92
86
|
};
|
|
93
87
|
InlineLoading.propTypes = {
|
|
@@ -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
|
|
@@ -296,10 +296,6 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
296
296
|
[`${prefix}--autoalign`]: enableFloatingStyles,
|
|
297
297
|
[`${prefix}--multi-select--selectall`]: selectAll
|
|
298
298
|
});
|
|
299
|
-
|
|
300
|
-
// needs to be capitalized for react to render it correctly
|
|
301
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
302
|
-
const ItemToElement = itemToElement;
|
|
303
299
|
if (selectionFeedback === 'fixed') {
|
|
304
300
|
sortOptions.selectedItems = [];
|
|
305
301
|
} else if (selectionFeedback === 'top-after-reopen') {
|
|
@@ -528,9 +524,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
528
524
|
className: `${prefix}--checkbox-wrapper`
|
|
529
525
|
}, /*#__PURE__*/React.createElement(Checkbox.default, {
|
|
530
526
|
id: `${itemProps.id}__checkbox`,
|
|
531
|
-
labelText: itemToElement ?
|
|
532
|
-
key: itemProps.id
|
|
533
|
-
}, item)) : itemText,
|
|
527
|
+
labelText: itemToElement ? itemToElement(item) : itemText,
|
|
534
528
|
checked: isChecked,
|
|
535
529
|
title: useTitleInItem ? itemText : undefined,
|
|
536
530
|
indeterminate: isIndeterminate,
|
|
@@ -621,8 +615,7 @@ MultiSelect.propTypes = {
|
|
|
621
615
|
*/
|
|
622
616
|
invalidText: PropTypes.node,
|
|
623
617
|
/**
|
|
624
|
-
*
|
|
625
|
-
* Defaults to null and is overridden by a getter
|
|
618
|
+
* Renders an item as a custom React node instead of a string.
|
|
626
619
|
*/
|
|
627
620
|
itemToElement: PropTypes.func,
|
|
628
621
|
/**
|
|
@@ -574,6 +574,8 @@ function ActionableNotification({
|
|
|
574
574
|
role: "link",
|
|
575
575
|
className: `${prefix}--visually-hidden`
|
|
576
576
|
}, "Focus sentinel"), /*#__PURE__*/React.createElement("div", {
|
|
577
|
+
ref: innerModal
|
|
578
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
577
579
|
className: `${prefix}--actionable-notification__details`
|
|
578
580
|
}, /*#__PURE__*/React.createElement(NotificationIcon, {
|
|
579
581
|
notificationType: inline ? 'inline' : 'toast',
|
|
@@ -595,8 +597,7 @@ function ActionableNotification({
|
|
|
595
597
|
as: "div",
|
|
596
598
|
className: `${prefix}--actionable-notification__caption`
|
|
597
599
|
}, caption), children))), /*#__PURE__*/React.createElement("div", {
|
|
598
|
-
className: `${prefix}--actionable-notification__button-wrapper
|
|
599
|
-
ref: innerModal
|
|
600
|
+
className: `${prefix}--actionable-notification__button-wrapper`
|
|
600
601
|
}, actionButtonLabel && /*#__PURE__*/React.createElement(NotificationActionButton, {
|
|
601
602
|
onClick: onActionButtonClick,
|
|
602
603
|
inline: inline
|
|
@@ -604,7 +605,7 @@ function ActionableNotification({
|
|
|
604
605
|
"aria-label": deprecatedAriaLabel || ariaLabel,
|
|
605
606
|
notificationType: "actionable",
|
|
606
607
|
onClick: handleCloseButtonClick
|
|
607
|
-
})), !focusTrapWithoutSentinels && /*#__PURE__*/React.createElement("span", {
|
|
608
|
+
}))), !focusTrapWithoutSentinels && /*#__PURE__*/React.createElement("span", {
|
|
608
609
|
ref: endTrap,
|
|
609
610
|
tabIndex: 0,
|
|
610
611
|
role: "link",
|
|
@@ -148,9 +148,7 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
148
148
|
setTimeout(() => {
|
|
149
149
|
setTextCount(0);
|
|
150
150
|
}, 0);
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
if (enableCounter && typeof maxCount !== 'undefined' && textareaRef.current !== null) {
|
|
151
|
+
} else if (enableCounter && typeof maxCount !== 'undefined' && textareaRef.current !== null) {
|
|
154
152
|
const matchedWords = evt.target?.value?.match(/\p{L}+/gu);
|
|
155
153
|
if (matchedWords && matchedWords.length <= maxCount) {
|
|
156
154
|
textareaRef.current.removeAttribute('maxLength');
|
|
@@ -384,11 +384,8 @@ const ExpandableTile = /*#__PURE__*/React.forwardRef(({
|
|
|
384
384
|
hasRoundedCorners,
|
|
385
385
|
...rest
|
|
386
386
|
}, forwardRef) => {
|
|
387
|
-
const [
|
|
388
|
-
const [
|
|
389
|
-
const [prevExpanded, setPrevExpanded] = React.useState(expanded);
|
|
390
|
-
const [prevTileMaxHeight, setPrevTileMaxHeight] = React.useState(tileMaxHeight);
|
|
391
|
-
const [prevTilePadding, setPrevTilePadding] = React.useState(tilePadding);
|
|
387
|
+
const [measuredAboveHeight, setMeasuredAboveHeight] = React.useState(0);
|
|
388
|
+
const [measuredPadding, setMeasuredPadding] = React.useState(0);
|
|
392
389
|
const [isExpanded, setIsExpanded] = React.useState(expanded);
|
|
393
390
|
const [interactive, setInteractive] = React.useState(true);
|
|
394
391
|
const aboveTheFold = React.useRef(null);
|
|
@@ -398,105 +395,74 @@ const ExpandableTile = /*#__PURE__*/React.forwardRef(({
|
|
|
398
395
|
const tile = React.useRef(null);
|
|
399
396
|
const ref = useMergedRefs.useMergedRefs([forwardRef, tile]);
|
|
400
397
|
const prefix = usePrefix.usePrefix();
|
|
401
|
-
|
|
398
|
+
React.useEffect(() => {
|
|
402
399
|
setIsExpanded(expanded);
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
setPrevTileMaxHeight(tileMaxHeight);
|
|
409
|
-
}
|
|
410
|
-
if (tilePadding !== prevTilePadding) {
|
|
411
|
-
setIsTilePadding(tilePadding);
|
|
412
|
-
setPrevTilePadding(tilePadding);
|
|
413
|
-
}
|
|
414
|
-
function setMaxHeight() {
|
|
415
|
-
if (isExpanded && tileContent.current) {
|
|
416
|
-
setIsTileMaxHeight(tileContent.current.getBoundingClientRect()?.height);
|
|
417
|
-
}
|
|
418
|
-
if (aboveTheFold.current) {
|
|
419
|
-
setIsTileMaxHeight(aboveTheFold.current.getBoundingClientRect().height);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
function handleClick(evt) {
|
|
423
|
-
evt?.persist?.();
|
|
424
|
-
setIsExpanded(!isExpanded);
|
|
425
|
-
setMaxHeight();
|
|
426
|
-
}
|
|
427
|
-
function handleKeyUp(evt) {
|
|
400
|
+
}, [expanded]);
|
|
401
|
+
const handleClick = () => {
|
|
402
|
+
setIsExpanded(prev => !prev);
|
|
403
|
+
};
|
|
404
|
+
const handleKeyUp = evt => {
|
|
428
405
|
if (evt.target !== tile.current && evt.target !== chevronInteractiveRef.current) {
|
|
429
406
|
if (match.matches(evt, [keys.Enter, keys.Space])) {
|
|
430
407
|
evt.preventDefault();
|
|
431
408
|
}
|
|
432
409
|
}
|
|
433
|
-
}
|
|
434
|
-
function getChildren() {
|
|
435
|
-
return React.Children.toArray(children);
|
|
436
|
-
}
|
|
410
|
+
};
|
|
437
411
|
const classNames = cx(`${prefix}--tile`, `${prefix}--tile--expandable`, {
|
|
438
412
|
[`${prefix}--tile--is-expanded`]: isExpanded,
|
|
439
413
|
[`${prefix}--tile--light`]: light
|
|
440
414
|
}, className);
|
|
441
|
-
const interactiveClassNames = cx(
|
|
442
|
-
[`${prefix}--tile--is-expanded`]: isExpanded,
|
|
443
|
-
[`${prefix}--tile--light`]: light,
|
|
415
|
+
const interactiveClassNames = cx(classNames, `${prefix}--tile--expandable--interactive`, {
|
|
444
416
|
[`${prefix}--tile--slug`]: slug,
|
|
445
417
|
[`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners,
|
|
446
418
|
[`${prefix}--tile--decorator`]: decorator,
|
|
447
419
|
[`${prefix}--tile--decorator-rounded`]: decorator && hasRoundedCorners
|
|
448
|
-
}
|
|
420
|
+
});
|
|
449
421
|
const chevronInteractiveClassNames = cx(`${prefix}--tile__chevron`, `${prefix}--tile__chevron--interactive`);
|
|
450
|
-
const childrenAsArray =
|
|
422
|
+
const childrenAsArray = React.Children.toArray(children);
|
|
451
423
|
useIsomorphicEffect.default(() => {
|
|
452
424
|
if (!tile.current || !aboveTheFold.current) {
|
|
453
425
|
return;
|
|
454
426
|
}
|
|
455
|
-
const
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
} = node.getBoundingClientRect();
|
|
462
|
-
const paddingTop = parseInt(getStyle.getPropertyValue('padding-top'), 10);
|
|
463
|
-
const paddingBottom = parseInt(getStyle.getPropertyValue('padding-bottom'), 10);
|
|
464
|
-
setIsTileMaxHeight(height);
|
|
465
|
-
setIsTilePadding(paddingTop + paddingBottom);
|
|
466
|
-
}, [isTileMaxHeight]);
|
|
427
|
+
const style = window.getComputedStyle(tile.current);
|
|
428
|
+
const paddingTop = parseInt(style.getPropertyValue('padding-top'), 10) || 0;
|
|
429
|
+
const paddingBottom = parseInt(style.getPropertyValue('padding-bottom'), 10) || 0;
|
|
430
|
+
setMeasuredPadding(paddingTop + paddingBottom);
|
|
431
|
+
setMeasuredAboveHeight(aboveTheFold.current.scrollHeight);
|
|
432
|
+
}, []);
|
|
467
433
|
useIsomorphicEffect.default(() => {
|
|
468
434
|
if (!aboveTheFold.current || !belowTheFold.current) {
|
|
469
435
|
return;
|
|
470
436
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
if (!useNoInteractiveChildren.getInteractiveContent(belowTheFold.current) && !useNoInteractiveChildren.getRoleContent(belowTheFold.current) && !useNoInteractiveChildren.getInteractiveContent(aboveTheFold.current) && !useNoInteractiveChildren.getRoleContent(aboveTheFold.current) && !(slug || decorator)) {
|
|
475
|
-
setInteractive(false);
|
|
476
|
-
}
|
|
477
|
-
}, [slug, decorator]);
|
|
437
|
+
const hasInteractive = Boolean(useNoInteractiveChildren.getInteractiveContent(aboveTheFold.current)) || Boolean(useNoInteractiveChildren.getRoleContent(aboveTheFold.current)) || Boolean(useNoInteractiveChildren.getInteractiveContent(belowTheFold.current)) || Boolean(useNoInteractiveChildren.getRoleContent(belowTheFold.current)) || Boolean(slug || decorator);
|
|
438
|
+
setInteractive(hasInteractive);
|
|
439
|
+
}, [slug, decorator, children]);
|
|
478
440
|
useIsomorphicEffect.default(() => {
|
|
479
441
|
if (!tile.current) {
|
|
480
442
|
return;
|
|
481
443
|
}
|
|
482
444
|
if (isExpanded) {
|
|
483
445
|
tile.current.style.maxHeight = '';
|
|
484
|
-
|
|
485
|
-
tile.current.style.maxHeight = isTileMaxHeight + isTilePadding + 'px';
|
|
446
|
+
return;
|
|
486
447
|
}
|
|
487
|
-
|
|
448
|
+
const measured = measuredAboveHeight || aboveTheFold.current?.scrollHeight || 0;
|
|
449
|
+
const baseHeight = tileMaxHeight > 0 ? tileMaxHeight : measured;
|
|
450
|
+
const pad = tilePadding > 0 ? tilePadding : measuredPadding;
|
|
451
|
+
tile.current.style.maxHeight = `${baseHeight + pad}px`;
|
|
452
|
+
}, [isExpanded, tileMaxHeight, tilePadding, measuredAboveHeight, measuredPadding]);
|
|
488
453
|
React.useEffect(() => {
|
|
489
454
|
if (!aboveTheFold.current) {
|
|
490
455
|
return;
|
|
491
456
|
}
|
|
492
|
-
const resizeObserver = new ResizeObserver(
|
|
493
|
-
|
|
494
|
-
|
|
457
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
458
|
+
if (aboveTheFold.current) {
|
|
459
|
+
setMeasuredAboveHeight(aboveTheFold.current.scrollHeight);
|
|
460
|
+
}
|
|
495
461
|
});
|
|
496
462
|
resizeObserver.observe(aboveTheFold.current);
|
|
497
463
|
return () => resizeObserver.disconnect();
|
|
498
|
-
}, [
|
|
499
|
-
const belowTheFoldId = useId.useId('expandable-tile-interactive');
|
|
464
|
+
}, []);
|
|
465
|
+
const belowTheFoldId = useId.useId(interactive ? 'expandable-tile-interactive' : 'expandable-tile');
|
|
500
466
|
|
|
501
467
|
// AILabel is always size `xs`
|
|
502
468
|
const candidate = slug ?? decorator;
|
|
@@ -531,6 +497,7 @@ const ExpandableTile = /*#__PURE__*/React.forwardRef(({
|
|
|
531
497
|
type: "button",
|
|
532
498
|
ref: ref,
|
|
533
499
|
className: classNames,
|
|
500
|
+
"aria-controls": belowTheFoldId,
|
|
534
501
|
"aria-expanded": isExpanded,
|
|
535
502
|
title: isExpanded ? tileExpandedIconText : tileCollapsedIconText
|
|
536
503
|
}, rest, {
|
|
@@ -546,6 +513,7 @@ const ExpandableTile = /*#__PURE__*/React.forwardRef(({
|
|
|
546
513
|
className: `${prefix}--tile__chevron`
|
|
547
514
|
}, /*#__PURE__*/React.createElement("span", null, isExpanded ? tileExpandedLabel : tileCollapsedLabel), _ChevronDown2 || (_ChevronDown2 = /*#__PURE__*/React.createElement(iconsReact.ChevronDown, null))), /*#__PURE__*/React.createElement("div", {
|
|
548
515
|
ref: belowTheFold,
|
|
516
|
+
id: belowTheFoldId,
|
|
549
517
|
className: `${prefix}--tile-content`
|
|
550
518
|
}, childrenAsArray[1])));
|
|
551
519
|
});
|
|
@@ -161,6 +161,16 @@ const SideNav = frFn((props, ref) => {
|
|
|
161
161
|
});
|
|
162
162
|
const lgMediaQuery = `(min-width: ${layout.breakpoints.lg.width})`;
|
|
163
163
|
const isLg = useMatchMedia.useMatchMedia(lgMediaQuery);
|
|
164
|
+
const inertEnabled = !isRail ? !(expanded || isLg) : false;
|
|
165
|
+
React.useEffect(() => {
|
|
166
|
+
const node = sideNavRef.current;
|
|
167
|
+
if (!node) return;
|
|
168
|
+
if (inertEnabled) {
|
|
169
|
+
node.setAttribute('inert', '');
|
|
170
|
+
} else {
|
|
171
|
+
node.removeAttribute('inert');
|
|
172
|
+
}
|
|
173
|
+
}, [inertEnabled]);
|
|
164
174
|
return /*#__PURE__*/React.createElement(SideNavContext.Provider, {
|
|
165
175
|
value: {
|
|
166
176
|
isRail
|
|
@@ -174,8 +184,7 @@ const SideNav = frFn((props, ref) => {
|
|
|
174
184
|
}), /*#__PURE__*/React.createElement("nav", _rollupPluginBabelHelpers.extends({
|
|
175
185
|
tabIndex: -1,
|
|
176
186
|
ref: navRef,
|
|
177
|
-
className: `${prefix}--side-nav__navigation ${className}
|
|
178
|
-
inert: !isRail ? !(expanded || isLg) : undefined
|
|
187
|
+
className: `${prefix}--side-nav__navigation ${className}`
|
|
179
188
|
}, accessibilityLabel, eventHandlers, other), childrenToRender));
|
|
180
189
|
});
|
|
181
190
|
SideNav.displayName = 'SideNav';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carbon/react",
|
|
3
3
|
"description": "React components for the Carbon Design System",
|
|
4
|
-
"version": "1.100.0
|
|
4
|
+
"version": "1.100.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@babel/runtime": "^7.27.3",
|
|
55
55
|
"@carbon/feature-flags": ">=0.32.0",
|
|
56
|
-
"@carbon/icons-react": "^11.74.0
|
|
57
|
-
"@carbon/layout": "^11.47.0
|
|
58
|
-
"@carbon/styles": "^1.99.0
|
|
59
|
-
"@carbon/utilities": "^0.15.0
|
|
56
|
+
"@carbon/icons-react": "^11.74.0",
|
|
57
|
+
"@carbon/layout": "^11.47.0",
|
|
58
|
+
"@carbon/styles": "^1.99.0",
|
|
59
|
+
"@carbon/utilities": "^0.15.0",
|
|
60
60
|
"@floating-ui/react": "^0.27.4",
|
|
61
61
|
"@ibm/telemetry-js": "^1.5.0",
|
|
62
62
|
"classnames": "2.5.1",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"@babel/preset-react": "^7.27.1",
|
|
80
80
|
"@babel/preset-typescript": "^7.27.1",
|
|
81
81
|
"@carbon/test-utils": "^10.39.0",
|
|
82
|
-
"@carbon/themes": "^11.67.0
|
|
82
|
+
"@carbon/themes": "^11.67.0",
|
|
83
83
|
"@figma/code-connect": "^1.3.5",
|
|
84
84
|
"@rollup/plugin-babel": "^6.0.0",
|
|
85
85
|
"@rollup/plugin-commonjs": "^28.0.3",
|
|
@@ -131,5 +131,5 @@
|
|
|
131
131
|
"**/*.scss",
|
|
132
132
|
"**/*.css"
|
|
133
133
|
],
|
|
134
|
-
"gitHead": "
|
|
134
|
+
"gitHead": "f366448449df3d81c9bb63a8a842772d734c163a"
|
|
135
135
|
}
|