@carbon/react 1.60.2 → 1.61.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 +972 -1013
- package/es/components/ComboBox/ComboBox.js +8 -8
- package/es/components/ComposedModal/ComposedModal.js +4 -2
- package/es/components/DatePicker/DatePicker.js +6 -1
- package/es/components/Dropdown/Dropdown.d.ts +4 -0
- package/es/components/Dropdown/Dropdown.js +53 -8
- package/es/components/Modal/Modal.js +4 -2
- package/es/components/MultiSelect/FilterableMultiSelect.d.ts +20 -14
- package/es/components/MultiSelect/FilterableMultiSelect.js +59 -8
- package/es/components/MultiSelect/MultiSelect.d.ts +7 -38
- package/es/components/MultiSelect/MultiSelect.js +52 -5
- package/es/components/MultiSelect/MultiSelectPropTypes.d.ts +19 -16
- package/es/components/OverflowMenu/OverflowMenu.js +0 -1
- package/es/components/OverflowMenu/next/index.d.ts +4 -0
- package/es/components/OverflowMenu/next/index.js +41 -2
- package/es/components/UIShell/HeaderContainer.d.ts +11 -9
- package/es/components/UIShell/HeaderContainer.js +9 -7
- package/lib/components/ComboBox/ComboBox.js +7 -7
- package/lib/components/ComposedModal/ComposedModal.js +6 -4
- package/lib/components/DatePicker/DatePicker.js +6 -1
- package/lib/components/Dropdown/Dropdown.d.ts +4 -0
- package/lib/components/Dropdown/Dropdown.js +49 -4
- package/lib/components/Modal/Modal.js +6 -4
- package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +20 -14
- package/lib/components/MultiSelect/FilterableMultiSelect.js +56 -5
- package/lib/components/MultiSelect/MultiSelect.d.ts +7 -38
- package/lib/components/MultiSelect/MultiSelect.js +49 -2
- package/lib/components/MultiSelect/MultiSelectPropTypes.d.ts +19 -16
- package/lib/components/OverflowMenu/OverflowMenu.js +0 -1
- package/lib/components/OverflowMenu/next/index.d.ts +4 -0
- package/lib/components/OverflowMenu/next/index.js +40 -1
- package/lib/components/UIShell/HeaderContainer.d.ts +11 -9
- package/lib/components/UIShell/HeaderContainer.js +9 -7
- package/package.json +7 -7
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { type UseComboboxProps, type UseMultipleSelectionProps } from 'downshift';
|
|
8
8
|
import { ReactNode, FunctionComponent, ReactElement } from 'react';
|
|
9
|
-
import { type
|
|
10
|
-
export interface FilterableMultiSelectProps<
|
|
9
|
+
import { type MultiSelectSortingProps } from './MultiSelectPropTypes';
|
|
10
|
+
export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSortingProps<ItemType> {
|
|
11
11
|
/**
|
|
12
12
|
* Specify a label to be read by screen readers on the container node
|
|
13
13
|
* @deprecated
|
|
@@ -15,6 +15,12 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
15
15
|
'aria-label'?: string;
|
|
16
16
|
/** @deprecated */
|
|
17
17
|
ariaLabel?: string;
|
|
18
|
+
/**
|
|
19
|
+
* **Experimental**: Will attempt to automatically align the floating
|
|
20
|
+
* element to avoid collisions with the viewport and being clipped by
|
|
21
|
+
* ancestor elements.
|
|
22
|
+
*/
|
|
23
|
+
autoAlign?: boolean;
|
|
18
24
|
className?: string;
|
|
19
25
|
/**
|
|
20
26
|
* Specify the text that should be read for screen readers that describes total items selected
|
|
@@ -35,14 +41,14 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
35
41
|
/**
|
|
36
42
|
* Additional props passed to Downshift
|
|
37
43
|
*/
|
|
38
|
-
downshiftProps?: UseMultipleSelectionProps<
|
|
44
|
+
downshiftProps?: UseMultipleSelectionProps<ItemType>;
|
|
39
45
|
/**
|
|
40
46
|
* Default sorter is assigned if not provided.
|
|
41
47
|
*/
|
|
42
|
-
filterItems(items: readonly
|
|
48
|
+
filterItems(items: readonly ItemType[], extra: {
|
|
43
49
|
inputValue: string | null;
|
|
44
|
-
itemToString: NonNullable<UseMultipleSelectionProps<
|
|
45
|
-
}):
|
|
50
|
+
itemToString: NonNullable<UseMultipleSelectionProps<ItemType>['itemToString']>;
|
|
51
|
+
}): ItemType[];
|
|
46
52
|
/**
|
|
47
53
|
* Specify whether the title text should be hidden or not
|
|
48
54
|
*/
|
|
@@ -60,7 +66,7 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
60
66
|
* Allow users to pass in arbitrary items from their collection that are
|
|
61
67
|
* pre-selected
|
|
62
68
|
*/
|
|
63
|
-
initialSelectedItems?:
|
|
69
|
+
initialSelectedItems?: ItemType[];
|
|
64
70
|
/**
|
|
65
71
|
* Is the current selection invalid?
|
|
66
72
|
*/
|
|
@@ -73,7 +79,7 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
73
79
|
* Function to render items as custom components instead of strings.
|
|
74
80
|
* Defaults to null and is overridden by a getter
|
|
75
81
|
*/
|
|
76
|
-
itemToElement?: FunctionComponent<
|
|
82
|
+
itemToElement?: FunctionComponent<ItemType>;
|
|
77
83
|
/**
|
|
78
84
|
* Helper function passed to downshift that allows the library to render
|
|
79
85
|
* a given item to a string label.
|
|
@@ -81,12 +87,12 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
81
87
|
* By default, it extracts the `label` field from a given item
|
|
82
88
|
* to serve as the item label in the list.
|
|
83
89
|
*/
|
|
84
|
-
itemToString?(item:
|
|
90
|
+
itemToString?(item: ItemType | null): string;
|
|
85
91
|
/**
|
|
86
92
|
* We try to stay as generic as possible here to allow individuals to pass
|
|
87
93
|
* in a collection of whatever kind of data structure they prefer
|
|
88
94
|
*/
|
|
89
|
-
items:
|
|
95
|
+
items: ItemType[];
|
|
90
96
|
/**
|
|
91
97
|
* @deprecated `true` to use the light version.
|
|
92
98
|
*/
|
|
@@ -102,13 +108,13 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
102
108
|
* consuming component what kind of internal state changes are occurring.
|
|
103
109
|
*/
|
|
104
110
|
onChange?(changes: {
|
|
105
|
-
selectedItems:
|
|
111
|
+
selectedItems: ItemType[];
|
|
106
112
|
}): void;
|
|
107
113
|
/**
|
|
108
114
|
* A utility for this controlled component
|
|
109
115
|
* to communicate to the currently typed input.
|
|
110
116
|
*/
|
|
111
|
-
onInputValueChange?: UseComboboxProps<
|
|
117
|
+
onInputValueChange?: UseComboboxProps<ItemType>['onInputValueChange'];
|
|
112
118
|
/**
|
|
113
119
|
* `onMenuChange` is a utility for this controlled component to communicate to a
|
|
114
120
|
* consuming component that the menu was opened(`true`)/closed(`false`).
|
|
@@ -133,7 +139,7 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
133
139
|
/**
|
|
134
140
|
* For full control of the selected items
|
|
135
141
|
*/
|
|
136
|
-
selectedItems?:
|
|
142
|
+
selectedItems?: ItemType[];
|
|
137
143
|
/**
|
|
138
144
|
* Specify the size of the ListBox.
|
|
139
145
|
* Currently, supports either `sm`, `md` or `lg` as an option.
|
|
@@ -167,7 +173,7 @@ export interface FilterableMultiSelectProps<Item extends ItemBase> extends Sorti
|
|
|
167
173
|
warnText?: ReactNode;
|
|
168
174
|
}
|
|
169
175
|
declare const FilterableMultiSelect: {
|
|
170
|
-
<
|
|
176
|
+
<ItemType>(props: FilterableMultiSelectProps<ItemType>): ReactElement;
|
|
171
177
|
propTypes?: any;
|
|
172
178
|
contextTypes?: any;
|
|
173
179
|
defaultProps?: any;
|
|
@@ -28,6 +28,7 @@ var usePrefix = require('../../internal/usePrefix.js');
|
|
|
28
28
|
require('../FluidForm/FluidForm.js');
|
|
29
29
|
var FormContext = require('../FluidForm/FormContext.js');
|
|
30
30
|
var Selection = require('../../internal/Selection.js');
|
|
31
|
+
var react = require('@floating-ui/react');
|
|
31
32
|
var match = require('../../internal/keyboard/match.js');
|
|
32
33
|
var ListBoxSelection = require('../ListBox/next/ListBoxSelection.js');
|
|
33
34
|
var ListBoxTrigger = require('../ListBox/next/ListBoxTrigger.js');
|
|
@@ -65,6 +66,7 @@ const {
|
|
|
65
66
|
} = Downshift.useMultipleSelection.stateChangeTypes;
|
|
66
67
|
const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(function FilterableMultiSelect(_ref, ref) {
|
|
67
68
|
let {
|
|
69
|
+
autoAlign = false,
|
|
68
70
|
className: containerClassName,
|
|
69
71
|
clearSelectionDescription = 'Total items selected: ',
|
|
70
72
|
clearSelectionText = 'To clear selection, press Delete or Backspace',
|
|
@@ -121,6 +123,42 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
|
|
|
121
123
|
onChange,
|
|
122
124
|
selectedItems: selected
|
|
123
125
|
});
|
|
126
|
+
const {
|
|
127
|
+
refs,
|
|
128
|
+
floatingStyles,
|
|
129
|
+
middlewareData
|
|
130
|
+
} = react.useFloating(autoAlign ? {
|
|
131
|
+
placement: direction,
|
|
132
|
+
// The floating element is positioned relative to its nearest
|
|
133
|
+
// containing block (usually the viewport). It will in many cases also
|
|
134
|
+
// “break” the floating element out of a clipping ancestor.
|
|
135
|
+
// https://floating-ui.com/docs/misc#clipping
|
|
136
|
+
strategy: 'fixed',
|
|
137
|
+
// Middleware order matters, arrow should be last
|
|
138
|
+
middleware: [react.flip({
|
|
139
|
+
crossAxis: false
|
|
140
|
+
}), react.size({
|
|
141
|
+
apply(_ref2) {
|
|
142
|
+
let {
|
|
143
|
+
rects,
|
|
144
|
+
elements
|
|
145
|
+
} = _ref2;
|
|
146
|
+
Object.assign(elements.floating.style, {
|
|
147
|
+
width: `${rects.reference.width}px`
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
})],
|
|
151
|
+
whileElementsMounted: react.autoUpdate
|
|
152
|
+
} : {});
|
|
153
|
+
React.useLayoutEffect(() => {
|
|
154
|
+
if (autoAlign) {
|
|
155
|
+
Object.keys(floatingStyles).forEach(style => {
|
|
156
|
+
if (refs.floating.current) {
|
|
157
|
+
refs.floating.current.style[style] = floatingStyles[style];
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}, [autoAlign, floatingStyles, refs.floating, middlewareData, open]);
|
|
124
162
|
const textInput = React.useRef(null);
|
|
125
163
|
const filterableMultiSelectInstanceId = useId.useId();
|
|
126
164
|
const prefix = usePrefix.usePrefix();
|
|
@@ -128,6 +166,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
|
|
|
128
166
|
setIsOpen(open);
|
|
129
167
|
setPrevOpen(open);
|
|
130
168
|
}
|
|
169
|
+
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
131
171
|
const sortedItems = sortItems(filterItems(items, {
|
|
132
172
|
itemToString: itemToString$1,
|
|
133
173
|
inputValue
|
|
@@ -243,8 +283,6 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
|
|
|
243
283
|
return changes;
|
|
244
284
|
case InputBlur:
|
|
245
285
|
case InputKeyDownEscape:
|
|
246
|
-
setInputFocused(false);
|
|
247
|
-
setInputValue('');
|
|
248
286
|
setIsOpen(false);
|
|
249
287
|
return changes;
|
|
250
288
|
case FunctionToggleMenu:
|
|
@@ -428,7 +466,11 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
|
|
|
428
466
|
$input.setSelectionRange($value.length, $value.length);
|
|
429
467
|
}
|
|
430
468
|
},
|
|
431
|
-
onFocus: () => setInputFocused(true)
|
|
469
|
+
onFocus: () => setInputFocused(true),
|
|
470
|
+
onBlur: () => {
|
|
471
|
+
!isOpen && setInputFocused(false);
|
|
472
|
+
setInputValue('');
|
|
473
|
+
}
|
|
432
474
|
}));
|
|
433
475
|
const menuProps = getMenuProps({}, {
|
|
434
476
|
suppressRefError: true
|
|
@@ -465,7 +507,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
|
|
|
465
507
|
isOpen: isOpen,
|
|
466
508
|
size: size
|
|
467
509
|
}, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
468
|
-
className: `${prefix}--list-box__field
|
|
510
|
+
className: `${prefix}--list-box__field`,
|
|
511
|
+
ref: refs.setReference
|
|
469
512
|
}, controlledSelectedItems.length > 0 &&
|
|
470
513
|
/*#__PURE__*/
|
|
471
514
|
// @ts-expect-error: It is expecting a non-required prop called: "onClearSelection"
|
|
@@ -506,7 +549,9 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
|
|
|
506
549
|
// @ts-expect-error
|
|
507
550
|
isOpen: isOpen,
|
|
508
551
|
translateWithId: translateWithId
|
|
509
|
-
}))), normalizedSlug, /*#__PURE__*/React__default["default"].createElement(index["default"].Menu,
|
|
552
|
+
}))), normalizedSlug, /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, _rollupPluginBabelHelpers["extends"]({}, menuProps, {
|
|
553
|
+
ref: refs.setFloating
|
|
554
|
+
}), isOpen ? sortedItems.map((item, index$1) => {
|
|
510
555
|
const isChecked = controlledSelectedItems.filter(selected => isEqual__default["default"](selected, item)).length > 0;
|
|
511
556
|
const itemProps = getItemProps({
|
|
512
557
|
item,
|
|
@@ -554,6 +599,12 @@ FilterableMultiSelect.propTypes = {
|
|
|
554
599
|
* Specify a label to be read by screen readers on the container note.
|
|
555
600
|
*/
|
|
556
601
|
ariaLabel: deprecate["default"](PropTypes__default["default"].string, 'ariaLabel / aria-label props are no longer required for FilterableMultiSelect'),
|
|
602
|
+
/**
|
|
603
|
+
* **Experimental**: Will attempt to automatically align the floating
|
|
604
|
+
* element to avoid collisions with the viewport and being clipped by
|
|
605
|
+
* ancestor elements.
|
|
606
|
+
*/
|
|
607
|
+
autoAlign: PropTypes__default["default"].bool,
|
|
557
608
|
/**
|
|
558
609
|
* Specify the text that should be read for screen readers that describes total items selected
|
|
559
610
|
*/
|
|
@@ -7,50 +7,19 @@
|
|
|
7
7
|
import { UseSelectProps } from 'downshift';
|
|
8
8
|
import React, { ReactNode } from 'react';
|
|
9
9
|
import { ListBoxSize, ListBoxType } from '../ListBox';
|
|
10
|
+
import { MultiSelectSortingProps } from './MultiSelectPropTypes';
|
|
10
11
|
import { ListBoxProps } from '../ListBox/ListBox';
|
|
11
12
|
import type { InternationalProps } from '../../types/common';
|
|
12
|
-
interface SharedOptions {
|
|
13
|
-
locale: string;
|
|
14
|
-
}
|
|
15
|
-
interface DownshiftTypedProps<ItemType> {
|
|
16
|
-
itemToString?(item: ItemType): string;
|
|
17
|
-
}
|
|
18
|
-
interface SortItemsOptions<ItemType> extends SharedOptions, DownshiftTypedProps<ItemType> {
|
|
19
|
-
compareItems(item1: ItemType, item2: ItemType, options: SharedOptions): number;
|
|
20
|
-
selectedItems: ItemType[];
|
|
21
|
-
}
|
|
22
|
-
interface MultiSelectSortingProps<ItemType> {
|
|
23
|
-
/**
|
|
24
|
-
* Provide a compare function that is used to determine the ordering of
|
|
25
|
-
* options. See 'sortItems' for more control.
|
|
26
|
-
*/
|
|
27
|
-
compareItems?(item1: ItemType, item2: ItemType, options: SharedOptions): number;
|
|
28
|
-
/**
|
|
29
|
-
* Provide a method that sorts all options in the control. Overriding this
|
|
30
|
-
* prop means that you also have to handle the sort logic for selected versus
|
|
31
|
-
* un-selected items. If you just want to control ordering, consider the
|
|
32
|
-
* `compareItems` prop instead.
|
|
33
|
-
*
|
|
34
|
-
* The return value should be a number whose sign indicates the relative order
|
|
35
|
-
* of the two elements: negative if a is less than b, positive if a is greater
|
|
36
|
-
* than b, and zero if they are equal.
|
|
37
|
-
*
|
|
38
|
-
* sortItems :
|
|
39
|
-
* (items: Array<Item>, {
|
|
40
|
-
* selectedItems: Array<Item>,
|
|
41
|
-
* itemToString: Item => string,
|
|
42
|
-
* compareItems: (itemA: string, itemB: string, {
|
|
43
|
-
* locale: string
|
|
44
|
-
* }) => number,
|
|
45
|
-
* locale: string,
|
|
46
|
-
* }) => Array<Item>
|
|
47
|
-
*/
|
|
48
|
-
sortItems?(items: ReadonlyArray<ItemType>, options: SortItemsOptions<ItemType>): ItemType[];
|
|
49
|
-
}
|
|
50
13
|
interface OnChangeData<ItemType> {
|
|
51
14
|
selectedItems: ItemType[] | null;
|
|
52
15
|
}
|
|
53
16
|
export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<ItemType>, InternationalProps<'close.menu' | 'open.menu' | 'clear.all' | 'clear.selection'> {
|
|
17
|
+
/**
|
|
18
|
+
* **Experimental**: Will attempt to automatically align the floating
|
|
19
|
+
* element to avoid collisions with the viewport and being clipped by
|
|
20
|
+
* ancestor elements.
|
|
21
|
+
*/
|
|
22
|
+
autoAlign?: boolean;
|
|
54
23
|
className?: string;
|
|
55
24
|
/**
|
|
56
25
|
* Specify the text that should be read for screen readers that describes that all items are deleted
|
|
@@ -27,6 +27,7 @@ var usePrefix = require('../../internal/usePrefix.js');
|
|
|
27
27
|
require('../FluidForm/FluidForm.js');
|
|
28
28
|
var FormContext = require('../FluidForm/FormContext.js');
|
|
29
29
|
var noopFn = require('../../internal/noopFn.js');
|
|
30
|
+
var react = require('@floating-ui/react');
|
|
30
31
|
var match = require('../../internal/keyboard/match.js');
|
|
31
32
|
var ListBoxPropTypes = require('../ListBox/ListBoxPropTypes.js');
|
|
32
33
|
var keys = require('../../internal/keyboard/keys.js');
|
|
@@ -68,6 +69,7 @@ const defaultItemToString = item => {
|
|
|
68
69
|
};
|
|
69
70
|
const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) => {
|
|
70
71
|
let {
|
|
72
|
+
autoAlign = false,
|
|
71
73
|
className: containerClassName,
|
|
72
74
|
id,
|
|
73
75
|
items,
|
|
@@ -127,6 +129,42 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
|
|
|
127
129
|
onChange,
|
|
128
130
|
selectedItems: selected
|
|
129
131
|
});
|
|
132
|
+
const {
|
|
133
|
+
refs,
|
|
134
|
+
floatingStyles,
|
|
135
|
+
middlewareData
|
|
136
|
+
} = react.useFloating(autoAlign ? {
|
|
137
|
+
placement: direction,
|
|
138
|
+
// The floating element is positioned relative to its nearest
|
|
139
|
+
// containing block (usually the viewport). It will in many cases also
|
|
140
|
+
// “break” the floating element out of a clipping ancestor.
|
|
141
|
+
// https://floating-ui.com/docs/misc#clipping
|
|
142
|
+
strategy: 'fixed',
|
|
143
|
+
// Middleware order matters, arrow should be last
|
|
144
|
+
middleware: [react.flip({
|
|
145
|
+
crossAxis: false
|
|
146
|
+
}), react.size({
|
|
147
|
+
apply(_ref2) {
|
|
148
|
+
let {
|
|
149
|
+
rects,
|
|
150
|
+
elements
|
|
151
|
+
} = _ref2;
|
|
152
|
+
Object.assign(elements.floating.style, {
|
|
153
|
+
width: `${rects.reference.width}px`
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
})],
|
|
157
|
+
whileElementsMounted: react.autoUpdate
|
|
158
|
+
} : {});
|
|
159
|
+
React.useLayoutEffect(() => {
|
|
160
|
+
if (autoAlign) {
|
|
161
|
+
Object.keys(floatingStyles).forEach(style => {
|
|
162
|
+
if (refs.floating.current) {
|
|
163
|
+
refs.floating.current.style[style] = floatingStyles[style];
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}, [autoAlign, floatingStyles, refs.floating, middlewareData, open]);
|
|
130
168
|
|
|
131
169
|
// Filter out items with an object having undefined values
|
|
132
170
|
const filteredItems = React.useMemo(() => {
|
|
@@ -393,7 +431,8 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
|
|
|
393
431
|
}), showWarning && /*#__PURE__*/React__default["default"].createElement(iconsReact.WarningAltFilled, {
|
|
394
432
|
className: `${prefix}--list-box__invalid-icon ${prefix}--list-box__invalid-icon--warning`
|
|
395
433
|
}), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
396
|
-
className: multiSelectFieldWrapperClasses
|
|
434
|
+
className: multiSelectFieldWrapperClasses,
|
|
435
|
+
ref: refs.setReference
|
|
397
436
|
}, selectedItems.length > 0 && /*#__PURE__*/React__default["default"].createElement(index["default"].Selection, {
|
|
398
437
|
readOnly: readOnly,
|
|
399
438
|
clearSelection: !disabled && !readOnly ? clearSelection : noopFn.noopFn,
|
|
@@ -416,7 +455,9 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
|
|
|
416
455
|
}, label), /*#__PURE__*/React__default["default"].createElement(index["default"].MenuIcon, {
|
|
417
456
|
isOpen: isOpen,
|
|
418
457
|
translateWithId: translateWithId
|
|
419
|
-
})), normalizedSlug), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, getMenuProps(
|
|
458
|
+
})), normalizedSlug), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, getMenuProps({
|
|
459
|
+
ref: refs.setFloating
|
|
460
|
+
}), isOpen &&
|
|
420
461
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
421
462
|
sortItems(filteredItems, sortOptions).map((item, index$1) => {
|
|
422
463
|
const isChecked = selectedItems.filter(selected => isEqual__default["default"](selected, item)).length > 0;
|
|
@@ -455,6 +496,12 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
|
|
|
455
496
|
MultiSelect.displayName = 'MultiSelect';
|
|
456
497
|
MultiSelect.propTypes = {
|
|
457
498
|
...MultiSelectPropTypes.sortingPropTypes,
|
|
499
|
+
/**
|
|
500
|
+
* **Experimental**: Will attempt to automatically align the floating
|
|
501
|
+
* element to avoid collisions with the viewport and being clipped by
|
|
502
|
+
* ancestor elements.
|
|
503
|
+
*/
|
|
504
|
+
autoAlign: PropTypes__default["default"].bool,
|
|
458
505
|
/**
|
|
459
506
|
* Provide a custom class name to be added to the outermost node in the
|
|
460
507
|
* component
|
|
@@ -34,29 +34,32 @@ export declare const sortingPropTypes: {
|
|
|
34
34
|
*/
|
|
35
35
|
sortItems: PropTypes.Requireable<(...args: any[]) => any>;
|
|
36
36
|
};
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
interface DownshiftTypedProps<ItemType> {
|
|
38
|
+
itemToString?(item: ItemType): string;
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
interface SharedOptions {
|
|
41
|
+
locale: string;
|
|
42
|
+
}
|
|
43
|
+
export interface SortItemsOptions<ItemType> extends SharedOptions, DownshiftTypedProps<ItemType> {
|
|
44
|
+
compareItems(item1: ItemType, item2: ItemType, options: SharedOptions): number;
|
|
45
|
+
selectedItems: ItemType[];
|
|
46
|
+
}
|
|
47
|
+
export interface MultiSelectSortingProps<ItemType> {
|
|
41
48
|
/**
|
|
42
|
-
* Provide a compare function that is used
|
|
43
|
-
*
|
|
49
|
+
* Provide a compare function that is used to determine the ordering of
|
|
50
|
+
* options. See 'sortItems' for more control.
|
|
44
51
|
*/
|
|
45
|
-
compareItems(
|
|
46
|
-
locale: string;
|
|
47
|
-
}): number;
|
|
52
|
+
compareItems?(item1: ItemType, item2: ItemType, options: SharedOptions): number;
|
|
48
53
|
/**
|
|
49
54
|
* Provide a method that sorts all options in the control. Overriding this
|
|
50
55
|
* prop means that you also have to handle the sort logic for selected versus
|
|
51
56
|
* un-selected items. If you just want to control ordering, consider the
|
|
52
57
|
* `compareItems` prop instead.
|
|
58
|
+
*
|
|
59
|
+
* The return value should be a number whose sign indicates the relative order
|
|
60
|
+
* of the two elements: negative if a is less than b, positive if a is greater
|
|
61
|
+
* than b, and zero if they are equal.
|
|
53
62
|
*/
|
|
54
|
-
sortItems(items:
|
|
55
|
-
selectedItems: Item[];
|
|
56
|
-
itemToString(item: Item): string;
|
|
57
|
-
compareItems(itemA: string, itemB: string, ctx: {
|
|
58
|
-
locale: string;
|
|
59
|
-
}): number;
|
|
60
|
-
locale: string;
|
|
61
|
-
}): Item[];
|
|
63
|
+
sortItems?(items: ReadonlyArray<ItemType>, options: SortItemsOptions<ItemType>): ItemType[];
|
|
62
64
|
}
|
|
65
|
+
export {};
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React, { type ComponentType, type FunctionComponent } from 'react';
|
|
8
8
|
interface OverflowMenuProps {
|
|
9
|
+
/**
|
|
10
|
+
* **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
|
|
11
|
+
*/
|
|
12
|
+
autoAlign?: boolean;
|
|
9
13
|
/**
|
|
10
14
|
* A collection of MenuItems to be rendered within this OverflowMenu.
|
|
11
15
|
*/
|
|
@@ -14,9 +14,11 @@ var React = require('react');
|
|
|
14
14
|
var PropTypes = require('prop-types');
|
|
15
15
|
var cx = require('classnames');
|
|
16
16
|
var iconsReact = require('@carbon/icons-react');
|
|
17
|
+
var react = require('@floating-ui/react');
|
|
17
18
|
var index = require('../../IconButton/index.js');
|
|
18
19
|
var Menu = require('../../Menu/Menu.js');
|
|
19
20
|
require('../../Menu/MenuItem.js');
|
|
21
|
+
var mergeRefs = require('../../../tools/mergeRefs.js');
|
|
20
22
|
var useId = require('../../../internal/useId.js');
|
|
21
23
|
var usePrefix = require('../../../internal/usePrefix.js');
|
|
22
24
|
var useAttachedMenu = require('../../../internal/useAttachedMenu.js');
|
|
@@ -30,6 +32,7 @@ var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
|
|
|
30
32
|
const defaultSize = 'md';
|
|
31
33
|
const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function OverflowMenu(_ref, forwardRef) {
|
|
32
34
|
let {
|
|
35
|
+
autoAlign = false,
|
|
33
36
|
children,
|
|
34
37
|
className,
|
|
35
38
|
label = 'Options',
|
|
@@ -39,6 +42,26 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
|
|
|
39
42
|
tooltipAlignment,
|
|
40
43
|
...rest
|
|
41
44
|
} = _ref;
|
|
45
|
+
const {
|
|
46
|
+
refs,
|
|
47
|
+
floatingStyles,
|
|
48
|
+
placement,
|
|
49
|
+
middlewareData
|
|
50
|
+
} = react.useFloating(autoAlign ? {
|
|
51
|
+
placement: menuAlignment,
|
|
52
|
+
// The floating element is positioned relative to its nearest
|
|
53
|
+
// containing block (usually the viewport). It will in many cases also
|
|
54
|
+
// “break” the floating element out of a clipping ancestor.
|
|
55
|
+
// https://floating-ui.com/docs/misc#clipping
|
|
56
|
+
strategy: 'fixed',
|
|
57
|
+
// Middleware order matters, arrow should be last
|
|
58
|
+
middleware: [react.flip({
|
|
59
|
+
fallbackAxisSideDirection: 'start',
|
|
60
|
+
fallbackPlacements: ['top-start', 'top-end', 'bottom-start', 'bottom-end']
|
|
61
|
+
})],
|
|
62
|
+
whileElementsMounted: react.autoUpdate
|
|
63
|
+
} : {} // When autoAlign is turned off, floating-ui will not be used
|
|
64
|
+
);
|
|
42
65
|
const id = useId.useId('overflowmenu');
|
|
43
66
|
const prefix = usePrefix.usePrefix();
|
|
44
67
|
const triggerRef = React.useRef(null);
|
|
@@ -50,6 +73,15 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
|
|
|
50
73
|
handleMousedown,
|
|
51
74
|
handleClose
|
|
52
75
|
} = useAttachedMenu.useAttachedMenu(triggerRef);
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
if (autoAlign) {
|
|
78
|
+
Object.keys(floatingStyles).forEach(style => {
|
|
79
|
+
if (refs.floating.current) {
|
|
80
|
+
refs.floating.current.style[style] = floatingStyles[style];
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}, [floatingStyles, autoAlign, refs.floating, open, placement, middlewareData]);
|
|
53
85
|
function handleTriggerClick() {
|
|
54
86
|
if (triggerRef.current) {
|
|
55
87
|
hookOnClick();
|
|
@@ -60,6 +92,7 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
|
|
|
60
92
|
const triggerClasses = cx__default["default"](`${prefix}--overflow-menu`, {
|
|
61
93
|
[`${prefix}--overflow-menu--open`]: open
|
|
62
94
|
}, size !== defaultSize && `${prefix}--overflow-menu--${size}`);
|
|
95
|
+
const floatingRef = mergeRefs["default"](triggerRef, refs.setReference);
|
|
63
96
|
return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
64
97
|
className: containerClasses,
|
|
65
98
|
"aria-owns": open ? id : undefined,
|
|
@@ -71,17 +104,19 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
|
|
|
71
104
|
className: triggerClasses,
|
|
72
105
|
onClick: handleTriggerClick,
|
|
73
106
|
onMouseDown: handleMousedown,
|
|
74
|
-
ref:
|
|
107
|
+
ref: floatingRef,
|
|
75
108
|
label: label,
|
|
76
109
|
align: tooltipAlignment
|
|
77
110
|
}, /*#__PURE__*/React__default["default"].createElement(IconElement, {
|
|
78
111
|
className: `${prefix}--overflow-menu__icon`
|
|
79
112
|
})), /*#__PURE__*/React__default["default"].createElement(Menu.Menu, {
|
|
80
113
|
containerRef: triggerRef,
|
|
114
|
+
ref: refs.setFloating,
|
|
81
115
|
menuAlignment: menuAlignment,
|
|
82
116
|
className: menuClasses,
|
|
83
117
|
id: id,
|
|
84
118
|
size: size,
|
|
119
|
+
legacyAutoalign: !autoAlign,
|
|
85
120
|
open: open,
|
|
86
121
|
onClose: handleClose,
|
|
87
122
|
x: x,
|
|
@@ -90,6 +125,10 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
|
|
|
90
125
|
}, children));
|
|
91
126
|
});
|
|
92
127
|
OverflowMenu.propTypes = {
|
|
128
|
+
/**
|
|
129
|
+
* **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
|
|
130
|
+
*/
|
|
131
|
+
autoAlign: PropTypes__default["default"].bool,
|
|
93
132
|
/**
|
|
94
133
|
* A collection of MenuItems to be rendered within this OverflowMenu.
|
|
95
134
|
*/
|
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import React from 'react';
|
|
9
|
-
interface HeaderContainerRenderProps {
|
|
9
|
+
export interface HeaderContainerRenderProps {
|
|
10
10
|
isSideNavExpanded: boolean;
|
|
11
11
|
onClickSideNavExpand: () => void;
|
|
12
12
|
}
|
|
13
|
-
export
|
|
13
|
+
export type HeaderContainerProps<P extends HeaderContainerRenderProps> = {
|
|
14
14
|
isSideNavExpanded?: boolean;
|
|
15
|
-
render: React.ComponentType<
|
|
16
|
-
}
|
|
17
|
-
|
|
15
|
+
render: React.ComponentType<P>;
|
|
16
|
+
} & {
|
|
17
|
+
[K in keyof Omit<P, keyof HeaderContainerRenderProps>]: P[K];
|
|
18
|
+
};
|
|
19
|
+
declare function HeaderContainer<P extends HeaderContainerRenderProps>({ render: Children, isSideNavExpanded, ...rest }: HeaderContainerProps<P>): import("react/jsx-runtime").JSX.Element;
|
|
18
20
|
declare namespace HeaderContainer {
|
|
19
21
|
var propTypes: {
|
|
20
22
|
/**
|
|
@@ -22,10 +24,10 @@ declare namespace HeaderContainer {
|
|
|
22
24
|
*/
|
|
23
25
|
isSideNavExpanded: PropTypes.Requireable<boolean>;
|
|
24
26
|
/**
|
|
25
|
-
* A function or component that is
|
|
26
|
-
* properties
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* A function or a component that is invoked with `isSideNavExpanded` and `onClickSideNavExpand`.
|
|
28
|
+
* The function or component can then use those properties to within the components it
|
|
29
|
+
* returns, such as with the HeaderMenuButton and SideNav components. Additional props will also be passed
|
|
30
|
+
* into this component for convenience.
|
|
29
31
|
*/
|
|
30
32
|
render: PropTypes.Validator<NonNullable<PropTypes.ReactComponentLike>>;
|
|
31
33
|
};
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
11
11
|
|
|
12
|
+
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
|
|
12
13
|
var PropTypes = require('prop-types');
|
|
13
14
|
var React = require('react');
|
|
14
15
|
var useEvent = require('../../internal/useEvent.js');
|
|
@@ -23,7 +24,8 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
|
23
24
|
function HeaderContainer(_ref) {
|
|
24
25
|
let {
|
|
25
26
|
render: Children,
|
|
26
|
-
isSideNavExpanded = false
|
|
27
|
+
isSideNavExpanded = false,
|
|
28
|
+
...rest
|
|
27
29
|
} = _ref;
|
|
28
30
|
//state for expandable sidenav
|
|
29
31
|
const [isSideNavExpandedState, setIsSideNavExpandedState] = React.useState(isSideNavExpanded);
|
|
@@ -35,10 +37,10 @@ function HeaderContainer(_ref) {
|
|
|
35
37
|
const handleHeaderMenuButtonClick = React.useCallback(() => {
|
|
36
38
|
setIsSideNavExpandedState(prevIsSideNavExpanded => !prevIsSideNavExpanded);
|
|
37
39
|
}, [setIsSideNavExpandedState]);
|
|
38
|
-
return /*#__PURE__*/React__default["default"].createElement(Children, {
|
|
40
|
+
return /*#__PURE__*/React__default["default"].createElement(Children, _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
39
41
|
isSideNavExpanded: isSideNavExpandedState,
|
|
40
42
|
onClickSideNavExpand: handleHeaderMenuButtonClick
|
|
41
|
-
});
|
|
43
|
+
}));
|
|
42
44
|
}
|
|
43
45
|
HeaderContainer.propTypes = {
|
|
44
46
|
/**
|
|
@@ -46,10 +48,10 @@ HeaderContainer.propTypes = {
|
|
|
46
48
|
*/
|
|
47
49
|
isSideNavExpanded: PropTypes__default["default"].bool,
|
|
48
50
|
/**
|
|
49
|
-
* A function or component that is
|
|
50
|
-
* properties
|
|
51
|
-
*
|
|
52
|
-
*
|
|
51
|
+
* A function or a component that is invoked with `isSideNavExpanded` and `onClickSideNavExpand`.
|
|
52
|
+
* The function or component can then use those properties to within the components it
|
|
53
|
+
* returns, such as with the HeaderMenuButton and SideNav components. Additional props will also be passed
|
|
54
|
+
* into this component for convenience.
|
|
53
55
|
*/
|
|
54
56
|
render: PropTypes__default["default"].elementType.isRequired
|
|
55
57
|
};
|