@carbon/react 1.101.0 → 1.102.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 +998 -963
- package/es/components/Accordion/AccordionItem.js +8 -6
- package/es/components/ComboBox/ComboBox.js +3 -3
- package/es/components/ComposedModal/ComposedModal.js +0 -1
- package/es/components/ContainedList/ContainedList.d.ts +1 -1
- package/es/components/ContainedList/ContainedList.js +9 -34
- package/es/components/ContentSwitcher/ContentSwitcher.d.ts +3 -3
- package/es/components/ContentSwitcher/ContentSwitcher.js +1 -2
- package/es/components/DataTable/DataTable.d.ts +6 -2
- package/es/components/DataTable/DataTable.js +3 -1
- package/es/components/DataTable/Table.js +1 -1
- package/es/components/DataTable/TableToolbarSearch.d.ts +11 -2
- package/es/components/DataTable/TableToolbarSearch.js +10 -3
- package/es/components/DataTable/stories/examples/TableToolbarFilter.d.ts +3 -0
- package/es/components/DataTableSkeleton/DataTableSkeleton.d.ts +2 -12
- package/es/components/DataTableSkeleton/DataTableSkeleton.js +1 -8
- package/es/components/DatePicker/DatePicker.js +4 -1
- package/es/components/DatePickerInput/DatePickerInput.d.ts +2 -5
- package/es/components/DatePickerInput/DatePickerInput.js +2 -13
- package/es/components/Dropdown/Dropdown.js +1 -0
- package/es/components/ExpandableSearch/ExpandableSearch.js +2 -1
- package/es/components/ExpandableSearch/index.js +12 -0
- package/es/components/FluidSelect/FluidSelect.d.ts +3 -3
- package/es/components/FluidTextArea/FluidTextArea.d.ts +2 -4
- package/es/components/FluidTextArea/FluidTextArea.js +1 -2
- package/es/components/FluidTimePickerSelect/FluidTimePickerSelect.d.ts +3 -3
- package/es/components/Grid/Column.d.ts +1 -1
- package/es/components/Grid/Column.js +2 -2
- package/es/components/Loading/Loading.d.ts +1 -1
- package/es/components/Loading/Loading.js +3 -1
- package/es/components/Menu/Menu.d.ts +1 -1
- package/es/components/Menu/Menu.js +6 -2
- package/es/components/Menu/MenuItem.js +2 -2
- package/es/components/Modal/Modal.js +0 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +4 -3
- package/es/components/MultiSelect/MultiSelect.js +5 -8
- package/es/components/MultiSelect/MultiSelectPropTypes.d.ts +6 -8
- package/es/components/MultiSelect/tools/sorting.d.ts +16 -9
- package/es/components/MultiSelect/tools/sorting.js +10 -14
- package/es/components/OverflowMenu/OverflowMenu.js +1 -0
- package/es/components/OverflowMenuItem/OverflowMenuItem.d.ts +5 -1
- package/es/components/OverflowMenuItem/OverflowMenuItem.js +12 -2
- package/es/components/Popover/index.js +3 -3
- package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
- package/es/components/RadioButtonGroup/RadioButtonGroup.js +8 -11
- package/es/components/Search/Search.js +3 -2
- package/es/components/Search/utils.d.ts +7 -0
- package/es/components/Search/utils.js +10 -0
- package/es/components/Select/Select.d.ts +2 -2
- package/es/components/Select/Select.js +1 -1
- package/es/components/SelectItem/SelectItem.d.ts +3 -3
- package/es/components/StructuredList/StructuredList.js +2 -2
- package/es/components/Tabs/Tabs.js +9 -4
- package/es/components/Tag/DismissibleTag.d.ts +1 -1
- package/es/components/Tag/DismissibleTag.js +2 -2
- package/es/components/Tag/OperationalTag.d.ts +1 -1
- package/es/components/Tag/OperationalTag.js +2 -2
- package/es/components/Tag/SelectableTag.d.ts +1 -1
- package/es/components/Tag/SelectableTag.js +2 -2
- package/es/components/Tag/Tag.d.ts +1 -1
- package/es/components/Tag/Tag.js +2 -2
- package/es/components/TextArea/TextArea.d.ts +1 -2
- package/es/components/TextArea/TextArea.js +4 -5
- package/es/components/TextInput/ControlledPasswordInput.js +1 -1
- package/es/components/TimePickerSelect/TimePickerSelect.d.ts +4 -4
- package/es/components/Toggletip/index.js +1 -2
- package/es/components/TreeView/TreeNode.js +2 -2
- package/es/components/TreeView/TreeView.d.ts +1 -1
- package/es/components/UIShell/HeaderPanel.d.ts +1 -1
- package/es/components/UIShell/HeaderPanel.js +4 -2
- package/es/components/UIShell/SideNav.js +3 -3
- package/es/components/UIShell/Switcher.d.ts +1 -1
- package/es/components/UIShell/Switcher.js +1 -1
- package/es/feature-flags.js +2 -2
- package/es/internal/FloatingMenu.js +3 -3
- package/lib/components/Accordion/AccordionItem.js +7 -5
- package/lib/components/ComboBox/ComboBox.js +3 -3
- package/lib/components/ComposedModal/ComposedModal.js +0 -1
- package/lib/components/ContainedList/ContainedList.d.ts +1 -1
- package/lib/components/ContainedList/ContainedList.js +9 -34
- package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +3 -3
- package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -2
- package/lib/components/DataTable/DataTable.d.ts +6 -2
- package/lib/components/DataTable/DataTable.js +3 -1
- package/lib/components/DataTable/Table.js +1 -1
- package/lib/components/DataTable/TableToolbarSearch.d.ts +11 -2
- package/lib/components/DataTable/TableToolbarSearch.js +10 -3
- package/lib/components/DataTable/stories/examples/TableToolbarFilter.d.ts +3 -0
- package/lib/components/DataTableSkeleton/DataTableSkeleton.d.ts +2 -12
- package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -8
- package/lib/components/DatePicker/DatePicker.js +4 -1
- package/lib/components/DatePickerInput/DatePickerInput.d.ts +2 -5
- package/lib/components/DatePickerInput/DatePickerInput.js +2 -13
- package/lib/components/Dropdown/Dropdown.js +1 -0
- package/lib/components/ExpandableSearch/ExpandableSearch.js +2 -1
- package/lib/components/ExpandableSearch/index.js +17 -0
- package/lib/components/FeatureFlags/index.js +5 -5
- package/lib/components/FluidSelect/FluidSelect.d.ts +3 -3
- package/lib/components/FluidTextArea/FluidTextArea.d.ts +2 -4
- package/lib/components/FluidTextArea/FluidTextArea.js +1 -2
- package/lib/components/FluidTimePickerSelect/FluidTimePickerSelect.d.ts +3 -3
- package/lib/components/Grid/Column.d.ts +1 -1
- package/lib/components/Grid/Column.js +2 -21
- package/lib/components/Loading/Loading.d.ts +1 -1
- package/lib/components/Loading/Loading.js +3 -1
- package/lib/components/Menu/Menu.d.ts +1 -1
- package/lib/components/Menu/Menu.js +6 -2
- package/lib/components/Menu/MenuItem.js +2 -2
- package/lib/components/Modal/Modal.js +0 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +4 -3
- package/lib/components/MultiSelect/MultiSelect.js +5 -8
- package/lib/components/MultiSelect/MultiSelectPropTypes.d.ts +6 -8
- package/lib/components/MultiSelect/tools/sorting.d.ts +16 -9
- package/lib/components/MultiSelect/tools/sorting.js +10 -14
- package/lib/components/OverflowMenu/OverflowMenu.js +1 -0
- package/lib/components/OverflowMenuItem/OverflowMenuItem.d.ts +5 -1
- package/lib/components/OverflowMenuItem/OverflowMenuItem.js +12 -2
- package/lib/components/Popover/index.js +3 -3
- package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
- package/lib/components/RadioButtonGroup/RadioButtonGroup.js +7 -10
- package/lib/components/Search/Search.js +3 -2
- package/lib/components/Search/utils.d.ts +7 -0
- package/lib/components/Search/utils.js +12 -0
- package/lib/components/Select/Select.d.ts +2 -2
- package/lib/components/Select/Select.js +1 -1
- package/lib/components/SelectItem/SelectItem.d.ts +3 -3
- package/lib/components/StructuredList/StructuredList.js +2 -2
- package/lib/components/Tabs/Tabs.js +9 -4
- package/lib/components/Tag/DismissibleTag.d.ts +1 -1
- package/lib/components/Tag/DismissibleTag.js +2 -2
- package/lib/components/Tag/OperationalTag.d.ts +1 -1
- package/lib/components/Tag/OperationalTag.js +2 -2
- package/lib/components/Tag/SelectableTag.d.ts +1 -1
- package/lib/components/Tag/SelectableTag.js +2 -2
- package/lib/components/Tag/Tag.d.ts +1 -1
- package/lib/components/Tag/Tag.js +2 -2
- package/lib/components/TextArea/TextArea.d.ts +1 -2
- package/lib/components/TextArea/TextArea.js +4 -5
- package/lib/components/TextInput/ControlledPasswordInput.js +1 -1
- package/lib/components/TimePickerSelect/TimePickerSelect.d.ts +4 -4
- package/lib/components/Toggletip/index.js +1 -2
- package/lib/components/TreeView/TreeNode.js +2 -2
- package/lib/components/TreeView/TreeView.d.ts +1 -1
- package/lib/components/UIShell/HeaderPanel.d.ts +1 -1
- package/lib/components/UIShell/HeaderPanel.js +4 -2
- package/lib/components/UIShell/SideNav.js +3 -3
- package/lib/components/UIShell/Switcher.d.ts +1 -1
- package/lib/components/UIShell/Switcher.js +1 -1
- package/lib/feature-flags.js +2 -21
- package/lib/internal/FloatingMenu.js +3 -22
- package/package.json +7 -7
- package/telemetry.yml +0 -1
|
@@ -69,7 +69,7 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
|
|
|
69
69
|
const context = useContext(MenuContext);
|
|
70
70
|
const menuItem = useRef(null);
|
|
71
71
|
const ref = useMergedRefs([forwardRef, menuItem, refs.setReference]);
|
|
72
|
-
const hasChildren =
|
|
72
|
+
const hasChildren = React.Children.toArray(children).length > 0;
|
|
73
73
|
const isDisabled = disabled && !hasChildren;
|
|
74
74
|
const isDanger = kind === 'danger' && !hasChildren;
|
|
75
75
|
function registerItem() {
|
|
@@ -77,7 +77,7 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem({
|
|
|
77
77
|
type: 'registerItem',
|
|
78
78
|
payload: {
|
|
79
79
|
ref: menuItem,
|
|
80
|
-
disabled:
|
|
80
|
+
disabled: disabled ?? false
|
|
81
81
|
}
|
|
82
82
|
});
|
|
83
83
|
}
|
|
@@ -158,7 +158,6 @@ const ModalDialog = /*#__PURE__*/React.forwardRef(function ModalDialog({
|
|
|
158
158
|
const {
|
|
159
159
|
target
|
|
160
160
|
} = evt;
|
|
161
|
-
evt.stopPropagation();
|
|
162
161
|
const shouldCloseOnOutsideClick =
|
|
163
162
|
// Passive modals can close on clicks outside the modal when
|
|
164
163
|
// preventCloseOnClickOutside is undefined or explicitly set to false.
|
|
@@ -220,7 +220,6 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
220
220
|
item => !item.disabled);
|
|
221
221
|
|
|
222
222
|
// Sort only non-select-all items, select-all item must stay at the top
|
|
223
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- https://github.com/carbon-design-system/carbon/issues/20452
|
|
224
223
|
const sortedReal = sortItems(nonSelectAllItems, {
|
|
225
224
|
selectedItems: {
|
|
226
225
|
top: controlledSelectedItems,
|
|
@@ -313,6 +312,7 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
313
312
|
useEffect(() => {
|
|
314
313
|
const handleClickOutside = event => {
|
|
315
314
|
const target = event.target;
|
|
315
|
+
if (!(target instanceof Node)) return;
|
|
316
316
|
const wrapper = document.getElementById(id)?.closest(`.${prefix}--multi-select__wrapper`);
|
|
317
317
|
|
|
318
318
|
// If click is outside our component and menu is open or input is focused
|
|
@@ -614,10 +614,11 @@ const FilterableMultiSelect = /*#__PURE__*/forwardRef(function FilterableMultiSe
|
|
|
614
614
|
|
|
615
615
|
// Memoize the value of getMenuProps to avoid an infinite loop
|
|
616
616
|
const menuProps = useMemo(() => getMenuProps({
|
|
617
|
-
ref: autoAlign ? refs.setFloating : null
|
|
617
|
+
ref: autoAlign ? refs.setFloating : null,
|
|
618
|
+
hidden: !isOpen
|
|
618
619
|
}, {
|
|
619
620
|
suppressRefError: true
|
|
620
|
-
}), [autoAlign, getMenuProps, refs.setFloating]);
|
|
621
|
+
}), [autoAlign, getMenuProps, isOpen, refs.setFloating]);
|
|
621
622
|
const handleFocus = evt => {
|
|
622
623
|
if (evt?.target.classList.contains(`${prefix}--tag__close-icon`) || evt?.target.classList.contains(`${prefix}--list-box__selection`)) {
|
|
623
624
|
setIsFocused(false);
|
|
@@ -424,8 +424,9 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
424
424
|
|
|
425
425
|
// Memoize the value of getMenuProps to avoid an infinite loop
|
|
426
426
|
const menuProps = useMemo(() => getMenuProps({
|
|
427
|
-
ref: enableFloatingStyles ? refs.setFloating : null
|
|
428
|
-
|
|
427
|
+
ref: enableFloatingStyles ? refs.setFloating : null,
|
|
428
|
+
hidden: !isOpen
|
|
429
|
+
}), [enableFloatingStyles, getMenuProps, isOpen, refs.setFloating]);
|
|
429
430
|
const allLabelProps = getLabelProps();
|
|
430
431
|
const labelProps = /*#__PURE__*/isValidElement(titleText) ? {
|
|
431
432
|
id: allLabelProps.id
|
|
@@ -472,9 +473,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
472
473
|
}, selectedItems.length > 0 && /*#__PURE__*/React.createElement(ListBox.Selection, {
|
|
473
474
|
readOnly: readOnly,
|
|
474
475
|
clearSelection: !disabled && !readOnly ? clearSelection : noopFn,
|
|
475
|
-
selectionCount: selectedItemsLength
|
|
476
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
477
|
-
,
|
|
476
|
+
selectionCount: selectedItemsLength,
|
|
478
477
|
translateWithId: translateWithId,
|
|
479
478
|
disabled: disabled
|
|
480
479
|
}), /*#__PURE__*/React.createElement("button", _extends({
|
|
@@ -493,9 +492,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
493
492
|
translateWithId: translateWithId
|
|
494
493
|
})), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React.createElement("div", {
|
|
495
494
|
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
496
|
-
}, normalizedDecorator) : ''), /*#__PURE__*/React.createElement(ListBox.Menu, menuProps, isOpen &&
|
|
497
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- https://github.com/carbon-design-system/carbon/issues/20452
|
|
498
|
-
sortItems(filteredItems, sortOptions).map((item, index) => {
|
|
495
|
+
}, normalizedDecorator) : ''), /*#__PURE__*/React.createElement(ListBox.Menu, menuProps, isOpen && sortItems(filteredItems, sortOptions).map((item, index) => {
|
|
499
496
|
const {
|
|
500
497
|
hasIndividualSelections,
|
|
501
498
|
nonSelectAllSelectedCount,
|
|
@@ -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.
|
|
@@ -34,17 +34,15 @@ export declare const sortingPropTypes: {
|
|
|
34
34
|
*/
|
|
35
35
|
sortItems: PropTypes.Requireable<(...args: any[]) => any>;
|
|
36
36
|
};
|
|
37
|
-
interface DownshiftTypedProps<ItemType> {
|
|
38
|
-
itemToString?(item: ItemType): string;
|
|
39
|
-
}
|
|
40
37
|
interface SharedOptions {
|
|
41
38
|
locale: string;
|
|
42
39
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
export interface SortItemsOptions<ItemType> extends SharedOptions
|
|
40
|
+
export type CompareItems = (itemA: string, itemB: string, options: {
|
|
41
|
+
locale: string;
|
|
42
|
+
}) => number;
|
|
43
|
+
export interface SortItemsOptions<ItemType> extends SharedOptions {
|
|
47
44
|
compareItems: CompareItems;
|
|
45
|
+
itemToString: (item: ItemType) => string;
|
|
48
46
|
selectedItems: ItemType[];
|
|
49
47
|
}
|
|
50
48
|
export interface MultiSelectSortingProps<ItemType> {
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import type { CompareItems, SortItemsOptions } from '../MultiSelectPropTypes';
|
|
8
|
+
/**
|
|
9
|
+
* Use `localeCompare` with the `numeric` option enabled to sort two
|
|
10
|
+
* alphanumeric strings.
|
|
11
|
+
*/
|
|
12
|
+
export declare const defaultCompareItems: CompareItems;
|
|
13
|
+
/**
|
|
14
|
+
* Default sorting function for options in a selection control.
|
|
15
|
+
*/
|
|
16
|
+
export declare const defaultSortItems: <T>(items: T[], { selectedItems, itemToString, compareItems, locale }: SortItemsOptions<T>) => T[];
|
|
@@ -5,16 +5,11 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
const isSelectAllItem = item => typeof item === 'object' && item !== null && 'isSelectAll' in item;
|
|
9
|
+
|
|
8
10
|
/**
|
|
9
|
-
* Use
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* @param {string} itemA - The first string to compare.
|
|
13
|
-
* @param {string} itemB - The second string to compare.
|
|
14
|
-
* @param {object} options - Options for comparing.
|
|
15
|
-
* @param {string} options.locale - The locale to use for comparison.
|
|
16
|
-
* @returns {number} A negative number if itemA comes before itemB, a positive
|
|
17
|
-
* number if itemA comes after itemB, or 0 if they are equal.
|
|
11
|
+
* Use `localeCompare` with the `numeric` option enabled to sort two
|
|
12
|
+
* alphanumeric strings.
|
|
18
13
|
*/
|
|
19
14
|
const defaultCompareItems = (itemA, itemB, {
|
|
20
15
|
locale
|
|
@@ -23,18 +18,19 @@ const defaultCompareItems = (itemA, itemB, {
|
|
|
23
18
|
});
|
|
24
19
|
|
|
25
20
|
/**
|
|
26
|
-
* Default sorting
|
|
21
|
+
* Default sorting function for options in a selection control.
|
|
27
22
|
*/
|
|
28
23
|
const defaultSortItems = (items, {
|
|
29
|
-
selectedItems
|
|
24
|
+
selectedItems,
|
|
30
25
|
itemToString,
|
|
31
26
|
compareItems,
|
|
32
|
-
locale
|
|
27
|
+
locale
|
|
33
28
|
}) => {
|
|
29
|
+
// TODO: Should this util mutate items or should that be avoided?
|
|
34
30
|
return items.sort((itemA, itemB) => {
|
|
35
31
|
// Always place "select all" option at the beginning
|
|
36
|
-
if (itemA.isSelectAll) return -1;
|
|
37
|
-
if (itemB.isSelectAll) return 1;
|
|
32
|
+
if (isSelectAllItem(itemA) && itemA.isSelectAll) return -1;
|
|
33
|
+
if (isSelectAllItem(itemB) && itemB.isSelectAll) return 1;
|
|
38
34
|
const hasItemA = selectedItems.includes(itemA);
|
|
39
35
|
const hasItemB = selectedItems.includes(itemB);
|
|
40
36
|
if (hasItemA && !hasItemB) return -1;
|
|
@@ -255,6 +255,7 @@ const OverflowMenu = /*#__PURE__*/forwardRef(({
|
|
|
255
255
|
const focusinEventName = hasFocusin ? 'focusin' : 'focus';
|
|
256
256
|
hFocusIn.current = on(menuBody.ownerDocument, focusinEventName, event => {
|
|
257
257
|
const target = event.target;
|
|
258
|
+
if (!(target instanceof Element)) return;
|
|
258
259
|
const triggerEl = triggerRef.current;
|
|
259
260
|
if (typeof target.matches === 'function') {
|
|
260
261
|
if (!menuBody.contains(target) && triggerEl && !target.matches(`.${prefix}--overflow-menu:first-child, .${prefix}--overflow-menu-options:first-child`)) {
|
|
@@ -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.
|
|
@@ -14,6 +14,10 @@ export interface OverflowMenuItemProps extends React.HTMLAttributes<HTMLElement>
|
|
|
14
14
|
* A callback to tell the parent menu component that the menu should be closed.
|
|
15
15
|
*/
|
|
16
16
|
closeMenu?: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Specify the message read by screen readers for the danger overflow menu item variant
|
|
19
|
+
*/
|
|
20
|
+
dangerDescription?: string;
|
|
17
21
|
/**
|
|
18
22
|
* `true` to make this menu item disabled.
|
|
19
23
|
*/
|
|
@@ -15,12 +15,14 @@ import { usePrefix } from '../../internal/usePrefix.js';
|
|
|
15
15
|
import { warning } from '../../internal/warning.js';
|
|
16
16
|
import { Text } from '../Text/Text.js';
|
|
17
17
|
import '../Text/TextDirection.js';
|
|
18
|
+
import { useId } from '../../internal/useId.js';
|
|
18
19
|
|
|
19
20
|
const frFn = forwardRef;
|
|
20
21
|
const OverflowMenuItem = frFn((props, ref) => {
|
|
21
22
|
const {
|
|
22
23
|
className,
|
|
23
24
|
closeMenu,
|
|
25
|
+
dangerDescription = 'danger',
|
|
24
26
|
disabled = false,
|
|
25
27
|
handleOverflowMenuItemFocus,
|
|
26
28
|
hasDivider = false,
|
|
@@ -64,13 +66,17 @@ const OverflowMenuItem = frFn((props, ref) => {
|
|
|
64
66
|
[`${prefix}--overflow-menu-options__option--disabled`]: disabled
|
|
65
67
|
}, wrapperClassName);
|
|
66
68
|
const TagToUse = href ? 'a' : 'button';
|
|
69
|
+
const assistiveId = useId('danger-description');
|
|
67
70
|
const OverflowMenuItemContent = (() => {
|
|
68
71
|
if (typeof itemText !== 'string') {
|
|
69
72
|
return itemText;
|
|
70
73
|
}
|
|
71
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
74
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
72
75
|
className: `${prefix}--overflow-menu-options__option-content`
|
|
73
|
-
}, itemText)
|
|
76
|
+
}, itemText), isDelete && /*#__PURE__*/React.createElement("span", {
|
|
77
|
+
id: assistiveId,
|
|
78
|
+
className: `${prefix}--visually-hidden`
|
|
79
|
+
}, dangerDescription));
|
|
74
80
|
})();
|
|
75
81
|
return /*#__PURE__*/React.createElement(Text, {
|
|
76
82
|
as: "li",
|
|
@@ -110,6 +116,10 @@ OverflowMenuItem.propTypes = {
|
|
|
110
116
|
* A callback to tell the parent menu component that the menu should be closed.
|
|
111
117
|
*/
|
|
112
118
|
closeMenu: PropTypes.func,
|
|
119
|
+
/**
|
|
120
|
+
* Specify the message read by screen readers for the danger overflow menu item variant
|
|
121
|
+
*/
|
|
122
|
+
dangerDescription: PropTypes.string,
|
|
113
123
|
/**
|
|
114
124
|
* `true` to make this menu item disabled.
|
|
115
125
|
*/
|
|
@@ -160,7 +160,8 @@ forwardRef) {
|
|
|
160
160
|
// Middleware order matters, arrow should be last
|
|
161
161
|
middleware: [offset(!isTabTip ? {
|
|
162
162
|
alignmentAxis: alignmentAxisOffset,
|
|
163
|
-
|
|
163
|
+
// Use 4px spacing when no caret, otherwise use the caret offset
|
|
164
|
+
mainAxis: caret ? popoverDimensions?.current?.offset : 4
|
|
164
165
|
} : 0), autoAlign && flip({
|
|
165
166
|
fallbackPlacements: isTabTip ? align.includes('bottom') ? ['bottom-start', 'bottom-end', 'top-start', 'top-end'] : ['top-start', 'top-end', 'bottom-start', 'bottom-end'] : align.includes('bottom') ? ['bottom', 'bottom-start', 'bottom-end', 'right', 'right-start', 'right-end', 'left', 'left-start', 'left-end', 'top', 'top-start', 'top-end'] : ['top', 'top-start', 'top-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end', 'bottom', 'bottom-start', 'bottom-end'],
|
|
166
167
|
fallbackStrategy: 'initialPlacement',
|
|
@@ -297,10 +298,9 @@ forwardRef) {
|
|
|
297
298
|
return item;
|
|
298
299
|
}
|
|
299
300
|
});
|
|
300
|
-
const BaseComponentAsAny = BaseComponent;
|
|
301
301
|
return /*#__PURE__*/React.createElement(PopoverContext.Provider, {
|
|
302
302
|
value: value
|
|
303
|
-
}, /*#__PURE__*/React.createElement(
|
|
303
|
+
}, /*#__PURE__*/React.createElement(BaseComponent, _extends({}, rest, {
|
|
304
304
|
className: className,
|
|
305
305
|
ref: ref
|
|
306
306
|
}), enableFloatingStyles || isTabTip ? mappedChildren : children));
|
|
@@ -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, { useState, useRef, cloneElement } from 'react';
|
|
10
|
+
import React, { useState, useRef, useEffect, cloneElement } from 'react';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { Legend } from '../Text/createTextComponent.js';
|
|
13
13
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -43,17 +43,14 @@ const RadioButtonGroup = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
43
43
|
} = props;
|
|
44
44
|
const prefix = usePrefix();
|
|
45
45
|
const [selected, setSelected] = useState(valueSelected ?? defaultSelected);
|
|
46
|
-
const
|
|
46
|
+
const prevValueSelected = useRef(valueSelected);
|
|
47
47
|
const radioButtonGroupInstanceId = useId();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
setSelected(valueSelected);
|
|
55
|
-
setPrevValueSelected(valueSelected);
|
|
56
|
-
}
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (valueSelected !== prevValueSelected.current) {
|
|
50
|
+
setSelected(valueSelected);
|
|
51
|
+
prevValueSelected.current = valueSelected;
|
|
52
|
+
}
|
|
53
|
+
}, [valueSelected]);
|
|
57
54
|
function getRadioButtons() {
|
|
58
55
|
const mappedChildren = React.Children.map(children, radioButton => {
|
|
59
56
|
if (!radioButton) {
|
|
@@ -22,6 +22,7 @@ import { FormContext } from '../FluidForm/FormContext.js';
|
|
|
22
22
|
import { noopFn } from '../../internal/noopFn.js';
|
|
23
23
|
import '../Tooltip/DefinitionTooltip.js';
|
|
24
24
|
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
25
|
+
import { isSearchValuePresent } from './utils.js';
|
|
25
26
|
|
|
26
27
|
var _Close;
|
|
27
28
|
const Search = /*#__PURE__*/React.forwardRef(({
|
|
@@ -47,7 +48,7 @@ const Search = /*#__PURE__*/React.forwardRef(({
|
|
|
47
48
|
value,
|
|
48
49
|
...rest
|
|
49
50
|
}, forwardRef) => {
|
|
50
|
-
const hasPropValue =
|
|
51
|
+
const hasPropValue = isSearchValuePresent(value) || isSearchValuePresent(defaultValue);
|
|
51
52
|
const prefix = usePrefix();
|
|
52
53
|
const {
|
|
53
54
|
isFluid
|
|
@@ -74,7 +75,7 @@ const Search = /*#__PURE__*/React.forwardRef(({
|
|
|
74
75
|
[`${prefix}--search-close--hidden`]: !hasContent || !isExpanded
|
|
75
76
|
});
|
|
76
77
|
if (value !== prevValue) {
|
|
77
|
-
setHasContent(
|
|
78
|
+
setHasContent(isSearchValuePresent(value));
|
|
78
79
|
setPrevValue(value);
|
|
79
80
|
}
|
|
80
81
|
function clearInput() {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
export declare const isSearchValuePresent: (value: string | number | undefined) => boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2023
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const isSearchValuePresent = value => value !== '' && typeof value !== 'undefined';
|
|
9
|
+
|
|
10
|
+
export { isSearchValuePresent };
|
|
@@ -4,7 +4,7 @@
|
|
|
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, { type ChangeEventHandler, type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
7
|
+
import React, { type ChangeEventHandler, type ComponentPropsWithRef, type ReactNode, type SelectHTMLAttributes } from 'react';
|
|
8
8
|
type ExcludedAttributes = 'size';
|
|
9
9
|
export interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, ExcludedAttributes> {
|
|
10
10
|
/**
|
|
@@ -22,7 +22,7 @@ export interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, Exclu
|
|
|
22
22
|
/**
|
|
23
23
|
* Optionally provide the default value of the `<select>`
|
|
24
24
|
*/
|
|
25
|
-
defaultValue?:
|
|
25
|
+
defaultValue?: SelectHTMLAttributes<HTMLSelectElement>['defaultValue'];
|
|
26
26
|
/**
|
|
27
27
|
* Specify whether the control is disabled
|
|
28
28
|
*/
|
|
@@ -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 { HTMLAttributes } from 'react';
|
|
8
|
+
import { type HTMLAttributes, type OptionHTMLAttributes } from 'react';
|
|
9
9
|
export interface SelectItemProps extends HTMLAttributes<HTMLOptionElement> {
|
|
10
10
|
/**
|
|
11
11
|
* Specify an optional className to be applied to the node
|
|
@@ -26,7 +26,7 @@ export interface SelectItemProps extends HTMLAttributes<HTMLOptionElement> {
|
|
|
26
26
|
/**
|
|
27
27
|
* Specify the value of the <SelectItem>
|
|
28
28
|
*/
|
|
29
|
-
value:
|
|
29
|
+
value: OptionHTMLAttributes<HTMLOptionElement>['value'];
|
|
30
30
|
}
|
|
31
31
|
declare const SelectItem: {
|
|
32
32
|
({ className, value, disabled, hidden, text, ...other }: SelectItemProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -150,8 +150,8 @@ function StructuredListRow(props) {
|
|
|
150
150
|
...other
|
|
151
151
|
} = props;
|
|
152
152
|
const [hasFocusWithin, setHasFocusWithin] = useState(false);
|
|
153
|
-
|
|
154
|
-
const rowId = id ??
|
|
153
|
+
const generatedRowId = useId('grid-input');
|
|
154
|
+
const rowId = id ?? generatedRowId;
|
|
155
155
|
const selectedRow = React.useContext(GridSelectedRowStateContext);
|
|
156
156
|
const setSelectedRow = React.useContext(GridSelectedRowDispatchContext);
|
|
157
157
|
const prefix = usePrefix();
|
|
@@ -848,8 +848,8 @@ const Tab = /*#__PURE__*/forwardRef(({
|
|
|
848
848
|
if (tabRef.current && tabRef.current.parentElement) {
|
|
849
849
|
// determine number of tabs, excluding disabled
|
|
850
850
|
const tabCount = Array.from(tabRef.current.parentElement.childNodes).filter(node => {
|
|
851
|
-
|
|
852
|
-
return
|
|
851
|
+
if (!(node instanceof HTMLElement)) return false;
|
|
852
|
+
return node.classList.contains(`${prefix}--tabs__nav-link`) && !node.classList.contains(`${prefix}--tabs__nav-item--disabled`);
|
|
853
853
|
}).length;
|
|
854
854
|
|
|
855
855
|
// if not removing last tab focus on next tab
|
|
@@ -859,7 +859,10 @@ const Tab = /*#__PURE__*/forwardRef(({
|
|
|
859
859
|
// if removing last tab focus on previous tab
|
|
860
860
|
else {
|
|
861
861
|
const prevTabIndex = (tabCount - 2) * 2;
|
|
862
|
-
tabRef.current.parentElement.childNodes[prevTabIndex]
|
|
862
|
+
const previousTab = tabRef.current.parentElement.childNodes[prevTabIndex];
|
|
863
|
+
if (previousTab instanceof HTMLElement) {
|
|
864
|
+
previousTab.focus();
|
|
865
|
+
}
|
|
863
866
|
}
|
|
864
867
|
}
|
|
865
868
|
};
|
|
@@ -1160,7 +1163,9 @@ function TabPanels({
|
|
|
1160
1163
|
// set max height to TabList
|
|
1161
1164
|
const heights = refs.current.map(ref => ref?.offsetHeight || 0);
|
|
1162
1165
|
const max = Math.max(...heights);
|
|
1163
|
-
tabContainer
|
|
1166
|
+
if (tabContainer instanceof HTMLElement) {
|
|
1167
|
+
tabContainer.style.height = max + 'px';
|
|
1168
|
+
}
|
|
1164
1169
|
|
|
1165
1170
|
// re-hide hidden Tab Panels
|
|
1166
1171
|
refs.current.forEach((ref, index) => {
|
|
@@ -45,8 +45,8 @@ const DismissibleTag = /*#__PURE__*/forwardRef(({
|
|
|
45
45
|
}, forwardRef) => {
|
|
46
46
|
const prefix = usePrefix();
|
|
47
47
|
const tagLabelRef = useRef(null);
|
|
48
|
-
|
|
49
|
-
const tagId = id
|
|
48
|
+
const generatedTagId = useId();
|
|
49
|
+
const tagId = id ?? `tag-${generatedTagId}`;
|
|
50
50
|
const tagClasses = cx(`${prefix}--tag--filter`, className);
|
|
51
51
|
const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
|
|
52
52
|
useIsomorphicEffect(() => {
|
|
@@ -45,8 +45,8 @@ const OperationalTag = /*#__PURE__*/forwardRef(({
|
|
|
45
45
|
}, forwardRef) => {
|
|
46
46
|
const prefix = usePrefix();
|
|
47
47
|
const tagRef = useRef(null);
|
|
48
|
-
|
|
49
|
-
const tagId = id
|
|
48
|
+
const generatedTagId = useId();
|
|
49
|
+
const tagId = id ?? `tag-${generatedTagId}`;
|
|
50
50
|
const tagClasses = cx(`${prefix}--tag--operational`, className);
|
|
51
51
|
const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
|
|
52
52
|
useIsomorphicEffect(() => {
|
|
@@ -37,8 +37,8 @@ const SelectableTag = /*#__PURE__*/forwardRef(({
|
|
|
37
37
|
}, forwardRef) => {
|
|
38
38
|
const prefix = usePrefix();
|
|
39
39
|
const tagRef = useRef(null);
|
|
40
|
-
|
|
41
|
-
const tagId = id
|
|
40
|
+
const generatedTagId = useId();
|
|
41
|
+
const tagId = id ?? `tag-${generatedTagId}`;
|
|
42
42
|
const [selectedTag, setSelectedTag] = useControllableState({
|
|
43
43
|
value: selected,
|
|
44
44
|
onChange: onChange,
|
package/es/components/Tag/Tag.js
CHANGED
|
@@ -74,8 +74,8 @@ const TagBase = /*#__PURE__*/React.forwardRef(({
|
|
|
74
74
|
console.warn('The `onClose` prop for Tag has been deprecated and will be removed in the next major version. Use DismissibleTag instead.');
|
|
75
75
|
}
|
|
76
76
|
const ref = useMergedRefs([forwardRef, tagRef]);
|
|
77
|
-
|
|
78
|
-
const tagId = id
|
|
77
|
+
const generatedTagId = useId();
|
|
78
|
+
const tagId = id ?? `tag-${generatedTagId}`;
|
|
79
79
|
const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
|
|
80
80
|
useIsomorphicEffect(() => {
|
|
81
81
|
const newElement = tagRef.current?.getElementsByClassName(`${prefix}--tag__label`)[0];
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
import React, { type ReactNode } from 'react';
|
|
8
8
|
export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
9
9
|
/**
|
|
10
|
-
* Provide a custom className that is applied
|
|
11
|
-
* `<textarea>` node
|
|
10
|
+
* Provide a custom className that is applied to the wrapper node
|
|
12
11
|
*/
|
|
13
12
|
className?: string;
|
|
14
13
|
/**
|
|
@@ -38,7 +38,7 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
38
38
|
onKeyDown = noopFn,
|
|
39
39
|
invalid = false,
|
|
40
40
|
invalidText = '',
|
|
41
|
-
helperText
|
|
41
|
+
helperText,
|
|
42
42
|
light,
|
|
43
43
|
placeholder = '',
|
|
44
44
|
enableCounter = false,
|
|
@@ -239,7 +239,7 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
239
239
|
ariaDescribedBy = warnId;
|
|
240
240
|
} else {
|
|
241
241
|
const ids = [];
|
|
242
|
-
if (!isFluid &&
|
|
242
|
+
if (!isFluid && hasHelper && helperId) ids.push(helperId);
|
|
243
243
|
if (counterDescriptionId) ids.push(counterDescriptionId);
|
|
244
244
|
ariaDescribedBy = ids.length > 0 ? ids.join(' ') : undefined;
|
|
245
245
|
}
|
|
@@ -278,7 +278,7 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
278
278
|
}, [ariaAnnouncement, prevAnnouncement, counterMode]);
|
|
279
279
|
const input = /*#__PURE__*/React.createElement("textarea", _extends({}, other, textareaProps, {
|
|
280
280
|
placeholder: placeholder,
|
|
281
|
-
"aria-readonly":
|
|
281
|
+
"aria-readonly": other.readOnly,
|
|
282
282
|
className: textareaClasses,
|
|
283
283
|
"aria-invalid": invalid,
|
|
284
284
|
"aria-describedby": ariaDescribedBy,
|
|
@@ -324,8 +324,7 @@ const TextArea = frFn((props, forwardRef) => {
|
|
|
324
324
|
TextArea.displayName = 'TextArea';
|
|
325
325
|
TextArea.propTypes = {
|
|
326
326
|
/**
|
|
327
|
-
* Provide a custom className that is applied
|
|
328
|
-
* `<textarea>` node
|
|
327
|
+
* Provide a custom className that is applied to the wrapper node
|
|
329
328
|
*/
|
|
330
329
|
className: PropTypes.string,
|
|
331
330
|
/**
|