@carbon/react 1.71.0 → 1.72.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 +833 -858
- package/es/components/ComboBox/ComboBox.d.ts +5 -0
- package/es/components/ComboBox/ComboBox.js +17 -12
- package/es/components/MultiSelect/FilterableMultiSelect.d.ts +5 -0
- package/es/components/MultiSelect/FilterableMultiSelect.js +14 -9
- package/es/components/MultiSelect/MultiSelect.d.ts +5 -0
- package/es/components/MultiSelect/MultiSelect.js +15 -10
- package/es/components/OverflowMenu/OverflowMenu.d.ts +1 -1
- package/es/components/OverflowMenu/OverflowMenu.js +7 -17
- package/es/components/Pagination/Pagination.js +1 -1
- package/es/components/Popover/index.d.ts +5 -0
- package/es/components/Popover/index.js +12 -1
- package/es/components/Select/Select.d.ts +6 -1
- package/es/components/Select/Select.js +15 -10
- package/es/components/UIShell/Switcher.js +7 -3
- package/es/internal/wrapFocus.js +1 -2
- package/lib/components/ComboBox/ComboBox.d.ts +5 -0
- package/lib/components/ComboBox/ComboBox.js +17 -12
- package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +5 -0
- package/lib/components/MultiSelect/FilterableMultiSelect.js +14 -9
- package/lib/components/MultiSelect/MultiSelect.d.ts +5 -0
- package/lib/components/MultiSelect/MultiSelect.js +15 -10
- package/lib/components/OverflowMenu/OverflowMenu.d.ts +1 -1
- package/lib/components/OverflowMenu/OverflowMenu.js +9 -19
- package/lib/components/Pagination/Pagination.js +1 -1
- package/lib/components/Popover/index.d.ts +5 -0
- package/lib/components/Popover/index.js +12 -1
- package/lib/components/Select/Select.d.ts +6 -1
- package/lib/components/Select/Select.js +15 -10
- package/lib/components/UIShell/Switcher.js +7 -3
- package/lib/internal/wrapFocus.js +1 -6
- package/package.json +3 -4
|
@@ -48,6 +48,10 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
|
|
|
48
48
|
* An optional className to add to the container node
|
|
49
49
|
*/
|
|
50
50
|
className?: string;
|
|
51
|
+
/**
|
|
52
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `ComboBox` component
|
|
53
|
+
*/
|
|
54
|
+
decorator?: ReactNode;
|
|
51
55
|
/**
|
|
52
56
|
* Specify the direction of the combobox dropdown. Can be either top or bottom.
|
|
53
57
|
*/
|
|
@@ -170,6 +174,7 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
|
|
|
170
174
|
*/
|
|
171
175
|
size?: ListBoxSize;
|
|
172
176
|
/**
|
|
177
|
+
* @deprecated please use decorator instead.
|
|
173
178
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `ComboBox` component
|
|
174
179
|
*/
|
|
175
180
|
slug?: ReactNode;
|
|
@@ -118,6 +118,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
118
118
|
ariaLabel: deprecatedAriaLabel,
|
|
119
119
|
autoAlign = false,
|
|
120
120
|
className: containerClassName,
|
|
121
|
+
decorator,
|
|
121
122
|
direction = 'bottom',
|
|
122
123
|
disabled = false,
|
|
123
124
|
downshiftActions,
|
|
@@ -386,7 +387,8 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
386
387
|
const wrapperClasses = cx(`${prefix}--list-box__wrapper`, [containerClassName, {
|
|
387
388
|
[`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
|
|
388
389
|
[`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused,
|
|
389
|
-
[`${prefix}--list-box__wrapper--slug`]: slug
|
|
390
|
+
[`${prefix}--list-box__wrapper--slug`]: slug,
|
|
391
|
+
[`${prefix}--list-box__wrapper--decorator`]: decorator
|
|
390
392
|
}]);
|
|
391
393
|
const inputClasses = cx(`${prefix}--text-input`, {
|
|
392
394
|
[`${prefix}--text-input--empty`]: !inputValue,
|
|
@@ -396,10 +398,10 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
396
398
|
// needs to be Capitalized for react to render it correctly
|
|
397
399
|
const ItemToElement = itemToElement;
|
|
398
400
|
|
|
399
|
-
//
|
|
400
|
-
let
|
|
401
|
-
if (
|
|
402
|
-
|
|
401
|
+
// AILabel always size `mini`
|
|
402
|
+
let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
|
|
403
|
+
if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
|
|
404
|
+
normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
|
|
403
405
|
size: 'mini'
|
|
404
406
|
});
|
|
405
407
|
}
|
|
@@ -456,12 +458,12 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
456
458
|
type,
|
|
457
459
|
selectedItem: newSelectedItem
|
|
458
460
|
} = _ref6;
|
|
459
|
-
if (type ===
|
|
461
|
+
if (type === useCombobox.stateChangeTypes.ItemClick && !isEqual(selectedItemProp, newSelectedItem)) {
|
|
460
462
|
onChange({
|
|
461
463
|
selectedItem: newSelectedItem
|
|
462
464
|
});
|
|
463
465
|
}
|
|
464
|
-
if (type ===
|
|
466
|
+
if (type === useCombobox.stateChangeTypes.FunctionSelectItem || type === useCombobox.stateChangeTypes.InputKeyDownEnter) {
|
|
465
467
|
onChange({
|
|
466
468
|
selectedItem: newSelectedItem
|
|
467
469
|
});
|
|
@@ -661,7 +663,9 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
661
663
|
}), /*#__PURE__*/React__default.createElement(ListBoxTrigger, _extends({}, buttonProps, {
|
|
662
664
|
isOpen: isOpen,
|
|
663
665
|
translateWithId: translateWithId
|
|
664
|
-
}))),
|
|
666
|
+
}))), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
|
|
667
|
+
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
668
|
+
}, normalizedDecorator) : '', /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen ? filterItems(items, itemToString, inputValue).map((item, index) => {
|
|
665
669
|
const isObject = item !== null && typeof item === 'object';
|
|
666
670
|
const title = isObject && 'text' in item && itemToElement ? item.text?.toString() : itemToString(item);
|
|
667
671
|
const itemProps = getItemProps({
|
|
@@ -724,6 +728,10 @@ ComboBox.propTypes = {
|
|
|
724
728
|
* An optional className to add to the container node
|
|
725
729
|
*/
|
|
726
730
|
className: PropTypes.string,
|
|
731
|
+
/**
|
|
732
|
+
* **Experimental**: Provide a decorator component to be rendered inside the `ComboBox` component
|
|
733
|
+
*/
|
|
734
|
+
decorator: PropTypes.node,
|
|
727
735
|
/**
|
|
728
736
|
* Specify the direction of the combobox dropdown. Can be either top or bottom.
|
|
729
737
|
*/
|
|
@@ -841,10 +849,7 @@ ComboBox.propTypes = {
|
|
|
841
849
|
* Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
|
|
842
850
|
*/
|
|
843
851
|
size: ListBoxSize,
|
|
844
|
-
|
|
845
|
-
* **Experimental**: Provide a `Slug` component to be rendered inside the `ComboBox` component
|
|
846
|
-
*/
|
|
847
|
-
slug: PropTypes.node,
|
|
852
|
+
slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
|
|
848
853
|
/**
|
|
849
854
|
* Provide text to be used in a `<label>` element that is tied to the
|
|
850
855
|
* combobox via ARIA attributes.
|
|
@@ -39,6 +39,10 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
|
|
|
39
39
|
* Specify the text that should be read for screen readers to clear selection.
|
|
40
40
|
*/
|
|
41
41
|
clearSelectionText?: string;
|
|
42
|
+
/**
|
|
43
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `FilterableMultiSelect` component
|
|
44
|
+
*/
|
|
45
|
+
decorator?: ReactNode;
|
|
42
46
|
/**
|
|
43
47
|
* Specify the direction of the multiselect dropdown.
|
|
44
48
|
*/
|
|
@@ -164,6 +168,7 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
|
|
|
164
168
|
*/
|
|
165
169
|
size?: 'sm' | 'md' | 'lg';
|
|
166
170
|
/**
|
|
171
|
+
* @deprecated please use decorator instead.
|
|
167
172
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `Checkbox` component
|
|
168
173
|
*/
|
|
169
174
|
slug?: ReactNode;
|
|
@@ -69,6 +69,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
69
69
|
clearSelectionDescription = 'Total items selected: ',
|
|
70
70
|
clearSelectionText = 'To clear selection, press Delete or Backspace',
|
|
71
71
|
compareItems = defaultCompareItems,
|
|
72
|
+
decorator,
|
|
72
73
|
direction = 'bottom',
|
|
73
74
|
disabled = false,
|
|
74
75
|
downshiftProps,
|
|
@@ -198,6 +199,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
198
199
|
[`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
|
|
199
200
|
[`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused,
|
|
200
201
|
[`${prefix}--list-box__wrapper--slug`]: slug,
|
|
202
|
+
[`${prefix}--list-box__wrapper--decorator`]: decorator,
|
|
201
203
|
[`${prefix}--autoalign`]: autoAlign
|
|
202
204
|
});
|
|
203
205
|
const helperId = !helperText ? undefined : `filterablemultiselect-helper-text-${filterableMultiSelectInstanceId}`;
|
|
@@ -412,10 +414,10 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
412
414
|
}
|
|
413
415
|
}
|
|
414
416
|
|
|
415
|
-
//
|
|
416
|
-
let
|
|
417
|
-
if (
|
|
418
|
-
|
|
417
|
+
// AILabel always size `mini`
|
|
418
|
+
let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
|
|
419
|
+
if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
|
|
420
|
+
normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
|
|
419
421
|
size: 'mini'
|
|
420
422
|
});
|
|
421
423
|
}
|
|
@@ -596,7 +598,9 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
596
598
|
}), /*#__PURE__*/React__default.createElement(ListBoxTrigger, _extends({}, buttonProps, {
|
|
597
599
|
isOpen: isOpen,
|
|
598
600
|
translateWithId: translateWithId
|
|
599
|
-
}))),
|
|
601
|
+
}))), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
|
|
602
|
+
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
603
|
+
}, normalizedDecorator) : '', /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen ? sortedItems.map((item, index) => {
|
|
600
604
|
const isChecked = controlledSelectedItems.filter(selected => isEqual(selected, item)).length > 0;
|
|
601
605
|
const itemProps = getItemProps({
|
|
602
606
|
item,
|
|
@@ -658,6 +662,10 @@ FilterableMultiSelect.propTypes = {
|
|
|
658
662
|
* Specify the text that should be read for screen readers to clear selection.
|
|
659
663
|
*/
|
|
660
664
|
clearSelectionText: PropTypes.string,
|
|
665
|
+
/**
|
|
666
|
+
* **Experimental**: Provide a decorator component to be rendered inside the `FilterableMultiSelect` component
|
|
667
|
+
*/
|
|
668
|
+
decorator: PropTypes.node,
|
|
661
669
|
/**
|
|
662
670
|
* Specify the direction of the multiselect dropdown. Can be either top or bottom.
|
|
663
671
|
*/
|
|
@@ -757,10 +765,7 @@ FilterableMultiSelect.propTypes = {
|
|
|
757
765
|
* Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
|
|
758
766
|
*/
|
|
759
767
|
size: ListBoxSize,
|
|
760
|
-
|
|
761
|
-
* **Experimental**: Provide a `Slug` component to be rendered inside the `FilterableMultiSelect` component
|
|
762
|
-
*/
|
|
763
|
-
slug: PropTypes.node,
|
|
768
|
+
slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
|
|
764
769
|
...sortingPropTypes,
|
|
765
770
|
/**
|
|
766
771
|
* Provide text to be used in a `<label>` element that is tied to the
|
|
@@ -33,6 +33,10 @@ export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<Item
|
|
|
33
33
|
* Specify the text that should be read for screen readers to clear selection.
|
|
34
34
|
*/
|
|
35
35
|
clearSelectionText?: string;
|
|
36
|
+
/**
|
|
37
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `MultiSelect` component
|
|
38
|
+
*/
|
|
39
|
+
decorator?: ReactNode;
|
|
36
40
|
/**
|
|
37
41
|
* Specify the direction of the multiselect dropdown. Can be either top or bottom.
|
|
38
42
|
*/
|
|
@@ -143,6 +147,7 @@ export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<Item
|
|
|
143
147
|
*/
|
|
144
148
|
size?: ListBoxSize;
|
|
145
149
|
/**
|
|
150
|
+
* @deprecated please use decorator instead.
|
|
146
151
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `MultiSelect` component
|
|
147
152
|
*/
|
|
148
153
|
slug?: ReactNode;
|
|
@@ -63,6 +63,7 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
63
63
|
let {
|
|
64
64
|
autoAlign = false,
|
|
65
65
|
className: containerClassName,
|
|
66
|
+
decorator,
|
|
66
67
|
id,
|
|
67
68
|
items,
|
|
68
69
|
itemToElement,
|
|
@@ -262,7 +263,8 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
262
263
|
[`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
|
|
263
264
|
[`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
|
|
264
265
|
[`${prefix}--list-box__wrapper--fluid--focus`]: !isOpen && isFluid && isFocused,
|
|
265
|
-
[`${prefix}--list-box__wrapper--slug`]: slug
|
|
266
|
+
[`${prefix}--list-box__wrapper--slug`]: slug,
|
|
267
|
+
[`${prefix}--list-box__wrapper--decorator`]: decorator
|
|
266
268
|
});
|
|
267
269
|
const titleClasses = cx(`${prefix}--label`, {
|
|
268
270
|
[`${prefix}--label--disabled`]: disabled,
|
|
@@ -400,10 +402,10 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
400
402
|
}
|
|
401
403
|
} : {};
|
|
402
404
|
|
|
403
|
-
//
|
|
404
|
-
let
|
|
405
|
-
if (
|
|
406
|
-
|
|
405
|
+
// AILabel always size `mini`
|
|
406
|
+
let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
|
|
407
|
+
if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
|
|
408
|
+
normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
|
|
407
409
|
size: 'mini'
|
|
408
410
|
});
|
|
409
411
|
}
|
|
@@ -463,7 +465,9 @@ const MultiSelect = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
463
465
|
}, label), /*#__PURE__*/React__default.createElement(ListBox.MenuIcon, {
|
|
464
466
|
isOpen: isOpen,
|
|
465
467
|
translateWithId: translateWithId
|
|
466
|
-
})),
|
|
468
|
+
})), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
|
|
469
|
+
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
470
|
+
}, normalizedDecorator) : ''), /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen && sortItems(filteredItems, sortOptions).map((item, index) => {
|
|
467
471
|
const isChecked = selectedItems.filter(selected => isEqual(selected, item)).length > 0;
|
|
468
472
|
const isIndeterminate = selectedItems.length !== 0 && item['isSelectAll'] && !isChecked;
|
|
469
473
|
const itemProps = getItemProps({
|
|
@@ -528,6 +532,10 @@ MultiSelect.propTypes = {
|
|
|
528
532
|
* declaring function with `useCallback` to prevent unnecessary re-renders.
|
|
529
533
|
*/
|
|
530
534
|
compareItems: PropTypes.func,
|
|
535
|
+
/**
|
|
536
|
+
* **Experimental**: Provide a decorator component to be rendered inside the `MultiSelect` component
|
|
537
|
+
*/
|
|
538
|
+
decorator: PropTypes.node,
|
|
531
539
|
/**
|
|
532
540
|
* Specify the direction of the multiselect dropdown. Can be either top or bottom.
|
|
533
541
|
*/
|
|
@@ -635,10 +643,7 @@ MultiSelect.propTypes = {
|
|
|
635
643
|
* Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
|
|
636
644
|
*/
|
|
637
645
|
size: ListBoxSize,
|
|
638
|
-
|
|
639
|
-
* **Experimental**: Provide a `Slug` component to be rendered inside the `MultiSelect` component
|
|
640
|
-
*/
|
|
641
|
-
slug: PropTypes.node,
|
|
646
|
+
slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
|
|
642
647
|
/**
|
|
643
648
|
* Provide a method that sorts all options in the control. Overriding this
|
|
644
649
|
* prop means that you also have to handle the sort logic for selected versus
|
|
@@ -4,8 +4,8 @@
|
|
|
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 PropTypes from 'prop-types';
|
|
8
7
|
import React, { ComponentType } from 'react';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
9
|
/**
|
|
10
10
|
* @param {Element} menuBody The menu body with the menu arrow.
|
|
11
11
|
* @param {string} direction The floating menu direction.
|
|
@@ -6,19 +6,19 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { defineProperty as _defineProperty, extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import
|
|
10
|
-
import PropTypes from 'prop-types';
|
|
9
|
+
import FloatingMenu, { DIRECTION_TOP, DIRECTION_BOTTOM } from '../../internal/FloatingMenu.js';
|
|
11
10
|
import React__default from 'react';
|
|
12
|
-
import cx from 'classnames';
|
|
13
11
|
import ClickListener from '../../internal/ClickListener.js';
|
|
14
|
-
import
|
|
12
|
+
import { IconButton } from '../IconButton/index.js';
|
|
15
13
|
import { OverflowMenuVertical } from '@carbon/icons-react';
|
|
16
|
-
import mergeRefs from '../../tools/mergeRefs.js';
|
|
17
14
|
import { PrefixContext } from '../../internal/usePrefix.js';
|
|
15
|
+
import PropTypes from 'prop-types';
|
|
16
|
+
import cx from 'classnames';
|
|
18
17
|
import deprecate from '../../prop-types/deprecate.js';
|
|
19
|
-
import
|
|
20
|
-
import
|
|
18
|
+
import invariant from 'invariant';
|
|
19
|
+
import mergeRefs from '../../tools/mergeRefs.js';
|
|
21
20
|
import { noopFn } from '../../internal/noopFn.js';
|
|
21
|
+
import setupGetInstanceId from '../../tools/setupGetInstanceId.js';
|
|
22
22
|
import { matches } from '../../internal/keyboard/match.js';
|
|
23
23
|
import { ArrowUp, ArrowRight, ArrowDown, ArrowLeft, Escape } from '../../internal/keyboard/keys.js';
|
|
24
24
|
|
|
@@ -81,16 +81,6 @@ const getMenuOffset = (menuBody, direction, trigger, flip) => {
|
|
|
81
81
|
top: 0
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
case 'left':
|
|
85
|
-
case 'right':
|
|
86
|
-
{
|
|
87
|
-
// TODO: Ensure `trigger` is there for `<OverflowMenu open>`
|
|
88
|
-
const triggerHeight = !trigger ? 0 : trigger.offsetHeight;
|
|
89
|
-
return {
|
|
90
|
-
left: 0,
|
|
91
|
-
top: (!flip ? 1 : -1) * (menuHeight / 2 - triggerHeight / 2)
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
84
|
}
|
|
95
85
|
};
|
|
96
86
|
class OverflowMenu extends React__default.Component {
|
|
@@ -225,7 +225,7 @@ const Pagination = /*#__PURE__*/React__default.forwardRef(function Pagination(_r
|
|
|
225
225
|
}, pageText(page)) : /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Select, {
|
|
226
226
|
id: `${prefix}-pagination-select-${inputId}-right`,
|
|
227
227
|
className: `${prefix}--select__page-number`,
|
|
228
|
-
labelText: `Page
|
|
228
|
+
labelText: `Page of ${totalPages} pages`,
|
|
229
229
|
inline: true,
|
|
230
230
|
hideLabel: true,
|
|
231
231
|
onChange: handlePageInputChange,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React, { type ForwardedRef, type WeakValidationMap, type ElementType } from 'react';
|
|
8
8
|
import { type PolymorphicProps } from '../../types/common';
|
|
9
|
+
import { type Boundary } from '@floating-ui/react';
|
|
9
10
|
/**
|
|
10
11
|
* Deprecated popover alignment values.
|
|
11
12
|
* @deprecated Use NewPopoverAlignment instead.
|
|
@@ -22,6 +23,10 @@ interface PopoverBaseProps {
|
|
|
22
23
|
* Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
|
|
23
24
|
*/
|
|
24
25
|
autoAlign?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Specify a bounding element to be used for autoAlign calculations. The viewport is used by default. This prop is currently experimental and is subject to future changes.
|
|
28
|
+
*/
|
|
29
|
+
autoAlignBoundary?: Boundary;
|
|
25
30
|
/**
|
|
26
31
|
* Specify whether a caret should be rendered
|
|
27
32
|
*/
|
|
@@ -53,6 +53,7 @@ const Popover = /*#__PURE__*/React__default.forwardRef(function PopoverRenderFun
|
|
|
53
53
|
align: initialAlign = isTabTip ? 'bottom-start' : 'bottom',
|
|
54
54
|
as: BaseComponent = 'span',
|
|
55
55
|
autoAlign = false,
|
|
56
|
+
autoAlignBoundary,
|
|
56
57
|
caret = isTabTip ? false : true,
|
|
57
58
|
className: customClassName,
|
|
58
59
|
children,
|
|
@@ -130,7 +131,8 @@ const Popover = /*#__PURE__*/React__default.forwardRef(function PopoverRenderFun
|
|
|
130
131
|
middleware: [offset(!isTabTip ? popoverDimensions?.current?.offset : 0), autoAlign && flip({
|
|
131
132
|
fallbackPlacements: 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'],
|
|
132
133
|
fallbackStrategy: 'initialPlacement',
|
|
133
|
-
fallbackAxisSideDirection: 'start'
|
|
134
|
+
fallbackAxisSideDirection: 'start',
|
|
135
|
+
boundary: autoAlignBoundary
|
|
134
136
|
}), arrow({
|
|
135
137
|
element: caretRef
|
|
136
138
|
}), autoAlign && hide()],
|
|
@@ -301,6 +303,15 @@ Popover.propTypes = {
|
|
|
301
303
|
* Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
|
|
302
304
|
*/
|
|
303
305
|
autoAlign: PropTypes.bool,
|
|
306
|
+
/**
|
|
307
|
+
* Specify a bounding element to be used for autoAlign calculations. The viewport is used by default. This prop is currently experimental and is subject to future changes.
|
|
308
|
+
*/
|
|
309
|
+
autoAlignBoundary: PropTypes.oneOfType([PropTypes.oneOf(['clippingAncestors']), PropTypes.elementType, PropTypes.arrayOf(PropTypes.elementType), PropTypes.exact({
|
|
310
|
+
x: PropTypes.number.isRequired,
|
|
311
|
+
y: PropTypes.number.isRequired,
|
|
312
|
+
width: PropTypes.number.isRequired,
|
|
313
|
+
height: PropTypes.number.isRequired
|
|
314
|
+
})]),
|
|
304
315
|
/**
|
|
305
316
|
* Specify whether a caret should be rendered
|
|
306
317
|
*/
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React, { ChangeEventHandler, ComponentPropsWithRef, ReactNode } from 'react';
|
|
8
8
|
type ExcludedAttributes = 'size';
|
|
9
|
-
interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, ExcludedAttributes> {
|
|
9
|
+
export interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, ExcludedAttributes> {
|
|
10
10
|
/**
|
|
11
11
|
* Provide the contents of your Select
|
|
12
12
|
*/
|
|
@@ -15,6 +15,10 @@ interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, ExcludedAttr
|
|
|
15
15
|
* Specify an optional className to be applied to the node containing the label and the select box
|
|
16
16
|
*/
|
|
17
17
|
className?: string;
|
|
18
|
+
/**
|
|
19
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `Select` component
|
|
20
|
+
*/
|
|
21
|
+
decorator?: ReactNode;
|
|
18
22
|
/**
|
|
19
23
|
* Optionally provide the default value of the `<select>`
|
|
20
24
|
*/
|
|
@@ -77,6 +81,7 @@ interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, ExcludedAttr
|
|
|
77
81
|
*/
|
|
78
82
|
size?: 'sm' | 'md' | 'lg';
|
|
79
83
|
/**
|
|
84
|
+
* @deprecated please use decorator instead.
|
|
80
85
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `Dropdown` component
|
|
81
86
|
*/
|
|
82
87
|
slug?: ReactNode;
|
|
@@ -22,6 +22,7 @@ import { Text } from '../Text/Text.js';
|
|
|
22
22
|
const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref) {
|
|
23
23
|
let {
|
|
24
24
|
className,
|
|
25
|
+
decorator,
|
|
25
26
|
id,
|
|
26
27
|
inline = false,
|
|
27
28
|
labelText = 'Select',
|
|
@@ -60,7 +61,8 @@ const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref)
|
|
|
60
61
|
[`${prefix}--select--warning`]: warn,
|
|
61
62
|
[`${prefix}--select--fluid--invalid`]: isFluid && invalid,
|
|
62
63
|
[`${prefix}--select--fluid--focus`]: isFluid && isFocused,
|
|
63
|
-
[`${prefix}--select--slug`]: slug
|
|
64
|
+
[`${prefix}--select--slug`]: slug,
|
|
65
|
+
[`${prefix}--select--decorator`]: decorator
|
|
64
66
|
});
|
|
65
67
|
const labelClasses = cx(`${prefix}--label`, {
|
|
66
68
|
[`${prefix}--visually-hidden`]: hideLabel,
|
|
@@ -123,10 +125,10 @@ const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref)
|
|
|
123
125
|
}
|
|
124
126
|
};
|
|
125
127
|
|
|
126
|
-
//
|
|
127
|
-
let
|
|
128
|
-
if (
|
|
129
|
-
|
|
128
|
+
// AILabel always size `mini`
|
|
129
|
+
let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
|
|
130
|
+
if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
|
|
131
|
+
normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
|
|
130
132
|
size: 'mini'
|
|
131
133
|
});
|
|
132
134
|
}
|
|
@@ -167,7 +169,9 @@ const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref)
|
|
|
167
169
|
"data-invalid": invalid || null,
|
|
168
170
|
onFocus: handleFocus,
|
|
169
171
|
onBlur: handleFocus
|
|
170
|
-
}, input,
|
|
172
|
+
}, input, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
|
|
173
|
+
className: `${prefix}--select__inner-wrapper--decorator`
|
|
174
|
+
}, normalizedDecorator) : '', isFluid && /*#__PURE__*/React__default.createElement("hr", {
|
|
171
175
|
className: `${prefix}--select__divider`
|
|
172
176
|
}), isFluid && error ? error : null), !inline && !isFluid && error ? error : helper));
|
|
173
177
|
});
|
|
@@ -181,6 +185,10 @@ Select.propTypes = {
|
|
|
181
185
|
* Specify an optional className to be applied to the node containing the label and the select box
|
|
182
186
|
*/
|
|
183
187
|
className: PropTypes.string,
|
|
188
|
+
/**
|
|
189
|
+
* **Experimental**: Provide a decorator component to be rendered inside the `Select` component
|
|
190
|
+
*/
|
|
191
|
+
decorator: PropTypes.node,
|
|
184
192
|
/**
|
|
185
193
|
* Optionally provide the default value of the `<select>`
|
|
186
194
|
*/
|
|
@@ -241,10 +249,7 @@ Select.propTypes = {
|
|
|
241
249
|
* Specify the size of the Select Input.
|
|
242
250
|
*/
|
|
243
251
|
size: PropTypes.oneOf(['sm', 'md', 'lg']),
|
|
244
|
-
|
|
245
|
-
* **Experimental**: Provide a `Slug` component to be rendered inside the `Select` component
|
|
246
|
-
*/
|
|
247
|
-
slug: PropTypes.node,
|
|
252
|
+
slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
|
|
248
253
|
/**
|
|
249
254
|
* Specify whether the control is currently in warning state
|
|
250
255
|
*/
|
|
@@ -38,7 +38,7 @@ const Switcher = /*#__PURE__*/forwardRef(function Switcher(props, forwardRef) {
|
|
|
38
38
|
direction
|
|
39
39
|
} = _ref;
|
|
40
40
|
const enabledIndices = React__default.Children.toArray(children).reduce((acc, curr, i) => {
|
|
41
|
-
if (Object.keys(curr.props).length !== 0) {
|
|
41
|
+
if (/*#__PURE__*/React__default.isValidElement(curr) && Object.keys(curr.props).length !== 0 && getDisplayName(curr.type) === 'SwitcherItem') {
|
|
42
42
|
acc.push(i);
|
|
43
43
|
}
|
|
44
44
|
return acc;
|
|
@@ -50,7 +50,11 @@ const Switcher = /*#__PURE__*/forwardRef(function Switcher(props, forwardRef) {
|
|
|
50
50
|
if (direction === -1) {
|
|
51
51
|
return enabledIndices[enabledIndices.length - 1];
|
|
52
52
|
}
|
|
53
|
-
return 0;
|
|
53
|
+
return enabledIndices[0];
|
|
54
|
+
case 0:
|
|
55
|
+
if (direction === 1) {
|
|
56
|
+
return enabledIndices[1];
|
|
57
|
+
}
|
|
54
58
|
default:
|
|
55
59
|
return enabledIndices[nextIndex];
|
|
56
60
|
}
|
|
@@ -62,7 +66,7 @@ const Switcher = /*#__PURE__*/forwardRef(function Switcher(props, forwardRef) {
|
|
|
62
66
|
};
|
|
63
67
|
const childrenWithProps = React__default.Children.toArray(children).map((child, index) => {
|
|
64
68
|
// only setup click handlers if onChange event is passed
|
|
65
|
-
if (/*#__PURE__*/React__default.isValidElement(child) && child.type && getDisplayName(child.type) === '
|
|
69
|
+
if (/*#__PURE__*/React__default.isValidElement(child) && child.type && getDisplayName(child.type) === 'SwitcherItem') {
|
|
66
70
|
return /*#__PURE__*/React__default.cloneElement(child, {
|
|
67
71
|
handleSwitcherItemFocus,
|
|
68
72
|
index,
|
package/es/internal/wrapFocus.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import findLast from 'lodash.findlast';
|
|
9
8
|
import { useEffect } from 'react';
|
|
10
9
|
import { DOCUMENT_POSITION_BROAD_PRECEDING, selectorTabbable, DOCUMENT_POSITION_BROAD_FOLLOWING } from './keyboard/navigation.js';
|
|
11
10
|
import { tabbable } from 'tabbable';
|
|
@@ -45,7 +44,7 @@ function wrapFocus(_ref) {
|
|
|
45
44
|
if (bodyNode && currentActiveNode && oldActiveNode && !bodyNode.contains(currentActiveNode) && !elementOrParentIsFloatingMenu(currentActiveNode, selectorsFloatingMenus)) {
|
|
46
45
|
const comparisonResult = oldActiveNode.compareDocumentPosition(currentActiveNode);
|
|
47
46
|
if (currentActiveNode === startTrapNode || comparisonResult & DOCUMENT_POSITION_BROAD_PRECEDING) {
|
|
48
|
-
const tabbable =
|
|
47
|
+
const tabbable = [...bodyNode.querySelectorAll(selectorTabbable)].reverse().find(elem => Boolean(elem.offsetParent));
|
|
49
48
|
if (tabbable) {
|
|
50
49
|
tabbable.focus();
|
|
51
50
|
} else if (bodyNode !== oldActiveNode) {
|
|
@@ -48,6 +48,10 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
|
|
|
48
48
|
* An optional className to add to the container node
|
|
49
49
|
*/
|
|
50
50
|
className?: string;
|
|
51
|
+
/**
|
|
52
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `ComboBox` component
|
|
53
|
+
*/
|
|
54
|
+
decorator?: ReactNode;
|
|
51
55
|
/**
|
|
52
56
|
* Specify the direction of the combobox dropdown. Can be either top or bottom.
|
|
53
57
|
*/
|
|
@@ -170,6 +174,7 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
|
|
|
170
174
|
*/
|
|
171
175
|
size?: ListBoxSize;
|
|
172
176
|
/**
|
|
177
|
+
* @deprecated please use decorator instead.
|
|
173
178
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `ComboBox` component
|
|
174
179
|
*/
|
|
175
180
|
slug?: ReactNode;
|
|
@@ -129,6 +129,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
129
129
|
ariaLabel: deprecatedAriaLabel,
|
|
130
130
|
autoAlign = false,
|
|
131
131
|
className: containerClassName,
|
|
132
|
+
decorator,
|
|
132
133
|
direction = 'bottom',
|
|
133
134
|
disabled = false,
|
|
134
135
|
downshiftActions,
|
|
@@ -397,7 +398,8 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
397
398
|
const wrapperClasses = cx__default["default"](`${prefix}--list-box__wrapper`, [containerClassName, {
|
|
398
399
|
[`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
|
|
399
400
|
[`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused,
|
|
400
|
-
[`${prefix}--list-box__wrapper--slug`]: slug
|
|
401
|
+
[`${prefix}--list-box__wrapper--slug`]: slug,
|
|
402
|
+
[`${prefix}--list-box__wrapper--decorator`]: decorator
|
|
401
403
|
}]);
|
|
402
404
|
const inputClasses = cx__default["default"](`${prefix}--text-input`, {
|
|
403
405
|
[`${prefix}--text-input--empty`]: !inputValue,
|
|
@@ -407,10 +409,10 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
407
409
|
// needs to be Capitalized for react to render it correctly
|
|
408
410
|
const ItemToElement = itemToElement;
|
|
409
411
|
|
|
410
|
-
//
|
|
411
|
-
let
|
|
412
|
-
if (
|
|
413
|
-
|
|
412
|
+
// AILabel always size `mini`
|
|
413
|
+
let normalizedDecorator = /*#__PURE__*/React__default["default"].isValidElement(slug ?? decorator) ? slug ?? decorator : null;
|
|
414
|
+
if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
|
|
415
|
+
normalizedDecorator = /*#__PURE__*/React__default["default"].cloneElement(normalizedDecorator, {
|
|
414
416
|
size: 'mini'
|
|
415
417
|
});
|
|
416
418
|
}
|
|
@@ -467,12 +469,12 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
467
469
|
type,
|
|
468
470
|
selectedItem: newSelectedItem
|
|
469
471
|
} = _ref6;
|
|
470
|
-
if (type ===
|
|
472
|
+
if (type === Downshift.useCombobox.stateChangeTypes.ItemClick && !isEqual__default["default"](selectedItemProp, newSelectedItem)) {
|
|
471
473
|
onChange({
|
|
472
474
|
selectedItem: newSelectedItem
|
|
473
475
|
});
|
|
474
476
|
}
|
|
475
|
-
if (type ===
|
|
477
|
+
if (type === Downshift.useCombobox.stateChangeTypes.FunctionSelectItem || type === Downshift.useCombobox.stateChangeTypes.InputKeyDownEnter) {
|
|
476
478
|
onChange({
|
|
477
479
|
selectedItem: newSelectedItem
|
|
478
480
|
});
|
|
@@ -672,7 +674,9 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
672
674
|
}), /*#__PURE__*/React__default["default"].createElement(ListBoxTrigger["default"], _rollupPluginBabelHelpers["extends"]({}, buttonProps, {
|
|
673
675
|
isOpen: isOpen,
|
|
674
676
|
translateWithId: translateWithId
|
|
675
|
-
}))),
|
|
677
|
+
}))), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default["default"].createElement("div", {
|
|
678
|
+
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
679
|
+
}, normalizedDecorator) : '', /*#__PURE__*/React__default["default"].createElement(index$1["default"].Menu, menuProps, isOpen ? filterItems(items, itemToString, inputValue).map((item, index) => {
|
|
676
680
|
const isObject = item !== null && typeof item === 'object';
|
|
677
681
|
const title = isObject && 'text' in item && itemToElement ? item.text?.toString() : itemToString(item);
|
|
678
682
|
const itemProps = getItemProps({
|
|
@@ -735,6 +739,10 @@ ComboBox.propTypes = {
|
|
|
735
739
|
* An optional className to add to the container node
|
|
736
740
|
*/
|
|
737
741
|
className: PropTypes__default["default"].string,
|
|
742
|
+
/**
|
|
743
|
+
* **Experimental**: Provide a decorator component to be rendered inside the `ComboBox` component
|
|
744
|
+
*/
|
|
745
|
+
decorator: PropTypes__default["default"].node,
|
|
738
746
|
/**
|
|
739
747
|
* Specify the direction of the combobox dropdown. Can be either top or bottom.
|
|
740
748
|
*/
|
|
@@ -852,10 +860,7 @@ ComboBox.propTypes = {
|
|
|
852
860
|
* Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
|
|
853
861
|
*/
|
|
854
862
|
size: ListBoxPropTypes.ListBoxSize,
|
|
855
|
-
|
|
856
|
-
* **Experimental**: Provide a `Slug` component to be rendered inside the `ComboBox` component
|
|
857
|
-
*/
|
|
858
|
-
slug: PropTypes__default["default"].node,
|
|
863
|
+
slug: deprecate["default"](PropTypes__default["default"].node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
|
|
859
864
|
/**
|
|
860
865
|
* Provide text to be used in a `<label>` element that is tied to the
|
|
861
866
|
* combobox via ARIA attributes.
|