@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.
Files changed (53) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +935 -935
  2. package/es/components/ComboBox/ComboBox.js +7 -7
  3. package/es/components/DatePicker/DatePicker.js +1 -2
  4. package/es/components/DatePicker/plugins/fixEventsPlugin.d.ts +2 -5
  5. package/es/components/DatePicker/plugins/fixEventsPlugin.js +5 -12
  6. package/es/components/Dropdown/Dropdown.js +1 -4
  7. package/es/components/FeatureFlags/index.d.ts +3 -1
  8. package/es/components/FeatureFlags/index.js +36 -14
  9. package/es/components/IconIndicator/index.d.ts +33 -1
  10. package/es/components/IconIndicator/index.js +55 -26
  11. package/es/components/ListBox/next/ListBoxSelection.d.ts +12 -2
  12. package/es/components/ListBox/next/ListBoxSelection.js +7 -2
  13. package/es/components/Modal/Modal.js +2 -2
  14. package/es/components/MultiSelect/FilterableMultiSelect.js +19 -10
  15. package/es/components/MultiSelect/MultiSelect.js +3 -4
  16. package/es/components/OverflowMenu/OverflowMenu.js +31 -6
  17. package/es/components/OverflowMenu/next/index.d.ts +1 -1
  18. package/es/components/OverflowMenu/next/index.js +2 -2
  19. package/es/components/ShapeIndicator/index.d.ts +18 -0
  20. package/es/components/ShapeIndicator/index.js +49 -7
  21. package/es/components/Tabs/Tabs.js +1 -1
  22. package/es/components/Tooltip/DefinitionTooltip.js +5 -2
  23. package/es/feature-flags.js +1 -0
  24. package/es/internal/index.d.ts +2 -1
  25. package/es/internal/isItemDisabled.d.ts +7 -0
  26. package/es/internal/isItemDisabled.js +17 -0
  27. package/lib/components/ComboBox/ComboBox.js +7 -7
  28. package/lib/components/DatePicker/DatePicker.js +1 -2
  29. package/lib/components/DatePicker/plugins/fixEventsPlugin.d.ts +2 -5
  30. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +5 -12
  31. package/lib/components/Dropdown/Dropdown.js +2 -5
  32. package/lib/components/FeatureFlags/index.d.ts +3 -1
  33. package/lib/components/FeatureFlags/index.js +36 -14
  34. package/lib/components/IconIndicator/index.d.ts +33 -1
  35. package/lib/components/IconIndicator/index.js +54 -25
  36. package/lib/components/ListBox/next/ListBoxSelection.d.ts +12 -2
  37. package/lib/components/ListBox/next/ListBoxSelection.js +7 -2
  38. package/lib/components/Modal/Modal.js +2 -2
  39. package/lib/components/MultiSelect/FilterableMultiSelect.js +19 -10
  40. package/lib/components/MultiSelect/MultiSelect.js +3 -4
  41. package/lib/components/OverflowMenu/OverflowMenu.js +30 -5
  42. package/lib/components/OverflowMenu/next/index.d.ts +1 -1
  43. package/lib/components/OverflowMenu/next/index.js +2 -2
  44. package/lib/components/ShapeIndicator/index.d.ts +18 -0
  45. package/lib/components/ShapeIndicator/index.js +48 -6
  46. package/lib/components/Tabs/Tabs.js +1 -1
  47. package/lib/components/Tooltip/DefinitionTooltip.js +4 -1
  48. package/lib/feature-flags.js +1 -0
  49. package/lib/internal/index.d.ts +2 -1
  50. package/lib/internal/isItemDisabled.d.ts +7 -0
  51. package/lib/internal/isItemDisabled.js +17 -0
  52. package/package.json +15 -11
  53. 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 (!isDisabledItem(items[i]) && item.indexOf(searchValue) !== -1) return i;
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) => !isDisabledItem(item) && autocompleteCustomFilter({
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 && !isDisabledItem(highlightedItem)) return {
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 && !isDisabledItem(matchingItem)) return {
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: isDisabledItem,
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) => !isDisabledItem(item) && itemToString(item).toLowerCase().startsWith(inputValue.toLowerCase()));
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 default fixEventsPlugin;
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, lastStartValue, container } = config;
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 = getEventPath(event);
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)) || fp.calendarContainer && (path.includes(fp.calendarContainer) || fp.calendarContainer.contains(target)) || inputFrom && (path.includes(inputFrom) || inputFrom.contains(target)) || inputTo && (path.includes(inputTo) || inputTo.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 as default };
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 = {}, enableV12TileDefaultIcons = false, enableV12TileRadioIcons = false, enableV12Overflowmenu = false, enableTreeviewControllable = false, enableExperimentalFocusWrapWithoutSentinels = false, enableFocusWrapWithoutSentinels = false, enableDialogElement = false, enableV12DynamicFloatingStyles = false, enableEnhancedFileUploader = false, enablePresence = false }) => {
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 scope = createScope({
34
- "enable-v12-tile-default-icons": enableV12TileDefaultIcons,
35
- "enable-v12-tile-radio-icons": enableV12TileRadioIcons,
36
- "enable-v12-overflowmenu": enableV12Overflowmenu,
37
- "enable-treeview-controllable": enableTreeviewControllable,
38
- "enable-experimental-focus-wrap-without-sentinels": enableExperimentalFocusWrapWithoutSentinels,
39
- "enable-focus-wrap-without-sentinels": enableFocusWrapWithoutSentinels,
40
- "enable-dialog-element": enableDialogElement,
41
- "enable-v12-dynamic-floating-styles": enableV12DynamicFloatingStyles,
42
- "enable-enhanced-file-uploader": enableEnhancedFileUploader,
43
- "enable-presence": enablePresence,
44
- ...flags
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
- export declare const IconIndicatorKinds: string[];
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
- ["caution-major"]: WarningAltInvertedFilled,
38
- ["caution-minor"]: WarningAltFilled,
24
+ "caution-major": WarningAltInvertedFilled,
25
+ "caution-minor": WarningAltFilled,
39
26
  undefined: UndefinedFilled,
40
27
  succeeded: CheckmarkFilled,
41
28
  normal: CheckmarkOutline,
42
- ["in-progress"]: InProgress,
29
+ "in-progress": InProgress,
43
30
  incomplete: Incomplete,
44
- ["not-started"]: CircleDash,
31
+ "not-started": CircleDash,
45
32
  pending: PendingFilled,
46
33
  unknown: UnknownFilled,
47
34
  informative: WarningSquareFilled
48
35
  };
49
- const IconIndicator = React.forwardRef(({ className: customClassName, kind, label, size = 16 }, ref) => {
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 == 20 });
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
- return /* @__PURE__ */ jsxs("div", {
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: [/* @__PURE__ */ jsx(IconForKind, {
58
- size,
59
- className: `${prefix}--icon-indicator--${kind}`
60
- }), label]
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 `onClick` handler that is called when the underlying
88
- * clear selection element is clicked
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 `onClick` handler that is called when the underlying
110
- * clear selection element is clicked
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.disabled);
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((i) => !i.disabled);
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.disabled);
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(item) {
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.disabled !== true) if (isSelectAllItem(changes.selectedItem)) handleSelectAllClick();
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
- if (value?.length === 1 || event && "key" in event && match(event, Escape)) setInputValue("");
369
- else setInputValue(value ?? "");
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(item) {
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.disabled).length
300
+ totalSelectableCount: filteredItems.filter((item) => !isSelectAllItem(item) && !isItemDisabled(item)).length
302
301
  };
303
302
  }, [selectedItems, filteredItems]);
304
303
  return /* @__PURE__ */ jsxs("div", {