@carbon/react 1.101.0-rc.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 +1009 -974
- package/es/components/Accordion/AccordionItem.js +8 -6
- package/es/components/ComboBox/ComboBox.js +10 -5
- 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 +5 -4
- 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/ListBox/test-helpers.d.ts +71 -0
- 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 +5 -4
- package/es/components/MultiSelect/MultiSelect.js +6 -9
- 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/NumberInput/NumberInput.js +1 -1
- 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 +4 -4
- package/es/components/ProgressIndicator/ProgressIndicator.d.ts +1 -1
- package/es/components/ProgressIndicator/ProgressIndicator.js +1 -1
- package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
- package/es/components/RadioButtonGroup/RadioButtonGroup.js +8 -11
- package/es/components/Search/Search.d.ts +1 -1
- 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 +2 -2
- 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 +2 -3
- 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 +10 -5
- 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 +5 -4
- 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/ListBox/test-helpers.d.ts +71 -0
- 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 +5 -4
- package/lib/components/MultiSelect/MultiSelect.js +6 -9
- 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/NumberInput/NumberInput.js +1 -1
- 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 +4 -4
- package/lib/components/ProgressIndicator/ProgressIndicator.d.ts +1 -1
- package/lib/components/ProgressIndicator/ProgressIndicator.js +1 -1
- package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
- package/lib/components/RadioButtonGroup/RadioButtonGroup.js +7 -10
- package/lib/components/Search/Search.d.ts +1 -1
- 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 +2 -2
- 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 +2 -3
- 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 +10 -10
- package/telemetry.yml +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
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 '@testing-library/jest-dom/jest-globals';
|
|
8
|
+
export declare const findListBoxNode: () => Element | null;
|
|
9
|
+
export declare const findMenuNode: () => Element | null;
|
|
10
|
+
export declare const findMenuItemNode: (index: number) => Element;
|
|
11
|
+
export declare const findMenuIconNode: () => Element | null;
|
|
12
|
+
export declare const findFieldNode: () => Element | null;
|
|
13
|
+
export declare const findComboboxNode: () => Element | null;
|
|
14
|
+
export declare const findPopupNode: () => Element | null;
|
|
15
|
+
export declare const openMenu: () => Promise<void>;
|
|
16
|
+
export declare const assertMenuOpen: (mockProps: {
|
|
17
|
+
items: unknown[];
|
|
18
|
+
}) => void;
|
|
19
|
+
export declare const assertMenuClosed: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* 'GenericItem' corresponds to an item in a collection that is passed to
|
|
22
|
+
* `MultiSelect` that is in a predictable shape and works with the default
|
|
23
|
+
* `itemToString` function.
|
|
24
|
+
*/
|
|
25
|
+
export declare const generateGenericItem: (index: number) => {
|
|
26
|
+
id: string;
|
|
27
|
+
label: string;
|
|
28
|
+
value: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* 'CustomItem' corresponds to a potentially different item structure that might
|
|
32
|
+
* be passed into `MultiSelect` that we would need to supply a custom
|
|
33
|
+
* `itemToString` method for.
|
|
34
|
+
*/
|
|
35
|
+
export declare const generateCustomItem: (index: number) => {
|
|
36
|
+
field: string;
|
|
37
|
+
value: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Generates an array of values generated by the `generator` function.
|
|
41
|
+
*/
|
|
42
|
+
export declare const generateItems: <T>(amount: number, generator: (index: number) => T) => T[];
|
|
43
|
+
export declare const customItemToString: ({ field, }: {
|
|
44
|
+
field: string;
|
|
45
|
+
value: string;
|
|
46
|
+
}) => string;
|
|
47
|
+
/**
|
|
48
|
+
* This object contains two sets of three items that share the same root
|
|
49
|
+
* word in different portions of the string (beginning, middle, end):
|
|
50
|
+
*
|
|
51
|
+
* - 'struct'
|
|
52
|
+
* - 'port'
|
|
53
|
+
*
|
|
54
|
+
* Separated by a disabled item, these derivative words are helpful when
|
|
55
|
+
* testing fuzzy search functions and components that do substring filtering.
|
|
56
|
+
*/
|
|
57
|
+
export declare const cognateItems: ({
|
|
58
|
+
id: string;
|
|
59
|
+
text: string;
|
|
60
|
+
disabled?: undefined;
|
|
61
|
+
} | {
|
|
62
|
+
id: string;
|
|
63
|
+
text: string;
|
|
64
|
+
disabled: boolean;
|
|
65
|
+
})[];
|
|
66
|
+
/**
|
|
67
|
+
* Flushes microtasks to ensure element position state is settled
|
|
68
|
+
* From https://floating-ui.com/docs/react#testing
|
|
69
|
+
* More context here: https://github.com/floating-ui/react-popper/issues/368#issuecomment-1340413010
|
|
70
|
+
*/
|
|
71
|
+
export declare const waitForPosition: () => Promise<void>;
|
|
@@ -36,7 +36,9 @@ function Loading({
|
|
|
36
36
|
className: loadingClassName
|
|
37
37
|
}), /*#__PURE__*/React.createElement("svg", {
|
|
38
38
|
className: `${prefix}--loading__svg`,
|
|
39
|
-
viewBox: "0 0 100 100"
|
|
39
|
+
viewBox: "0 0 100 100",
|
|
40
|
+
role: "img",
|
|
41
|
+
"aria-label": description
|
|
40
42
|
}, /*#__PURE__*/React.createElement("title", null, description), small ? /*#__PURE__*/React.createElement("circle", {
|
|
41
43
|
className: `${prefix}--loading__background`,
|
|
42
44
|
cx: "50%",
|
|
@@ -84,10 +84,14 @@ const Menu = /*#__PURE__*/forwardRef(function Menu({
|
|
|
84
84
|
}
|
|
85
85
|
function handleOpen() {
|
|
86
86
|
if (menu.current) {
|
|
87
|
-
|
|
87
|
+
const {
|
|
88
|
+
activeElement,
|
|
89
|
+
dir
|
|
90
|
+
} = document;
|
|
91
|
+
focusReturn.current = activeElement instanceof HTMLElement ? activeElement : null;
|
|
88
92
|
if (legacyAutoalign) {
|
|
89
93
|
const pos = calculatePosition();
|
|
90
|
-
if ((
|
|
94
|
+
if ((dir === 'rtl' || direction === 'rtl') && !rest?.id?.includes('MenuButton')) {
|
|
91
95
|
menu.current.style.insetInlineStart = `initial`;
|
|
92
96
|
menu.current.style.insetInlineEnd = `${pos[0]}px`;
|
|
93
97
|
} else {
|
|
@@ -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,15 +614,16 @@ 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);
|
|
624
625
|
} else {
|
|
625
|
-
setIsFocused(evt?.type === 'focus'
|
|
626
|
+
setIsFocused(evt?.type === 'focus');
|
|
626
627
|
}
|
|
627
628
|
};
|
|
628
629
|
const mergedRef = mergeRefs(textInput, inputProp.ref);
|
|
@@ -390,7 +390,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
390
390
|
if (evt.target.classList.contains(`${prefix}--tag__close-icon`)) {
|
|
391
391
|
setIsFocused(false);
|
|
392
392
|
} else {
|
|
393
|
-
setIsFocused(evt.type === 'focus'
|
|
393
|
+
setIsFocused(evt.type === 'focus');
|
|
394
394
|
}
|
|
395
395
|
};
|
|
396
396
|
const readOnlyEventHandlers = readOnly ? {
|
|
@@ -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;
|
|
@@ -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`, {
|
|
@@ -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
|
*/
|
|
@@ -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,
|
|
@@ -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 = value || defaultValue
|
|
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
|
*/
|
|
@@ -34,7 +34,7 @@ const Select = /*#__PURE__*/forwardRef(({
|
|
|
34
34
|
hideLabel = false,
|
|
35
35
|
invalid = false,
|
|
36
36
|
invalidText = '',
|
|
37
|
-
helperText
|
|
37
|
+
helperText,
|
|
38
38
|
light = false,
|
|
39
39
|
readOnly,
|
|
40
40
|
size,
|
|
@@ -107,7 +107,7 @@ const Select = /*#__PURE__*/forwardRef(({
|
|
|
107
107
|
ariaProps['aria-describedby'] = helper ? normalizedProps.helperId : undefined;
|
|
108
108
|
}
|
|
109
109
|
const handleFocus = evt => {
|
|
110
|
-
setIsFocused(evt.type === 'focus'
|
|
110
|
+
setIsFocused(evt.type === 'focus');
|
|
111
111
|
};
|
|
112
112
|
const handleChange = evt => {
|
|
113
113
|
const selectedOption = evt?.target?.options[evt.target.selectedIndex];
|
|
@@ -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();
|