@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
@@ -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
  */
@@ -7,6 +7,7 @@
7
7
 
8
8
  const require_runtime = require("../../_virtual/_rolldown/runtime.js");
9
9
  const require_usePrefix = require("../../internal/usePrefix.js");
10
+ const require_DefinitionTooltip = require("../Tooltip/DefinitionTooltip.js");
10
11
  let classnames = require("classnames");
11
12
  classnames = require_runtime.__toESM(classnames);
12
13
  let react = require("react");
@@ -22,54 +23,82 @@ let _carbon_icons_react = require("@carbon/icons-react");
22
23
  * This source code is licensed under the Apache-2.0 license found in the
23
24
  * LICENSE file in the root directory of this source tree.
24
25
  */
25
- const IconIndicatorKinds = [
26
- "failed",
27
- "caution-major",
28
- "caution-minor",
29
- "undefined",
30
- "succeeded",
31
- "normal",
32
- "in-progress",
33
- "incomplete",
34
- "not-started",
35
- "pending",
36
- "unknown",
37
- "informative"
38
- ];
39
26
  const iconTypes = {
40
27
  failed: _carbon_icons_react.ErrorFilled,
41
- ["caution-major"]: _carbon_icons_react.WarningAltInvertedFilled,
42
- ["caution-minor"]: _carbon_icons_react.WarningAltFilled,
28
+ "caution-major": _carbon_icons_react.WarningAltInvertedFilled,
29
+ "caution-minor": _carbon_icons_react.WarningAltFilled,
43
30
  undefined: _carbon_icons_react.UndefinedFilled,
44
31
  succeeded: _carbon_icons_react.CheckmarkFilled,
45
32
  normal: _carbon_icons_react.CheckmarkOutline,
46
- ["in-progress"]: _carbon_icons_react.InProgress,
33
+ "in-progress": _carbon_icons_react.InProgress,
47
34
  incomplete: _carbon_icons_react.Incomplete,
48
- ["not-started"]: _carbon_icons_react.CircleDash,
35
+ "not-started": _carbon_icons_react.CircleDash,
49
36
  pending: _carbon_icons_react.PendingFilled,
50
37
  unknown: _carbon_icons_react.UnknownFilled,
51
38
  informative: _carbon_icons_react.WarningSquareFilled
52
39
  };
53
- const IconIndicator = react.default.forwardRef(({ className: customClassName, kind, label, size = 16 }, ref) => {
40
+ const IconIndicatorKinds = Object.keys(iconTypes);
41
+ const IconIndicator = react.default.forwardRef(({ align = "right", autoAlign = false, className: customClassName, compact = false, iconDescription, kind, label, size = 16 }, ref) => {
54
42
  const prefix = require_usePrefix.usePrefix();
55
- const classNames = (0, classnames.default)(`${prefix}--icon-indicator`, customClassName, { [`${prefix}--icon-indicator--20`]: size == 20 });
43
+ const classNames = (0, classnames.default)(`${prefix}--icon-indicator`, customClassName, { [`${prefix}--icon-indicator--20`]: size === 20 });
56
44
  const IconForKind = iconTypes[kind];
57
45
  if (!IconForKind) return null;
58
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
46
+ const iconElement = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconForKind, {
47
+ size,
48
+ className: `${prefix}--icon-indicator--${kind}`
49
+ });
50
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
59
51
  className: classNames,
60
52
  ref,
61
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconForKind, {
62
- size,
63
- className: `${prefix}--icon-indicator--${kind}`
64
- }), label]
53
+ children: compact ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_DefinitionTooltip.DefinitionTooltip, {
54
+ align,
55
+ autoAlign,
56
+ openOnHover: true,
57
+ definition: label,
58
+ triggerClassName: `${prefix}--icon-indicator__button`,
59
+ children: [iconElement, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
60
+ className: `${prefix}--visually-hidden`,
61
+ children: iconDescription ?? label
62
+ })]
63
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [iconElement, label] })
65
64
  });
66
65
  });
