@carbon/react 1.111.1 → 1.112.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 +935 -935
- package/es/components/ComboBox/ComboBox.js +7 -7
- package/es/components/DatePicker/DatePicker.js +1 -2
- package/es/components/DatePicker/plugins/fixEventsPlugin.d.ts +2 -5
- package/es/components/DatePicker/plugins/fixEventsPlugin.js +5 -12
- package/es/components/Dropdown/Dropdown.js +1 -4
- package/es/components/FeatureFlags/index.d.ts +3 -1
- package/es/components/FeatureFlags/index.js +36 -14
- package/es/components/IconIndicator/index.d.ts +33 -1
- package/es/components/IconIndicator/index.js +55 -26
- package/es/components/ListBox/next/ListBoxSelection.d.ts +12 -2
- package/es/components/ListBox/next/ListBoxSelection.js +7 -2
- package/es/components/Modal/Modal.js +2 -2
- package/es/components/MultiSelect/FilterableMultiSelect.js +19 -10
- package/es/components/MultiSelect/MultiSelect.js +3 -4
- package/es/components/OverflowMenu/OverflowMenu.js +31 -6
- package/es/components/OverflowMenu/next/index.d.ts +1 -1
- package/es/components/OverflowMenu/next/index.js +2 -2
- package/es/components/ShapeIndicator/index.d.ts +18 -0
- package/es/components/ShapeIndicator/index.js +49 -7
- package/es/components/Tabs/Tabs.js +1 -1
- package/es/components/Tooltip/DefinitionTooltip.js +5 -2
- package/es/feature-flags.js +1 -0
- package/es/internal/index.d.ts +2 -1
- package/es/internal/isItemDisabled.d.ts +7 -0
- package/es/internal/isItemDisabled.js +17 -0
- package/lib/components/ComboBox/ComboBox.js +7 -7
- package/lib/components/DatePicker/DatePicker.js +1 -2
- package/lib/components/DatePicker/plugins/fixEventsPlugin.d.ts +2 -5
- package/lib/components/DatePicker/plugins/fixEventsPlugin.js +5 -12
- package/lib/components/Dropdown/Dropdown.js +2 -5
- package/lib/components/FeatureFlags/index.d.ts +3 -1
- package/lib/components/FeatureFlags/index.js +36 -14
- package/lib/components/IconIndicator/index.d.ts +33 -1
- package/lib/components/IconIndicator/index.js +54 -25
- package/lib/components/ListBox/next/ListBoxSelection.d.ts +12 -2
- package/lib/components/ListBox/next/ListBoxSelection.js +7 -2
- package/lib/components/Modal/Modal.js +2 -2
- package/lib/components/MultiSelect/FilterableMultiSelect.js +19 -10
- package/lib/components/MultiSelect/MultiSelect.js +3 -4
- package/lib/components/OverflowMenu/OverflowMenu.js +30 -5
- package/lib/components/OverflowMenu/next/index.d.ts +1 -1
- package/lib/components/OverflowMenu/next/index.js +2 -2
- package/lib/components/ShapeIndicator/index.d.ts +18 -0
- package/lib/components/ShapeIndicator/index.js +48 -6
- package/lib/components/Tabs/Tabs.js +1 -1
- package/lib/components/Tooltip/DefinitionTooltip.js +4 -1
- package/lib/feature-flags.js +1 -0
- package/lib/internal/index.d.ts +2 -1
- package/lib/internal/isItemDisabled.d.ts +7 -0
- package/lib/internal/isItemDisabled.js +17 -0
- package/package.json +15 -11
- package/telemetry.yml +4 -1
|
@@ -12,6 +12,7 @@ import { match } from "../../internal/keyboard/match.js";
|
|
|
12
12
|
import { useId } from "../../internal/useId.js";
|
|
13
13
|
import { deprecate } from "../../prop-types/deprecate.js";
|
|
14
14
|
import { defaultItemToString } from "../../internal/defaultItemToString.js";
|
|
15
|
+
import { isItemDisabled } from "../../internal/isItemDisabled.js";
|
|
15
16
|
import { isComponentElement } from "../../internal/utils.js";
|
|
16
17
|
import { useFeatureFlag } from "../FeatureFlags/index.js";
|
|
17
18
|
import { useNormalizedInputProps } from "../../internal/useNormalizedInputProps.js";
|
|
@@ -39,7 +40,6 @@ import isEqual from "react-fast-compare";
|
|
|
39
40
|
*/
|
|
40
41
|
const { InputBlur, InputKeyDownEnter, FunctionToggleMenu, ToggleButtonClick, ItemMouseMove, InputKeyDownArrowUp, InputKeyDownArrowDown, MenuMouseLeave, ItemClick, FunctionSelectItem } = useCombobox.stateChangeTypes;
|
|
41
42
|
const defaultShouldFilterItem = () => true;
|
|
42
|
-
const isDisabledItem = (item) => item !== null && typeof item === "object" && "disabled" in item && Boolean(item.disabled);
|
|
43
43
|
const autocompleteCustomFilter = ({ item, inputValue }) => {
|
|
44
44
|
if (inputValue === null || inputValue === "") return true;
|
|
45
45
|
const lowercaseItem = item.toLowerCase();
|
|
@@ -56,7 +56,7 @@ const findHighlightedIndex = ({ items, itemToString = defaultItemToString }, inp
|
|
|
56
56
|
const searchValue = inputValue.toLowerCase();
|
|
57
57
|
for (let i = 0; i < items.length; i++) {
|
|
58
58
|
const item = itemToString(items[i]).toLowerCase();
|
|
59
|
-
if (!
|
|
59
|
+
if (!isItemDisabled(items[i]) && item.indexOf(searchValue) !== -1) return i;
|
|
60
60
|
}
|
|
61
61
|
return -1;
|
|
62
62
|
};
|
|
@@ -99,7 +99,7 @@ const ComboBox = forwardRef((props, ref) => {
|
|
|
99
99
|
useEffect(() => {
|
|
100
100
|
if (typeahead) {
|
|
101
101
|
if (inputValue.length >= prevInputLengthRef.current) if (inputValue) {
|
|
102
|
-
const filteredItems = items.filter((item) => !
|
|
102
|
+
const filteredItems = items.filter((item) => !isItemDisabled(item) && autocompleteCustomFilter({
|
|
103
103
|
item: itemToString(item),
|
|
104
104
|
inputValue
|
|
105
105
|
}));
|
|
@@ -221,7 +221,7 @@ const ComboBox = forwardRef((props, ref) => {
|
|
|
221
221
|
case InputKeyDownEnter:
|
|
222
222
|
if (!allowCustomValue) if (state.highlightedIndex !== -1) {
|
|
223
223
|
const highlightedItem = filterItems(items, itemToString, inputValue)[state.highlightedIndex];
|
|
224
|
-
if (highlightedItem && !
|
|
224
|
+
if (highlightedItem && !isItemDisabled(highlightedItem)) return {
|
|
225
225
|
...changes,
|
|
226
226
|
selectedItem: highlightedItem,
|
|
227
227
|
inputValue: itemToString(highlightedItem)
|
|
@@ -230,7 +230,7 @@ const ComboBox = forwardRef((props, ref) => {
|
|
|
230
230
|
const autoIndex = indexToHighlight(inputValue);
|
|
231
231
|
if (autoIndex !== -1) {
|
|
232
232
|
const matchingItem = items[autoIndex];
|
|
233
|
-
if (matchingItem && !
|
|
233
|
+
if (matchingItem && !isItemDisabled(matchingItem)) return {
|
|
234
234
|
...changes,
|
|
235
235
|
selectedItem: matchingItem,
|
|
236
236
|
inputValue: itemToString(matchingItem)
|
|
@@ -352,7 +352,7 @@ const ComboBox = forwardRef((props, ref) => {
|
|
|
352
352
|
initialSelectedItem,
|
|
353
353
|
inputId: id,
|
|
354
354
|
stateReducer,
|
|
355
|
-
isItemDisabled
|
|
355
|
+
isItemDisabled,
|
|
356
356
|
...downshiftProps,
|
|
357
357
|
onStateChange: ({ type, selectedItem: newSelectedItem }) => {
|
|
358
358
|
if (isManualClearingRef.current || isSyncingControlledSelectionRef.current) {
|
|
@@ -539,7 +539,7 @@ const ComboBox = forwardRef((props, ref) => {
|
|
|
539
539
|
}
|
|
540
540
|
if (typeahead && event.key === "Tab") {
|
|
541
541
|
if (!isOpen) return;
|
|
542
|
-
const matchingItem = items.find((item) => !
|
|
542
|
+
const matchingItem = items.find((item) => !isItemDisabled(item) && itemToString(item).toLowerCase().startsWith(inputValue.toLowerCase()));
|
|
543
543
|
if (matchingItem) {
|
|
544
544
|
downshiftSetInputValue(itemToString(matchingItem));
|
|
545
545
|
selectItem(matchingItem);
|
|
@@ -12,7 +12,7 @@ import { deprecate } from "../../prop-types/deprecate.js";
|
|
|
12
12
|
import { isComponentElement } from "../../internal/utils.js";
|
|
13
13
|
import DatePickerInput_default from "../DatePickerInput/index.js";
|
|
14
14
|
import { appendToPlugin } from "./plugins/appendToPlugin.js";
|
|
15
|
-
import fixEventsPlugin from "./plugins/fixEventsPlugin.js";
|
|
15
|
+
import { fixEventsPlugin } from "./plugins/fixEventsPlugin.js";
|
|
16
16
|
import { isEmptyDateValue } from "./utils.js";
|
|
17
17
|
import { rangePlugin } from "./plugins/rangePlugin.js";
|
|
18
18
|
import { useSavedCallback } from "../../internal/useSavedCallback.js";
|
|
@@ -283,7 +283,6 @@ const DatePicker = forwardRef((props, ref) => {
|
|
|
283
283
|
fixEventsPlugin({
|
|
284
284
|
inputFrom: startInputField.current,
|
|
285
285
|
inputTo: endInputField.current,
|
|
286
|
-
lastStartValue,
|
|
287
286
|
container: wrapperRef.current
|
|
288
287
|
})
|
|
289
288
|
],
|
|
@@ -8,11 +8,8 @@ import type { Plugin } from 'flatpickr/dist/types/options';
|
|
|
8
8
|
interface FixEventsPluginConfig {
|
|
9
9
|
inputFrom: HTMLInputElement;
|
|
10
10
|
inputTo?: HTMLInputElement | null;
|
|
11
|
-
lastStartValue: {
|
|
12
|
-
current: string;
|
|
13
|
-
};
|
|
14
11
|
container?: HTMLElement | null;
|
|
15
12
|
}
|
|
16
13
|
type FixEventsPlugin = (config: FixEventsPluginConfig) => Plugin;
|
|
17
|
-
declare const fixEventsPlugin: FixEventsPlugin;
|
|
18
|
-
export
|
|
14
|
+
export declare const fixEventsPlugin: FixEventsPlugin;
|
|
15
|
+
export {};
|
|
@@ -9,14 +9,13 @@ import { ArrowDown, Enter } from "../../../internal/keyboard/keys.js";
|
|
|
9
9
|
import { match } from "../../../internal/keyboard/match.js";
|
|
10
10
|
//#region src/components/DatePicker/plugins/fixEventsPlugin.ts
|
|
11
11
|
const fixEventsPlugin = (config) => (fp) => {
|
|
12
|
-
const { inputFrom, inputTo,
|
|
12
|
+
const { inputFrom, inputTo, container } = config;
|
|
13
13
|
let mouseDownInside = false;
|
|
14
|
-
const getEventPath = (event) => typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
15
14
|
const isEventInside = (event) => {
|
|
16
|
-
const path =
|
|
15
|
+
const path = event.composedPath();
|
|
17
16
|
const { target } = event;
|
|
18
17
|
if (!(target instanceof Node)) return false;
|
|
19
|
-
return Boolean(container && (path.includes(container) || container.contains(target)) ||
|
|
18
|
+
return Boolean(container && (path.includes(container) || container.contains(target)) || path.includes(fp.calendarContainer) || fp.calendarContainer.contains(target) || inputFrom && (path.includes(inputFrom) || inputFrom.contains(target)) || inputTo && (path.includes(inputTo) || inputTo.contains(target)));
|
|
20
19
|
};
|
|
21
20
|
/**
|
|
22
21
|
* Handles `click` outside to close calendar
|
|
@@ -62,6 +61,7 @@ const fixEventsPlugin = (config) => (fp) => {
|
|
|
62
61
|
}
|
|
63
62
|
};
|
|
64
63
|
const parseDateWithFormat = (dateStr) => fp.parseDate(dateStr, fp.config.dateFormat);
|
|
64
|
+
const isValidDate = (date) => date?.toString() !== "Invalid Date";
|
|
65
65
|
/**
|
|
66
66
|
* Handles `blur` event.
|
|
67
67
|
*
|
|
@@ -78,16 +78,9 @@ const fixEventsPlugin = (config) => (fp) => {
|
|
|
78
78
|
const currentValueToDate = withoutTime(parseDateWithFormat(inputTo.value));
|
|
79
79
|
if (selectedToDate && currentValueToDate && selectedToDate !== currentValueToDate) fp.setDate([inputFrom.value, inputTo.value], true, fp.config.dateFormat);
|
|
80
80
|
}
|
|
81
|
-
const isValidDate = (date) => date?.toString() !== "Invalid Date";
|
|
82
81
|
if (inputTo === target && fp.selectedDates.length === 1 && inputTo.value) {
|
|
83
82
|
if (isValidDate(parseDateWithFormat(inputTo.value))) fp.setDate([inputFrom.value, inputTo.value], true, fp.config.dateFormat);
|
|
84
83
|
}
|
|
85
|
-
if (inputTo === target && !inputFrom.value && lastStartValue.current) {
|
|
86
|
-
if (isValidDate(parseDateWithFormat(lastStartValue.current))) {
|
|
87
|
-
inputFrom.value = lastStartValue.current;
|
|
88
|
-
if (inputTo.value) fp.setDate([inputFrom.value, inputTo.value], true, fp.config.dateFormat);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
84
|
};
|
|
92
85
|
/**
|
|
93
86
|
* Releases event listeners used in this Flatpickr plugin.
|
|
@@ -128,4 +121,4 @@ const fixEventsPlugin = (config) => (fp) => {
|
|
|
128
121
|
};
|
|
129
122
|
};
|
|
130
123
|
//#endregion
|
|
131
|
-
export { fixEventsPlugin
|
|
124
|
+
export { fixEventsPlugin };
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { usePrefix } from "../../internal/usePrefix.js";
|
|
9
9
|
import { deprecate } from "../../prop-types/deprecate.js";
|
|
10
10
|
import { defaultItemToString } from "../../internal/defaultItemToString.js";
|
|
11
|
+
import { isItemDisabled } from "../../internal/isItemDisabled.js";
|
|
11
12
|
import { isComponentElement } from "../../internal/utils.js";
|
|
12
13
|
import { useFeatureFlag } from "../FeatureFlags/index.js";
|
|
13
14
|
import { useNormalizedInputProps } from "../../internal/useNormalizedInputProps.js";
|
|
@@ -99,9 +100,6 @@ const Dropdown = React.forwardRef(({ autoAlign = false, className: containerClas
|
|
|
99
100
|
const onSelectedItemChange = useCallback(({ selectedItem }) => {
|
|
100
101
|
if (onChange) onChange({ selectedItem: selectedItem ?? null });
|
|
101
102
|
}, [onChange]);
|
|
102
|
-
const isItemDisabled = useCallback((item) => {
|
|
103
|
-
return item !== null && typeof item === "object" && "disabled" in item && item.disabled === true;
|
|
104
|
-
}, []);
|
|
105
103
|
const onHighlightedIndexChange = useCallback((changes) => {
|
|
106
104
|
const { highlightedIndex } = changes;
|
|
107
105
|
if (highlightedIndex !== void 0 && highlightedIndex > -1) {
|
|
@@ -128,7 +126,6 @@ const Dropdown = React.forwardRef(({ autoAlign = false, className: containerClas
|
|
|
128
126
|
initialSelectedItem,
|
|
129
127
|
onSelectedItemChange,
|
|
130
128
|
stateReducer,
|
|
131
|
-
isItemDisabled,
|
|
132
129
|
onHighlightedIndexChange,
|
|
133
130
|
downshiftProps
|
|
134
131
|
]);
|
|
@@ -9,6 +9,7 @@ import { type ReactNode } from 'react';
|
|
|
9
9
|
export interface FeatureFlagsProps {
|
|
10
10
|
children?: ReactNode;
|
|
11
11
|
flags?: Record<string, boolean>;
|
|
12
|
+
enableV12Release?: boolean;
|
|
12
13
|
enableV12TileDefaultIcons?: boolean;
|
|
13
14
|
enableV12TileRadioIcons?: boolean;
|
|
14
15
|
enableV12Overflowmenu?: boolean;
|
|
@@ -26,13 +27,14 @@ export interface FeatureFlagsProps {
|
|
|
26
27
|
* a feature flag is enabled or disabled in a given React tree
|
|
27
28
|
*/
|
|
28
29
|
export declare const FeatureFlags: {
|
|
29
|
-
({ children, flags, enableV12TileDefaultIcons, enableV12TileRadioIcons, enableV12Overflowmenu, enableTreeviewControllable, enableExperimentalFocusWrapWithoutSentinels, enableFocusWrapWithoutSentinels, enableDialogElement, enableV12DynamicFloatingStyles, enableEnhancedFileUploader, enablePresence, }: FeatureFlagsProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
({ children, flags, enableV12Release, enableV12TileDefaultIcons, enableV12TileRadioIcons, enableV12Overflowmenu, enableTreeviewControllable, enableExperimentalFocusWrapWithoutSentinels, enableFocusWrapWithoutSentinels, enableDialogElement, enableV12DynamicFloatingStyles, enableEnhancedFileUploader, enablePresence, }: FeatureFlagsProps): import("react/jsx-runtime").JSX.Element;
|
|
30
31
|
propTypes: {
|
|
31
32
|
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
32
33
|
/**
|
|
33
34
|
* Provide the feature flags to enabled or disabled in the current Rea,ct tree
|
|
34
35
|
*/
|
|
35
36
|
flags: (props: Record<string, any>, propName: string, componentName: string, ...rest: any[]) => any;
|
|
37
|
+
enableV12Release: PropTypes.Requireable<boolean>;
|
|
36
38
|
enableV12TileDefaultIcons: PropTypes.Requireable<boolean>;
|
|
37
39
|
enableV12TileRadioIcons: PropTypes.Requireable<boolean>;
|
|
38
40
|
enableV12Overflowmenu: PropTypes.Requireable<boolean>;
|
|
@@ -22,30 +22,51 @@ import { jsx } from "react/jsx-runtime";
|
|
|
22
22
|
* or disable feature flags in a given React tree
|
|
23
23
|
*/
|
|
24
24
|
const FeatureFlagContext = createContext(FeatureFlags);
|
|
25
|
+
const PROP_TO_FLAG = {
|
|
26
|
+
enableV12Release: "enable-v12-release",
|
|
27
|
+
enableV12TileDefaultIcons: "enable-v12-tile-default-icons",
|
|
28
|
+
enableV12TileRadioIcons: "enable-v12-tile-radio-icons",
|
|
29
|
+
enableV12Overflowmenu: "enable-v12-overflowmenu",
|
|
30
|
+
enableTreeviewControllable: "enable-treeview-controllable",
|
|
31
|
+
enableExperimentalFocusWrapWithoutSentinels: "enable-experimental-focus-wrap-without-sentinels",
|
|
32
|
+
enableFocusWrapWithoutSentinels: "enable-focus-wrap-without-sentinels",
|
|
33
|
+
enableDialogElement: "enable-dialog-element",
|
|
34
|
+
enableV12DynamicFloatingStyles: "enable-v12-dynamic-floating-styles",
|
|
35
|
+
enableEnhancedFileUploader: "enable-enhanced-file-uploader",
|
|
36
|
+
enablePresence: "enable-presence"
|
|
37
|
+
};
|
|
25
38
|
/**
|
|
26
39
|
* Supports an object of feature flag values with the `flags` prop, merging them
|
|
27
40
|
* along with the current `FeatureFlagContext` to provide consumers to check if
|
|
28
41
|
* a feature flag is enabled or disabled in a given React tree
|
|
29
42
|
*/
|
|
30
|
-
const FeatureFlags$1 = ({ children, flags
|
|
43
|
+
const FeatureFlags$1 = ({ children, flags, enableV12Release, enableV12TileDefaultIcons, enableV12TileRadioIcons, enableV12Overflowmenu, enableTreeviewControllable, enableExperimentalFocusWrapWithoutSentinels, enableFocusWrapWithoutSentinels, enableDialogElement, enableV12DynamicFloatingStyles, enableEnhancedFileUploader, enablePresence }) => {
|
|
31
44
|
const parentScope = useContext(FeatureFlagContext);
|
|
32
45
|
const scope = useMemo(() => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
+
const flagProps = {
|
|
47
|
+
enableV12Release,
|
|
48
|
+
enableV12TileDefaultIcons,
|
|
49
|
+
enableV12TileRadioIcons,
|
|
50
|
+
enableV12Overflowmenu,
|
|
51
|
+
enableTreeviewControllable,
|
|
52
|
+
enableExperimentalFocusWrapWithoutSentinels,
|
|
53
|
+
enableFocusWrapWithoutSentinels,
|
|
54
|
+
enableDialogElement,
|
|
55
|
+
enableV12DynamicFloatingStyles,
|
|
56
|
+
enableEnhancedFileUploader,
|
|
57
|
+
enablePresence
|
|
58
|
+
};
|
|
59
|
+
const explicitFlags = {};
|
|
60
|
+
for (const [prop, flagKey] of Object.entries(PROP_TO_FLAG)) {
|
|
61
|
+
const value = flagProps[prop];
|
|
62
|
+
if (value !== void 0) explicitFlags[flagKey] = value;
|
|
63
|
+
}
|
|
64
|
+
if (flags) Object.assign(explicitFlags, flags);
|
|
65
|
+
const scope = createScope(explicitFlags);
|
|
46
66
|
scope.mergeWithScope(parentScope);
|
|
47
67
|
return scope;
|
|
48
68
|
}, [
|
|
69
|
+
enableV12Release,
|
|
49
70
|
enableV12TileDefaultIcons,
|
|
50
71
|
enableV12TileRadioIcons,
|
|
51
72
|
enableV12Overflowmenu,
|
|
@@ -70,6 +91,7 @@ FeatureFlags$1.propTypes = {
|
|
|
70
91
|
* Provide the feature flags to enabled or disabled in the current Rea,ct tree
|
|
71
92
|
*/
|
|
72
93
|
flags: deprecate(PropTypes.objectOf(PropTypes.bool), "The `flags` prop for `FeatureFlag` has been deprecated. Please run the `featureflag-deprecate-flags-prop` codemod to migrate to individual boolean props.npx @carbon/upgrade migrate featureflag-deprecate-flags-prop --write"),
|
|
94
|
+
enableV12Release: PropTypes.bool,
|
|
73
95
|
enableV12TileDefaultIcons: PropTypes.bool,
|
|
74
96
|
enableV12TileRadioIcons: PropTypes.bool,
|
|
75
97
|
enableV12Overflowmenu: PropTypes.bool,
|
|
@@ -5,13 +5,45 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
-
|
|
8
|
+
import { PopoverAlignment } from '../Popover';
|
|
9
|
+
declare const iconTypes: {
|
|
10
|
+
readonly failed: import("@carbon/icons-react").CarbonIconType;
|
|
11
|
+
readonly 'caution-major': import("@carbon/icons-react").CarbonIconType;
|
|
12
|
+
readonly 'caution-minor': import("@carbon/icons-react").CarbonIconType;
|
|
13
|
+
readonly undefined: import("@carbon/icons-react").CarbonIconType;
|
|
14
|
+
readonly succeeded: import("@carbon/icons-react").CarbonIconType;
|
|
15
|
+
readonly normal: import("@carbon/icons-react").CarbonIconType;
|
|
16
|
+
readonly 'in-progress': import("@carbon/icons-react").CarbonIconType;
|
|
17
|
+
readonly incomplete: import("@carbon/icons-react").CarbonIconType;
|
|
18
|
+
readonly 'not-started': import("@carbon/icons-react").CarbonIconType;
|
|
19
|
+
readonly pending: import("@carbon/icons-react").CarbonIconType;
|
|
20
|
+
readonly unknown: import("@carbon/icons-react").CarbonIconType;
|
|
21
|
+
readonly informative: import("@carbon/icons-react").CarbonIconType;
|
|
22
|
+
};
|
|
23
|
+
export declare const IconIndicatorKinds: (keyof typeof iconTypes)[];
|
|
9
24
|
export type IconIndicatorKind = (typeof IconIndicatorKinds)[number];
|
|
10
25
|
export interface IconIndicatorProps {
|
|
26
|
+
/**
|
|
27
|
+
* Specify how the tooltip should align with the icon in compact mode
|
|
28
|
+
*/
|
|
29
|
+
align?: PopoverAlignment;
|
|
30
|
+
/**
|
|
31
|
+
* Will auto-align the tooltip in compact mode.
|
|
32
|
+
*/
|
|
33
|
+
autoAlign?: boolean;
|
|
11
34
|
/**
|
|
12
35
|
* Specify an optional className to add.
|
|
13
36
|
*/
|
|
14
37
|
className?: string;
|
|
38
|
+
/**
|
|
39
|
+
* When true, displays only the icon with the label in a tooltip
|
|
40
|
+
*/
|
|
41
|
+
compact?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Description for the icon announced to screen readers in compact mode.
|
|
44
|
+
* Defaults to `label` when not provided.
|
|
45
|
+
*/
|
|
46
|
+
iconDescription?: string;
|
|
15
47
|
/**
|
|
16
48
|
* Specify the kind of icon to be used
|
|
17
49
|
*/
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { usePrefix } from "../../internal/usePrefix.js";
|
|
9
|
+
import { DefinitionTooltip } from "../Tooltip/DefinitionTooltip.js";
|
|
9
10
|
import classNames from "classnames";
|
|
10
11
|
import React from "react";
|
|
11
12
|
import PropTypes from "prop-types";
|
|
12
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
13
14
|
import { CheckmarkFilled, CheckmarkOutline, CircleDash, ErrorFilled, InProgress, Incomplete, PendingFilled, UndefinedFilled, UnknownFilled, WarningAltFilled, WarningAltInvertedFilled, WarningSquareFilled } from "@carbon/icons-react";
|
|
14
15
|
//#region src/components/IconIndicator/index.tsx
|
|
15
16
|
/**
|
|
@@ -18,54 +19,82 @@ import { CheckmarkFilled, CheckmarkOutline, CircleDash, ErrorFilled, InProgress,
|
|
|
18
19
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
19
20
|
* LICENSE file in the root directory of this source tree.
|
|
20
21
|
*/
|
|
21
|
-
const IconIndicatorKinds = [
|
|
22
|
-
"failed",
|
|
23
|
-
"caution-major",
|
|
24
|
-
"caution-minor",
|
|
25
|
-
"undefined",
|
|
26
|
-
"succeeded",
|
|
27
|
-
"normal",
|
|
28
|
-
"in-progress",
|
|
29
|
-
"incomplete",
|
|
30
|
-
"not-started",
|
|
31
|
-
"pending",
|
|
32
|
-
"unknown",
|
|
33
|
-
"informative"
|
|
34
|
-
];
|
|
35
22
|
const iconTypes = {
|
|
36
23
|
failed: ErrorFilled,
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
"caution-major": WarningAltInvertedFilled,
|
|
25
|
+
"caution-minor": WarningAltFilled,
|
|
39
26
|
undefined: UndefinedFilled,
|
|
40
27
|
succeeded: CheckmarkFilled,
|
|
41
28
|
normal: CheckmarkOutline,
|
|
42
|
-
|
|
29
|
+
"in-progress": InProgress,
|
|
43
30
|
incomplete: Incomplete,
|
|
44
|
-
|
|
31
|
+
"not-started": CircleDash,
|
|
45
32
|
pending: PendingFilled,
|
|
46
33
|
unknown: UnknownFilled,
|
|
47
34
|
informative: WarningSquareFilled
|
|
48
35
|
};
|
|
49
|
-
const
|
|
36
|
+
const IconIndicatorKinds = Object.keys(iconTypes);
|
|
37
|
+
const IconIndicator = React.forwardRef(({ align = "right", autoAlign = false, className: customClassName, compact = false, iconDescription, kind, label, size = 16 }, ref) => {
|
|
50
38
|
const prefix = usePrefix();
|
|
51
|
-
const classNames$1 = classNames(`${prefix}--icon-indicator`, customClassName, { [`${prefix}--icon-indicator--20`]: size
|
|
39
|
+
const classNames$1 = classNames(`${prefix}--icon-indicator`, customClassName, { [`${prefix}--icon-indicator--20`]: size === 20 });
|
|
52
40
|
const IconForKind = iconTypes[kind];
|
|
53
41
|
if (!IconForKind) return null;
|
|
54
|
-
|
|
42
|
+
const iconElement = /* @__PURE__ */ jsx(IconForKind, {
|
|
43
|
+
size,
|
|
44
|
+
className: `${prefix}--icon-indicator--${kind}`
|
|
45
|
+
});
|
|
46
|
+
return /* @__PURE__ */ jsx("div", {
|
|
55
47
|
className: classNames$1,
|
|
56
48
|
ref,
|
|
57
|
-
children:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
49
|
+
children: compact ? /* @__PURE__ */ jsxs(DefinitionTooltip, {
|
|
50
|
+
align,
|
|
51
|
+
autoAlign,
|
|
52
|
+
openOnHover: true,
|
|
53
|
+
definition: label,
|
|
54
|
+
triggerClassName: `${prefix}--icon-indicator__button`,
|
|
55
|
+
children: [iconElement, /* @__PURE__ */ jsx("span", {
|
|
56
|
+
className: `${prefix}--visually-hidden`,
|
|
57
|
+
children: iconDescription ?? label
|
|
58
|
+
})]
|
|
59
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [iconElement, label] })
|
|
61
60
|
});
|
|
62
61
|
});
|
|
63
62
|
IconIndicator.propTypes = {
|
|
63
|
+
/**
|
|
64
|
+
* Specify how the tooltip should align with the icon in compact mode
|
|
65
|
+
*/
|
|
66
|
+
align: PropTypes.oneOf([
|
|
67
|
+
"top",
|
|
68
|
+
"top-start",
|
|
69
|
+
"top-end",
|
|
70
|
+
"bottom",
|
|
71
|
+
"bottom-start",
|
|
72
|
+
"bottom-end",
|
|
73
|
+
"left",
|
|
74
|
+
"left-start",
|
|
75
|
+
"left-end",
|
|
76
|
+
"right",
|
|
77
|
+
"right-start",
|
|
78
|
+
"right-end"
|
|
79
|
+
]),
|
|
80
|
+
/**
|
|
81
|
+
* Will auto-align the tooltip in compact mode
|
|
82
|
+
*/
|
|
83
|
+
autoAlign: PropTypes.bool,
|
|
64
84
|
/**
|
|
65
85
|
* Specify an optional className to add.
|
|
66
86
|
*/
|
|
67
87
|
className: PropTypes.string,
|
|
68
88
|
/**
|
|
89
|
+
* When true, displays only the icon with the label in a tooltip
|
|
90
|
+
*/
|
|
91
|
+
compact: PropTypes.bool,
|
|
92
|
+
/**
|
|
93
|
+
* Description for the icon announced to screen readers in compact mode.
|
|
94
|
+
* Defaults to `label` when not provided.
|
|
95
|
+
*/
|
|
96
|
+
iconDescription: PropTypes.string,
|
|
97
|
+
/**
|
|
69
98
|
* Specify the kind of the Icon Indicator
|
|
70
99
|
*/
|
|
71
100
|
kind: PropTypes.oneOf(IconIndicatorKinds).isRequired,
|
|
@@ -56,6 +56,11 @@ export interface ListBoxSelectionProps extends TranslateWithId<TranslationKey> {
|
|
|
56
56
|
* clear selection element fires a mouseup event
|
|
57
57
|
*/
|
|
58
58
|
onMouseUp?: React.MouseEventHandler<HTMLButtonElement>;
|
|
59
|
+
/**
|
|
60
|
+
* Specify an optional `onMouseDown` handler that is called when the underlying
|
|
61
|
+
* clear selection element fires a mousedown event
|
|
62
|
+
*/
|
|
63
|
+
onMouseDown?: React.MouseEventHandler<HTMLButtonElement>;
|
|
59
64
|
}
|
|
60
65
|
declare function ListBoxSelection({ clearSelection, selectionCount, translateWithId: t, disabled, readOnly, onClearSelection, ...rest }: ListBoxSelectionProps): import("react/jsx-runtime").JSX.Element;
|
|
61
66
|
declare namespace ListBoxSelection {
|
|
@@ -84,8 +89,13 @@ declare namespace ListBoxSelection {
|
|
|
84
89
|
*/
|
|
85
90
|
onClick: PropTypes.Requireable<(...args: any[]) => any>;
|
|
86
91
|
/**
|
|
87
|
-
* Specify an optional `
|
|
88
|
-
* clear selection element
|
|
92
|
+
* Specify an optional `onMouseDown` handler that is called when the underlying
|
|
93
|
+
* clear selection element fires a mousedown event
|
|
94
|
+
*/
|
|
95
|
+
onMouseDown: PropTypes.Requireable<(...args: any[]) => any>;
|
|
96
|
+
/**
|
|
97
|
+
* Specify an optional `onMouseUp` handler that is called when the underlying
|
|
98
|
+
* clear selection element fires a mouseup event
|
|
89
99
|
*/
|
|
90
100
|
onMouseUp: PropTypes.Requireable<(...args: any[]) => any>;
|
|
91
101
|
/**
|
|
@@ -106,8 +106,13 @@ ListBoxSelection.propTypes = {
|
|
|
106
106
|
*/
|
|
107
107
|
onClick: PropTypes.func,
|
|
108
108
|
/**
|
|
109
|
-
* Specify an optional `
|
|
110
|
-
* clear selection element
|
|
109
|
+
* Specify an optional `onMouseDown` handler that is called when the underlying
|
|
110
|
+
* clear selection element fires a mousedown event
|
|
111
|
+
*/
|
|
112
|
+
onMouseDown: PropTypes.func,
|
|
113
|
+
/**
|
|
114
|
+
* Specify an optional `onMouseUp` handler that is called when the underlying
|
|
115
|
+
* clear selection element fires a mouseup event
|
|
111
116
|
*/
|
|
112
117
|
onMouseUp: PropTypes.func,
|
|
113
118
|
/**
|
|
@@ -302,8 +302,8 @@ const ModalDialog = React.forwardRef(function ModalDialog({ "aria-label": ariaLa
|
|
|
302
302
|
focusAfterCloseRef: launcherButtonRef,
|
|
303
303
|
modal: true,
|
|
304
304
|
ref: innerModal,
|
|
305
|
-
role: isAlertDialog ? "alertdialog" :
|
|
306
|
-
"aria-describedby": isAlertDialog ? modalBodyId :
|
|
305
|
+
role: isAlertDialog ? "alertdialog" : void 0,
|
|
306
|
+
"aria-describedby": isAlertDialog ? modalBodyId : void 0,
|
|
307
307
|
className: containerClasses,
|
|
308
308
|
"aria-label": ariaLabel,
|
|
309
309
|
"data-exiting": presenceContext?.isExiting || void 0,
|
|
@@ -12,6 +12,7 @@ import useIsomorphicEffect from "../../internal/useIsomorphicEffect.js";
|
|
|
12
12
|
import { useId } from "../../internal/useId.js";
|
|
13
13
|
import { deprecate } from "../../prop-types/deprecate.js";
|
|
14
14
|
import { defaultItemToString } from "../../internal/defaultItemToString.js";
|
|
15
|
+
import { isItemDisabled } from "../../internal/isItemDisabled.js";
|
|
15
16
|
import { isComponentElement } from "../../internal/utils.js";
|
|
16
17
|
import { hasHelperText } from "../../internal/hasHelperText.js";
|
|
17
18
|
import { useNormalizedInputProps } from "../../internal/useNormalizedInputProps.js";
|
|
@@ -43,7 +44,7 @@ import isEqual from "react-fast-compare";
|
|
|
43
44
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
44
45
|
* LICENSE file in the root directory of this source tree.
|
|
45
46
|
*/
|
|
46
|
-
const { InputBlur, InputKeyDownEnter, ItemClick, MenuMouseLeave, InputKeyDownArrowUp, InputKeyDownArrowDown, ItemMouseMove, InputClick, ToggleButtonClick, FunctionToggleMenu, InputChange, InputKeyDownEscape, FunctionSetHighlightedIndex } = useCombobox.stateChangeTypes;
|
|
47
|
+
const { InputBlur, InputKeyDownEnter, ItemClick, MenuMouseLeave, InputKeyDownArrowUp, InputKeyDownArrowDown, ItemMouseMove, InputClick, ToggleButtonClick, FunctionToggleMenu, InputChange, InputKeyDownEscape, FunctionSetHighlightedIndex, FunctionSetInputValue } = useCombobox.stateChangeTypes;
|
|
47
48
|
const { SelectedItemKeyDownBackspace, SelectedItemKeyDownDelete, DropdownKeyDownBackspace, FunctionRemoveSelectedItem } = useMultipleSelection.stateChangeTypes;
|
|
48
49
|
const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAlign = false, className: containerClassName, clearSelectionDescription = "Total items selected: ", clearSelectionText = "To clear selection, press Delete or Backspace", compareItems = defaultCompareItems, decorator, direction = "bottom", disabled = false, downshiftProps, filterItems = defaultFilterItems, helperText, hideLabel, id, initialSelectedItems = [], invalid = false, invalidText, items, itemToElement: ItemToElement, itemToString = defaultItemToString, light, locale = "en", onInputValueChange, open = false, onChange, onMenuChange, placeholder, readOnly, titleText, type, selectionFeedback = "top-after-reopen", selectedItems: selected, size: size$1, sortItems = defaultSortItems, translateWithId, useTitleInItem, warn = false, warnText, slug, inputProps }, ref) {
|
|
49
50
|
const { isFluid } = useContext(FormContext);
|
|
@@ -72,7 +73,7 @@ const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAl
|
|
|
72
73
|
filteredItems
|
|
73
74
|
});
|
|
74
75
|
const selectAllStatus = useMemo(() => {
|
|
75
|
-
const selectable = nonSelectAllItems.filter((item) => !item
|
|
76
|
+
const selectable = nonSelectAllItems.filter((item) => !isItemDisabled(item));
|
|
76
77
|
const nonSelectedCount = selectable.filter((item) => !controlledSelectedItems.some((sel) => isEqual(sel, item))).length;
|
|
77
78
|
const totalCount = selectable.length;
|
|
78
79
|
return {
|
|
@@ -81,7 +82,7 @@ const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAl
|
|
|
81
82
|
};
|
|
82
83
|
}, [controlledSelectedItems, nonSelectAllItems]);
|
|
83
84
|
const handleSelectAllClick = useCallback(() => {
|
|
84
|
-
const selectable = nonSelectAllItems.filter((
|
|
85
|
+
const selectable = nonSelectAllItems.filter((item) => !isItemDisabled(item));
|
|
85
86
|
const { checked, indeterminate } = selectAllStatus;
|
|
86
87
|
if (checked || indeterminate) toggleAll(controlledSelectedItems.filter((sel) => !filteredItems.some((e) => isEqual(e, sel))));
|
|
87
88
|
else {
|
|
@@ -131,7 +132,7 @@ const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAl
|
|
|
131
132
|
}, [open]);
|
|
132
133
|
const sortedItems = useMemo(() => {
|
|
133
134
|
const selectAllItem = items.find(isSelectAllItem);
|
|
134
|
-
const selectableRealItems = nonSelectAllItems.filter((item) => !item
|
|
135
|
+
const selectableRealItems = nonSelectAllItems.filter((item) => !isItemDisabled(item));
|
|
135
136
|
const sortedReal = sortItems(nonSelectAllItems, {
|
|
136
137
|
selectedItems: {
|
|
137
138
|
top: controlledSelectedItems,
|
|
@@ -255,9 +256,7 @@ const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAl
|
|
|
255
256
|
inputId,
|
|
256
257
|
inputValue,
|
|
257
258
|
stateReducer,
|
|
258
|
-
isItemDisabled
|
|
259
|
-
return item?.disabled;
|
|
260
|
-
}
|
|
259
|
+
isItemDisabled
|
|
261
260
|
});
|
|
262
261
|
function stateReducer(state, actionAndChanges) {
|
|
263
262
|
const { type, props, changes } = actionAndChanges;
|
|
@@ -266,7 +265,7 @@ const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAl
|
|
|
266
265
|
switch (type) {
|
|
267
266
|
case InputKeyDownEnter:
|
|
268
267
|
if (sortedItems.length === 0) return changes;
|
|
269
|
-
if (changes.selectedItem && changes.selectedItem
|
|
268
|
+
if (changes.selectedItem && !isItemDisabled(changes.selectedItem)) if (isSelectAllItem(changes.selectedItem)) handleSelectAllClick();
|
|
270
269
|
else onItemChange(changes.selectedItem);
|
|
271
270
|
setHighlightedIndex(changes.selectedItem);
|
|
272
271
|
return {
|
|
@@ -365,8 +364,15 @@ const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAl
|
|
|
365
364
|
});
|
|
366
365
|
function clearInputValue(event) {
|
|
367
366
|
const value = textInput.current?.value;
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
const isEscape = event && "key" in event && match(event, Escape);
|
|
368
|
+
const isClick = value && !(event && "key" in event);
|
|
369
|
+
if (value?.length === 1 || isEscape || isClick) {
|
|
370
|
+
setInputValue("");
|
|
371
|
+
onInputValueChange?.({
|
|
372
|
+
inputValue: "",
|
|
373
|
+
type: FunctionSetInputValue
|
|
374
|
+
});
|
|
375
|
+
} else setInputValue(value ?? "");
|
|
370
376
|
if (textInput.current) textInput.current.focus();
|
|
371
377
|
}
|
|
372
378
|
const candidate = slug ?? decorator;
|
|
@@ -509,6 +515,9 @@ const FilterableMultiSelect = forwardRef(function FilterableMultiSelect({ autoAl
|
|
|
509
515
|
disabled,
|
|
510
516
|
translateWithId,
|
|
511
517
|
readOnly,
|
|
518
|
+
onMouseDown: (event) => {
|
|
519
|
+
event.preventDefault();
|
|
520
|
+
},
|
|
512
521
|
onMouseUp: (event) => {
|
|
513
522
|
event.stopPropagation();
|
|
514
523
|
}
|
|
@@ -13,6 +13,7 @@ import { useId } from "../../internal/useId.js";
|
|
|
13
13
|
import { noopFn } from "../../internal/noopFn.js";
|
|
14
14
|
import { deprecate } from "../../prop-types/deprecate.js";
|
|
15
15
|
import { defaultItemToString } from "../../internal/defaultItemToString.js";
|
|
16
|
+
import { isItemDisabled } from "../../internal/isItemDisabled.js";
|
|
16
17
|
import { isComponentElement } from "../../internal/utils.js";
|
|
17
18
|
import { useFeatureFlag } from "../FeatureFlags/index.js";
|
|
18
19
|
import { useNormalizedInputProps } from "../../internal/useNormalizedInputProps.js";
|
|
@@ -114,9 +115,7 @@ const MultiSelect = React.forwardRef(({ autoAlign = false, className: containerC
|
|
|
114
115
|
},
|
|
115
116
|
selectedItem: controlledSelectedItems,
|
|
116
117
|
items: filteredItems,
|
|
117
|
-
isItemDisabled
|
|
118
|
-
return item?.disabled;
|
|
119
|
-
},
|
|
118
|
+
isItemDisabled,
|
|
120
119
|
...downshiftProps
|
|
121
120
|
});
|
|
122
121
|
const toggleButtonProps = getToggleButtonProps({
|
|
@@ -298,7 +297,7 @@ const MultiSelect = React.forwardRef(({ autoAlign = false, className: containerC
|
|
|
298
297
|
return {
|
|
299
298
|
hasIndividualSelections: selectedItems.some((selected) => !isSelectAllItem(selected)),
|
|
300
299
|
nonSelectAllSelectedCount: selectedItems.filter((selected) => !isSelectAllItem(selected)).length,
|
|
301
|
-
totalSelectableCount: filteredItems.filter((item) => !isSelectAllItem(item) && !item
|
|
300
|
+
totalSelectableCount: filteredItems.filter((item) => !isSelectAllItem(item) && !isItemDisabled(item)).length
|
|
302
301
|
};
|
|
303
302
|
}, [selectedItems, filteredItems]);
|
|
304
303
|
return /* @__PURE__ */ jsxs("div", {
|