67
66
  IconIndicator.propTypes = {
67
+ /**
68
+ * Specify how the tooltip should align with the icon in compact mode
69
+ */
70
+ align: prop_types.default.oneOf([
71
+ "top",
72
+ "top-start",
73
+ "top-end",
74
+ "bottom",
75
+ "bottom-start",
76
+ "bottom-end",
77
+ "left",
78
+ "left-start",
79
+ "left-end",
80
+ "right",
81
+ "right-start",
82
+ "right-end"
83
+ ]),
84
+ /**
85
+ * Will auto-align the tooltip in compact mode
86
+ */
87
+ autoAlign: prop_types.default.bool,
68
88
  /**
69
89
  * Specify an optional className to add.
70
90
  */
71
91
  className: prop_types.default.string,
72
92
  /**
93
+ * When true, displays only the icon with the label in a tooltip
94
+ */
95
+ compact: prop_types.default.bool,
96
+ /**
97
+ * Description for the icon announced to screen readers in compact mode.
98
+ * Defaults to `label` when not provided.
99
+ */
100
+ iconDescription: prop_types.default.string,
101
+ /**
73
102
  * Specify the kind of the Icon Indicator
74
103
  */
75
104
  kind: prop_types.default.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
  /**
@@ -110,8 +110,13 @@ ListBoxSelection.propTypes = {
110
110
  */
111
111
  onClick: prop_types.default.func,
112
112
  /**
113
- * Specify an optional `onClick` handler that is called when the underlying
114
- * clear selection element is clicked
113
+ * Specify an optional `onMouseDown` handler that is called when the underlying
114
+ * clear selection element fires a mousedown event
115
+ */
116
+ onMouseDown: prop_types.default.func,
117
+ /**
118
+ * Specify an optional `onMouseUp` handler that is called when the underlying
119
+ * clear selection element fires a mouseup event
115
120
  */
116
121
  onMouseUp: prop_types.default.func,
117
122
  /**
@@ -306,8 +306,8 @@ const ModalDialog = react.default.forwardRef(function ModalDialog({ "aria-label"
306
306
  focusAfterCloseRef: launcherButtonRef,
307
307
  modal: true,
308
308
  ref: innerModal,
309
- role: isAlertDialog ? "alertdialog" : "",
310
- "aria-describedby": isAlertDialog ? modalBodyId : "",
309
+ role: isAlertDialog ? "alertdialog" : void 0,
310
+ "aria-describedby": isAlertDialog ? modalBodyId : void 0,
311
311
  className: containerClasses,
312
312
  "aria-label": ariaLabel,
313
313
  "data-exiting": presenceContext?.isExiting || void 0,
@@ -13,6 +13,7 @@ const require_useIsomorphicEffect = require("../../internal/useIsomorphicEffect.
13
13
  const require_useId = require("../../internal/useId.js");
14
14
  const require_deprecate = require("../../prop-types/deprecate.js");
15
15
  const require_defaultItemToString = require("../../internal/defaultItemToString.js");
16
+ const require_isItemDisabled = require("../../internal/isItemDisabled.js");
16
17
  const require_utils = require("../../internal/utils.js");
17
18
  const require_hasHelperText = require("../../internal/hasHelperText.js");
18
19
  const require_useNormalizedInputProps = require("../../internal/useNormalizedInputProps.js");
@@ -49,7 +50,7 @@ react_fast_compare = require_runtime.__toESM(react_fast_compare);
49
50
  * This source code is licensed under the Apache-2.0 license found in the
50
51
  * LICENSE file in the root directory of this source tree.
51
52
  */
52
- const { InputBlur, InputKeyDownEnter, ItemClick, MenuMouseLeave, InputKeyDownArrowUp, InputKeyDownArrowDown, ItemMouseMove, InputClick, ToggleButtonClick, FunctionToggleMenu, InputChange, InputKeyDownEscape, FunctionSetHighlightedIndex } = downshift.useCombobox.stateChangeTypes;
53
+ const { InputBlur, InputKeyDownEnter, ItemClick, MenuMouseLeave, InputKeyDownArrowUp, InputKeyDownArrowDown, ItemMouseMove, InputClick, ToggleButtonClick, FunctionToggleMenu, InputChange, InputKeyDownEscape, FunctionSetHighlightedIndex, FunctionSetInputValue } = downshift.useCombobox.stateChangeTypes;
53
54
  const { SelectedItemKeyDownBackspace, SelectedItemKeyDownDelete, DropdownKeyDownBackspace, FunctionRemoveSelectedItem } = downshift.useMultipleSelection.stateChangeTypes;
54
55
  const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSelect({ autoAlign = false, className: containerClassName, clearSelectionDescription = "Total items selected: ", clearSelectionText = "To clear selection, press Delete or Backspace", compareItems = require_sorting.defaultCompareItems, decorator, direction = "bottom", disabled = false, downshiftProps, filterItems = require_filter.defaultFilterItems, helperText, hideLabel, id, initialSelectedItems = [], invalid = false, invalidText, items, itemToElement: ItemToElement, itemToString = require_defaultItemToString.defaultItemToString, light, locale = "en", onInputValueChange, open = false, onChange, onMenuChange, placeholder, readOnly, titleText, type, selectionFeedback = "top-after-reopen", selectedItems: selected, size, sortItems = require_sorting.defaultSortItems, translateWithId, useTitleInItem, warn = false, warnText, slug, inputProps }, ref) {
55
56
  const { isFluid } = (0, react.useContext)(require_FormContext.FormContext);
@@ -78,7 +79,7 @@ const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSele
78
79
  filteredItems
79
80
  });
80
81
  const selectAllStatus = (0, react.useMemo)(() => {
81
- const selectable = nonSelectAllItems.filter((item) => !item.disabled);
82
+ const selectable = nonSelectAllItems.filter((item) => !require_isItemDisabled.isItemDisabled(item));
82
83
  const nonSelectedCount = selectable.filter((item) => !controlledSelectedItems.some((sel) => (0, react_fast_compare.default)(sel, item))).length;
83
84
  const totalCount = selectable.length;
84
85
  return {
@@ -87,7 +88,7 @@ const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSele
87
88
  };
88
89
  }, [controlledSelectedItems, nonSelectAllItems]);
89
90
  const handleSelectAllClick = (0, react.useCallback)(() => {
90
- const selectable = nonSelectAllItems.filter((i) => !i.disabled);
91
+ const selectable = nonSelectAllItems.filter((item) => !require_isItemDisabled.isItemDisabled(item));
91
92
  const { checked, indeterminate } = selectAllStatus;
92
93
  if (checked || indeterminate) toggleAll(controlledSelectedItems.filter((sel) => !filteredItems.some((e) => (0, react_fast_compare.default)(e, sel))));
93
94
  else {
@@ -137,7 +138,7 @@ const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSele
137
138
  }, [open]);
138
139
  const sortedItems = (0, react.useMemo)(() => {
139
140
  const selectAllItem = items.find(require_isSelectAllItem.isSelectAllItem);
140
- const selectableRealItems = nonSelectAllItems.filter((item) => !item.disabled);
141
+ const selectableRealItems = nonSelectAllItems.filter((item) => !require_isItemDisabled.isItemDisabled(item));
141
142
  const sortedReal = sortItems(nonSelectAllItems, {
142
143
  selectedItems: {
143
144
  top: controlledSelectedItems,
@@ -261,9 +262,7 @@ const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSele
261
262
  inputId,
262
263
  inputValue,
263
264
  stateReducer,
264
- isItemDisabled(item) {
265
- return item?.disabled;
266
- }
265
+ isItemDisabled: require_isItemDisabled.isItemDisabled
267
266
  });
268
267
  function stateReducer(state, actionAndChanges) {
269
268
  const { type, props, changes } = actionAndChanges;
@@ -272,7 +271,7 @@ const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSele
272
271
  switch (type) {
273
272
  case InputKeyDownEnter:
274
273
  if (sortedItems.length === 0) return changes;
275
- if (changes.selectedItem && changes.selectedItem.disabled !== true) if (require_isSelectAllItem.isSelectAllItem(changes.selectedItem)) handleSelectAllClick();
274
+ if (changes.selectedItem && !require_isItemDisabled.isItemDisabled(changes.selectedItem)) if (require_isSelectAllItem.isSelectAllItem(changes.selectedItem)) handleSelectAllClick();
276
275
  else onItemChange(changes.selectedItem);
277
276
  setHighlightedIndex(changes.selectedItem);
278
277
  return {
@@ -371,8 +370,15 @@ const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSele
371
370
  });
372
371
  function clearInputValue(event) {
373
372
  const value = textInput.current?.value;
374
- if (value?.length === 1 || event && "key" in event && require_match.match(event, require_keys.Escape)) setInputValue("");
375
- else setInputValue(value ?? "");
373
+ const isEscape = event && "key" in event && require_match.match(event, require_keys.Escape);
374
+ const isClick = value && !(event && "key" in event);
375
+ if (value?.length === 1 || isEscape || isClick) {
376
+ setInputValue("");
377
+ onInputValueChange?.({
378
+ inputValue: "",
379
+ type: FunctionSetInputValue
380
+ });
381
+ } else setInputValue(value ?? "");
376
382
  if (textInput.current) textInput.current.focus();
377
383
  }
378
384
  const candidate = slug ?? decorator;
@@ -515,6 +521,9 @@ const FilterableMultiSelect = (0, react.forwardRef)(function FilterableMultiSele
515
521
  disabled,
516
522
  translateWithId,
517
523
  readOnly,
524
+ onMouseDown: (event) => {
525
+ event.preventDefault();
526
+ },
518
527
  onMouseUp: (event) => {
519
528
  event.stopPropagation();
520
529
  }
@@ -14,6 +14,7 @@ const require_useId = require("../../internal/useId.js");
14
14
  const require_noopFn = require("../../internal/noopFn.js");
15
15
  const require_deprecate = require("../../prop-types/deprecate.js");
16
16
  const require_defaultItemToString = require("../../internal/defaultItemToString.js");
17
+ const require_isItemDisabled = require("../../internal/isItemDisabled.js");
17
18
  const require_utils = require("../../internal/utils.js");
18
19
  const require_index = require("../FeatureFlags/index.js");
19
20
  const require_useNormalizedInputProps = require("../../internal/useNormalizedInputProps.js");
@@ -119,9 +120,7 @@ const MultiSelect = react.default.forwardRef(({ autoAlign = false, className: co
119
120
  },
120
121
  selectedItem: controlledSelectedItems,
121
122
  items: filteredItems,
122
- isItemDisabled(item) {
123
- return item?.disabled;
124
- },
123
+ isItemDisabled: require_isItemDisabled.isItemDisabled,
125
124
  ...downshiftProps
126
125
  });
127
126
  const toggleButtonProps = getToggleButtonProps({
@@ -303,7 +302,7 @@ const MultiSelect = react.default.forwardRef(({ autoAlign = false, className: co
303
302
  return {
304
303
  hasIndividualSelections: selectedItems.some((selected) => !require_isSelectAllItem.isSelectAllItem(selected)),
305
304
  nonSelectAllSelectedCount: selectedItems.filter((selected) => !require_isSelectAllItem.isSelectAllItem(selected)).length,
306
- totalSelectableCount: filteredItems.filter((item) => !require_isSelectAllItem.isSelectAllItem(item) && !item.disabled).length
305
+ totalSelectableCount: filteredItems.filter((item) => !require_isSelectAllItem.isSelectAllItem(item) && !require_isItemDisabled.isItemDisabled(item)).length
307
306
  };
308
307
  }, [selectedItems, filteredItems]);
309
308
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -86,7 +86,7 @@ const getMenuOffset = (menuBody, direction, trigger, flip) => {
86
86
  };
87
87
  }
88
88
  };
89
- const OverflowMenu = (0, react.forwardRef)(({ align, ["aria-label"]: ariaLabel = null, ariaLabel: deprecatedAriaLabel, children, className, direction = require_FloatingMenu.DIRECTION_BOTTOM, flipped = false, focusTrap = false, iconClass, iconDescription = "Options", id, light, menuOffset = getMenuOffset, menuOffsetFlip = getMenuOffset, menuOptionsClass, onClick = require_noopFn.noopFn, onClose = require_noopFn.noopFn, onOpen = require_noopFn.noopFn, open: openProp, renderIcon: IconElement = _carbon_icons_react.OverflowMenuVertical, selectorPrimaryFocus = "[data-floating-menu-primary-focus]", size = "md", innerRef, ...other }, ref) => {
89
+ const OverflowMenu = (0, react.forwardRef)(({ align, ["aria-label"]: ariaLabel = null, ariaLabel: deprecatedAriaLabel, children, className, direction = require_FloatingMenu.DIRECTION_BOTTOM, flipped = false, focusTrap = false, iconClass, iconDescription = "Options", id, light, menuOffset = getMenuOffset, menuOffsetFlip = getMenuOffset, menuOptionsClass, onClick = require_noopFn.noopFn, onClose = require_noopFn.noopFn, onOpen = require_noopFn.noopFn, open: openProp, renderIcon: IconElement = _carbon_icons_react.OverflowMenuVertical, selectorPrimaryFocus = "[data-floating-menu-primary-focus]", size, innerRef, ...other }, ref) => {
90
90
  const prefix = (0, react.useContext)(require_usePrefix.PrefixContext);
91
91
  const [open, setOpen] = (0, react.useState)(openProp ?? false);
92
92
  const [click, setClick] = (0, react.useState)(false);
@@ -101,6 +101,8 @@ const OverflowMenu = (0, react.forwardRef)(({ align, ["aria-label"]: ariaLabel =
101
101
  /** The element ref of the tooltip's trigger button. */
102
102
  const triggerRef = (0, react.useRef)(null);
103
103
  const wrapperRef = (0, react.useRef)(null);
104
+ const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
105
+ const resizeObserverRef = (0, react.useRef)(null);
104
106
  (0, react.useEffect)(() => {
105
107
  if (prevOpenProp.current !== openProp) {
106
108
  setOpen(!!openProp);
@@ -110,6 +112,26 @@ const OverflowMenu = (0, react.forwardRef)(({ align, ["aria-label"]: ariaLabel =
110
112
  (0, react.useEffect)(() => {
111
113
  if (triggerRef.current) setHasMountedTrigger(true);
112
114
  }, []);
115
+ /**
116
+ * When `size` is brought in from a contextual layout token, FloatingMenu can't detect size changes
117
+ * while the menu is open since there is no state/prop update. This ResizeObserver watches
118
+ * the trigger button when the menu is open and calls `forceUpdate()` on resize to force a re-render if its
119
+ * size changes while the menu is open
120
+ */
121
+ (0, react.useEffect)(() => {
122
+ resizeObserverRef.current = new ResizeObserver(() => {
123
+ forceUpdate();
124
+ });
125
+ return () => {
126
+ resizeObserverRef.current?.disconnect();
127
+ resizeObserverRef.current = null;
128
+ };
129
+ }, []);
130
+ (0, react.useEffect)(() => {
131
+ if (!triggerRef.current || !resizeObserverRef.current) return;
132
+ if (open) resizeObserverRef.current.observe(triggerRef.current);
133
+ else resizeObserverRef.current.disconnect();
134
+ }, [open]);
113
135
  (0, react.useEffect)(() => {
114
136
  if (open && !prevOpenState.current) onOpen();
115
137
  else if (!open && prevOpenState.current) onClose();
@@ -210,22 +232,25 @@ const OverflowMenu = (0, react.forwardRef)(({ align, ["aria-label"]: ariaLabel =
210
232
  };
211
233
  const getTarget = () => {
212
234
  const triggerEl = triggerRef.current;
213
- if (triggerEl instanceof Element) return triggerEl.closest("[data-floating-menu-container]") || document.body;
235
+ if (triggerEl instanceof Element) return triggerEl.closest("[data-floating-menu-container]") || triggerEl.closest(`.${prefix}--layout`) || document.body;
214
236
  return document.body;
215
237
  };
216
238
  const menuBodyId = `overflow-menu-${instanceId.current}__menu-body`;
217
239
  const overflowMenuClasses = (0, classnames.default)(className, `${prefix}--overflow-menu`, {
218
240
  [`${prefix}--overflow-menu--open`]: open,
219
241
  [`${prefix}--overflow-menu--light`]: light,
220
- [`${prefix}--overflow-menu--${size}`]: size
242
+ [`${prefix}--overflow-menu--${size}`]: size,
243
+ [`${prefix}--layout--size-${size}`]: size
221
244
  });
222
245
  const overflowMenuOptionsClasses = (0, classnames.default)(menuOptionsClass, `${prefix}--overflow-menu-options`, {
223
246
  [`${prefix}--overflow-menu--flip`]: flipped,
224
247
  [`${prefix}--overflow-menu-options--open`]: open,
225
248
  [`${prefix}--overflow-menu-options--light`]: light,
226
- [`${prefix}--overflow-menu-options--${size}`]: size
249
+ [`${prefix}--overflow-menu-options--${size}`]: size,
250
+ [`${prefix}--layout--size-${size}`]: size
227
251
  });
228
252
  const overflowMenuIconClasses = (0, classnames.default)(`${prefix}--overflow-menu__icon`, iconClass);
253
+ const overflowMenuWrapperClasses = (0, classnames.default)(`${prefix}--overflow-menu__wrapper`);
229
254
  const childrenWithProps = react.Children.toArray(children).map((child, index) => {
230
255
  if ((0, react.isValidElement)(child)) {
231
256
  const childElement = child;
@@ -262,7 +287,7 @@ const OverflowMenu = (0, react.forwardRef)(({ align, ["aria-label"]: ariaLabel =
262
287
  });
263
288
  const combinedRef = innerRef ? require_mergeRefs.mergeRefs(triggerRef, innerRef, ref) : require_mergeRefs.mergeRefs(triggerRef, ref);
264
289
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
265
- className: `${prefix}--overflow-menu__wrapper`,
290
+ className: overflowMenuWrapperClasses,
266
291
  "aria-owns": open ? menuBodyId : void 0,
267
292
  ref: wrapperRef,
268
293
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.IconButton, {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2020, 2025
2
+ * Copyright IBM Corp. 2020, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -26,7 +26,7 @@ let _carbon_icons_react = require("@carbon/icons-react");
26
26
  let _floating_ui_react = require("@floating-ui/react");
27
27
  //#region src/components/OverflowMenu/next/index.tsx
28
28
  /**
29
- * Copyright IBM Corp. 2020, 2025
29
+ * Copyright IBM Corp. 2020, 2026
30
30
  *
31
31
  * This source code is licensed under the Apache-2.0 license found in the
32
32
  * LICENSE file in the root directory of this source tree.
@@ -71,7 +71,7 @@ const OverflowMenu = react.default.forwardRef(({ autoAlign = false, children, cl
71
71
  }
72
72
  const containerClasses = (0, classnames.default)(className, `${prefix}--overflow-menu__container`, { [`${prefix}--autoalign`]: enableFloatingStyles });
73
73
  const menuClasses = (0, classnames.default)(`${prefix}--overflow-menu__${menuAlignment}`);
74
- const triggerClasses = (0, classnames.default)(`${prefix}--overflow-menu`, { [`${prefix}--overflow-menu--open`]: open }, size !== defaultSize && `${prefix}--overflow-menu--${size}`);
74
+ const triggerClasses = (0, classnames.default)(`${prefix}--overflow-menu`, { [`${prefix}--overflow-menu--open`]: open }, size !== defaultSize && `${prefix}--overflow-menu--${size}`, size !== defaultSize && `${prefix}--layout--size-${size}`);
75
75
  const floatingRef = require_mergeRefs.mergeRefs(triggerRef, refs.setReference);
76
76
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
77
77
  ...rest,
@@ -5,13 +5,26 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React from 'react';
8
+ import { PopoverAlignment } from '../Popover';
8
9
  export declare const ShapeIndicatorKinds: string[];
9
10
  export type ShapeIndicatorKind = (typeof ShapeIndicatorKinds)[number];
10
11
  export interface ShapeIndicatorProps {
12
+ /**
13
+ * Specify how the tooltip should align with the shape in compact mode
14
+ */
15
+ align?: PopoverAlignment;
16
+ /**
17
+ * Will auto-align the tooltip in compact mode.
18
+ */
19
+ autoAlign?: boolean;
11
20
  /**
12
21
  * Specify an optional className to add.
13
22
  */
14
23
  className?: string;
24
+ /**
25
+ * When true, displays only the shape with the label in a tooltip
26
+ */
27
+ compact?: boolean;
15
28
  /**
16
29
  * Specify the kind of shape to be used
17
30
  */
@@ -20,6 +33,11 @@ export interface ShapeIndicatorProps {
20
33
  * Label next to the shape
21
34
  */
22
35
  label: string;
36
+ /**
37
+ * Description for the shape announced to screen readers in compact mode.
38
+ * Defaults to `label` when not provided.
39
+ */
40
+ shapeDescription?: string;
23
41
  /**
24
42
  * Specify the text size of the Shape Indicator. Defaults to 12.
25
43
  */
@@ -7,6 +7,7 @@
7
7
 
8
8
  const require_runtime = require("../../_virtual/_rolldown/runtime.js");
9
9
  const require_usePrefix = require("../../internal/usePrefix.js");
10
+ const require_DefinitionTooltip = require("../Tooltip/DefinitionTooltip.js");
10
11
  let classnames = require("classnames");
11
12
  classnames = require_runtime.__toESM(classnames);
12
13
  let react = require("react");
@@ -65,26 +66,62 @@ const shapeTypes = {
65
66
  incomplete: incompleteIcon,
66
67
  draft: _carbon_icons_react.CircleStroke
67
68
  };
68
- const ShapeIndicator = react.default.forwardRef(({ className: customClassName, kind, label, textSize = 12 }, ref) => {
69
+ const ShapeIndicator = react.default.forwardRef(({ align = "right", autoAlign = false, className: customClassName, compact = false, kind, label, shapeDescription, textSize = 12 }, ref) => {
69
70
  const prefix = require_usePrefix.usePrefix();
70
71
  const classNames = (0, classnames.default)(`${prefix}--shape-indicator`, customClassName, { [`${prefix}--shape-indicator--14`]: textSize == 14 });
71
72
  const ShapeForKind = shapeTypes[kind];
72
73
  if (!ShapeForKind) return null;
73
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
74
+ const shapeElement = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShapeForKind, {
75
+ size: 16,
76
+ className: `${prefix}--shape-indicator--${kind}`
77
+ });
78
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
74
79
  className: classNames,
75
80
  ref,
76
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShapeForKind, {
77
- size: 16,
78
- className: `${prefix}--shape-indicator--${kind}`
79
- }), label]
81
+ children: compact ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_DefinitionTooltip.DefinitionTooltip, {
82
+ align,
83
+ autoAlign,
84
+ openOnHover: true,
85
+ definition: label,
86
+ triggerClassName: `${prefix}--shape-indicator__button`,
87
+ children: [shapeElement, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
88
+ className: `${prefix}--visually-hidden`,
89
+ children: shapeDescription ?? label
90
+ })]
91
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [shapeElement, label] })
80
92
  });
81
93
  });
82
94
  ShapeIndicator.propTypes = {
95
+ /**
96
+ * Specify how the tooltip should align with the shape in compact mode
97
+ */
98
+ align: prop_types.default.oneOf([
99
+ "top",
100
+ "top-start",
101
+ "top-end",
102
+ "bottom",
103
+ "bottom-start",
104
+ "bottom-end",
105
+ "left",
106
+ "left-start",
107
+ "left-end",
108
+ "right",
109
+ "right-start",
110
+ "right-end"
111
+ ]),
112
+ /**
113
+ * Will auto-align the tooltip in compact mode
114
+ */
115
+ autoAlign: prop_types.default.bool,
83
116
  /**
84
117
  * Specify an optional className to add.
85
118
  */
86
119
  className: prop_types.default.string,
87
120
  /**
121
+ * When true, displays only the shape with the label in a tooltip
122
+ */
123
+ compact: prop_types.default.bool,
124
+ /**
88
125
  * Specify the kind of the Shape Indicator
89
126
  */
90
127
  kind: prop_types.default.oneOf(ShapeIndicatorKinds).isRequired,
@@ -93,6 +130,11 @@ ShapeIndicator.propTypes = {
93
130
  */
94
131
  label: prop_types.default.string.isRequired,
95
132
  /**
133
+ * Description for the shape announced to screen readers in compact mode.
134
+ * Defaults to `label` when not provided.
135
+ */
136
+ shapeDescription: prop_types.default.string,
137
+ /**
96
138
  * Specify the text size of the Shape Indicator. Defaults to 12.
97
139
  */
98
140
  textSize: prop_types.default.oneOf([12, 14])
@@ -934,7 +934,7 @@ function TabPanels({ children }) {
934
934
  const isVertical = tabContainer?.classList.contains(`${prefix}--tabs--vertical`);
935
935
  const parentHasHeight = tabContainer?.parentElement?.style.height;
936
936
  if (isVertical && !parentHasHeight) {
937
- hiddenStates.current = refs.current.map((ref) => ref?.hidden || false);
937
+ hiddenStates.current = refs.current.map((ref) => ref?.hasAttribute("hidden") || false);
938
938
  refs.current.forEach((ref) => {
939
939
  if (ref) ref.hidden = false;
940
940
  });
@@ -31,7 +31,10 @@ const DefinitionTooltip = ({ align = "bottom", autoAlign, className, children, d
31
31
  const prefix = require_usePrefix.usePrefix();
32
32
  const tooltipId = require_useId.useFallbackId(id);
33
33
  function onKeyDown(event) {
34
- if (isOpen && require_match.match(event, require_keys.Escape)) {
34
+ if (require_match.match(event, require_keys.Enter) || require_match.match(event, require_keys.Space)) {
35
+ event.preventDefault();
36
+ setOpen(!isOpen);
37
+ } else if (isOpen && require_match.match(event, require_keys.Escape)) {
35
38
  event.stopPropagation();
36
39
  setOpen(false);
37
40
  }
@@ -16,6 +16,7 @@
16
16
  "enable-css-custom-properties": true,
17
17
  "enable-css-grid": true,
18
18
  "enable-v11-release": true,
19
+ "enable-v12-release": false,
19
20
  "enable-experimental-tile-contrast": false,
20
21
  "enable-tile-contrast": false,
21
22
  "enable-v12-tile-radio-icons": false,
@@ -1,8 +1,9 @@
1
1
  /**
2
- * Copyright IBM Corp. 2025
2
+ * Copyright IBM Corp. 2025, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  export * from './defaultItemToString';
8
+ export * from './isItemDisabled';
8
9
  export * from './utils';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright IBM Corp. 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ export declare const isItemDisabled: (item: unknown) => boolean;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ //#region src/internal/isItemDisabled.ts
9
+ /**
10
+ * Copyright IBM Corp. 2026
11
+ *
12
+ * This source code is licensed under the Apache-2.0 license found in the
13
+ * LICENSE file in the root directory of this source tree.
14
+ */
15
+ const isItemDisabled = (item) => item !== null && typeof item === "object" && "disabled" in item && item.disabled === true;
16
+ //#endregion
17
+ exports.isItemDisabled = isItemDisabled;