@carbon/react 1.49.0-rc.0 → 1.50.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +805 -817
  2. package/es/components/Button/Button.js +3 -2
  3. package/es/components/ComboButton/index.js +14 -0
  4. package/es/components/ContainedList/ContainedList.js +5 -3
  5. package/es/components/ContainedList/ContainedListItem/ContainedListItem.js +5 -3
  6. package/es/components/DataTable/TableToolbarSearch.d.ts +2 -2
  7. package/es/components/Menu/Menu.d.ts +9 -1
  8. package/es/components/Menu/Menu.js +34 -0
  9. package/es/components/MenuButton/index.js +13 -0
  10. package/es/components/MultiSelect/MultiSelect.js +2 -1
  11. package/es/components/Notification/Notification.d.ts +75 -0
  12. package/es/components/Notification/Notification.js +84 -2
  13. package/es/components/Notification/index.d.ts +1 -1
  14. package/es/components/OverflowMenu/next/index.js +16 -2
  15. package/es/components/Tooltip/Tooltip.js +2 -2
  16. package/es/index.js +1 -1
  17. package/es/internal/useNoInteractiveChildren.js +13 -1
  18. package/lib/components/Button/Button.js +3 -2
  19. package/lib/components/ComboButton/index.js +14 -0
  20. package/lib/components/ContainedList/ContainedList.js +5 -3
  21. package/lib/components/ContainedList/ContainedListItem/ContainedListItem.js +5 -3
  22. package/lib/components/DataTable/TableToolbarSearch.d.ts +2 -2
  23. package/lib/components/Menu/Menu.d.ts +9 -1
  24. package/lib/components/Menu/Menu.js +34 -0
  25. package/lib/components/MenuButton/index.js +13 -0
  26. package/lib/components/MultiSelect/MultiSelect.js +2 -1
  27. package/lib/components/Notification/Notification.d.ts +75 -0
  28. package/lib/components/Notification/Notification.js +83 -0
  29. package/lib/components/Notification/index.d.ts +1 -1
  30. package/lib/components/OverflowMenu/next/index.js +16 -2
  31. package/lib/components/Tooltip/Tooltip.js +2 -2
  32. package/lib/index.js +1 -0
  33. package/lib/internal/useNoInteractiveChildren.js +13 -0
  34. package/package.json +6 -6
@@ -46,6 +46,7 @@ const ComboButton = /*#__PURE__*/React__default["default"].forwardRef(function C
46
46
  label,
47
47
  onClick,
48
48
  size = 'lg',
49
+ menuAlignment = 'bottom',
49
50
  tooltipAlignment,
50
51
  translateWithId: t = defaultTranslateWithId,
51
52
  ...rest
@@ -80,10 +81,15 @@ const ComboButton = /*#__PURE__*/React__default["default"].forwardRef(function C
80
81
  }
81
82
  function handleOpen() {
82
83
  menuRef.current.style.inlineSize = `${width}px`;
84
+ menuRef.current.style.minInlineSize = `${width}px`;
85
+ if (menuAlignment !== 'bottom' && menuAlignment !== 'top') {
86
+ menuRef.current.style.inlineSize = `fit-content`;
87
+ }
83
88
  }
84
89
  const containerClasses = cx__default["default"](`${prefix}--combo-button__container`, `${prefix}--combo-button__container--${size}`, {
85
90
  [`${prefix}--combo-button__container--open`]: open
86
91
  }, className);
92
+ const menuClasses = cx__default["default"](`${prefix}--combo-button__${menuAlignment}`);
87
93
  const primaryActionClasses = cx__default["default"](`${prefix}--combo-button__primary-action`);
88
94
  const triggerClasses = cx__default["default"](`${prefix}--combo-button__trigger`);
89
95
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, rest, {
@@ -93,6 +99,7 @@ const ComboButton = /*#__PURE__*/React__default["default"].forwardRef(function C
93
99
  }), /*#__PURE__*/React__default["default"].createElement("div", {
94
100
  className: primaryActionClasses
95
101
  }, /*#__PURE__*/React__default["default"].createElement(Button["default"], {
102
+ title: label,
96
103
  size: size,
97
104
  disabled: disabled,
98
105
  onClick: handlePrimaryActionClick
@@ -108,6 +115,9 @@ const ComboButton = /*#__PURE__*/React__default["default"].forwardRef(function C
108
115
  onMouseDown: handleTriggerMousedown,
109
116
  "aria-controls": open ? id : null
110
117
  }, _ChevronDown || (_ChevronDown = /*#__PURE__*/React__default["default"].createElement(iconsReact.ChevronDown, null))), /*#__PURE__*/React__default["default"].createElement(Menu.Menu, {
118
+ containerRef: containerRef,
119
+ menuAlignment: menuAlignment,
120
+ className: menuClasses,
111
121
  ref: menuRef,
112
122
  id: id,
113
123
  label: t('carbon.combo-button.additional-actions'),
@@ -137,6 +147,10 @@ ComboButton.propTypes = {
137
147
  * Provide the label to be renderd on the primary action button.
138
148
  */
139
149
  label: PropTypes__default["default"].string.isRequired,
150
+ /**
151
+ * Experimental property. Specify how the menu should align with the button element
152
+ */
153
+ menuAlignment: PropTypes__default["default"].oneOf(['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end']),
140
154
  /**
141
155
  * Provide an optional function to be called when the primary action element is clicked.
142
156
  */
@@ -9,6 +9,7 @@
9
9
 
10
10
  Object.defineProperty(exports, '__esModule', { value: true });
11
11
 
12
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
12
13
  var React = require('react');
13
14
  var PropTypes = require('prop-types');
14
15
  var cx = require('classnames');
@@ -54,7 +55,8 @@ function ContainedList(_ref) {
54
55
  isInset,
55
56
  kind = variants[0],
56
57
  label,
57
- size
58
+ size,
59
+ ...rest
58
60
  } = _ref;
59
61
  const labelId = `${useId.useId('contained-list')}-header`;
60
62
  const prefix = usePrefix.usePrefix();
@@ -67,9 +69,9 @@ function ContainedList(_ref) {
67
69
  const filteredChildren = filterChildren(children);
68
70
  const isActionSearch = ['Search', 'ExpandableSearch'].includes(action?.type?.displayName);
69
71
  const renderedChildren = renderChildren(children);
70
- return /*#__PURE__*/React__default["default"].createElement("div", {
72
+ return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
71
73
  className: classes
72
- }, /*#__PURE__*/React__default["default"].createElement("div", {
74
+ }, rest), /*#__PURE__*/React__default["default"].createElement("div", {
73
75
  className: `${prefix}--contained-list__header`
74
76
  }, /*#__PURE__*/React__default["default"].createElement("div", {
75
77
  id: labelId,
@@ -9,6 +9,7 @@
9
9
 
10
10
  Object.defineProperty(exports, '__esModule', { value: true });
11
11
 
12
+ var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js');
12
13
  var React = require('react');
13
14
  var PropTypes = require('prop-types');
14
15
  var cx = require('classnames');
@@ -28,7 +29,8 @@ function ContainedListItem(_ref) {
28
29
  className,
29
30
  disabled = false,
30
31
  onClick,
31
- renderIcon: IconElement
32
+ renderIcon: IconElement,
33
+ ...rest
32
34
  } = _ref;
33
35
  const prefix = usePrefix.usePrefix();
34
36
  const isClickable = onClick !== undefined;
@@ -40,9 +42,9 @@ function ContainedListItem(_ref) {
40
42
  const content = /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, IconElement && /*#__PURE__*/React__default["default"].createElement("div", {
41
43
  className: `${prefix}--contained-list-item__icon`
42
44
  }, /*#__PURE__*/React__default["default"].createElement(IconElement, null)), /*#__PURE__*/React__default["default"].createElement("div", null, children));
43
- return /*#__PURE__*/React__default["default"].createElement("li", {
45
+ return /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({
44
46
  className: classes
45
- }, isClickable ? /*#__PURE__*/React__default["default"].createElement("button", {
47
+ }, rest), isClickable ? /*#__PURE__*/React__default["default"].createElement("button", {
46
48
  className: `${prefix}--contained-list-item__content`,
47
49
  type: "button",
48
50
  disabled: disabled,
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
- import React, { FocusEvent, ReactNode } from 'react';
8
+ import { ChangeEvent, FocusEvent, ReactNode } from 'react';
9
9
  export interface TableToolbarSearchProps {
10
10
  children?: ReactNode;
11
11
  /**
@@ -45,7 +45,7 @@ export interface TableToolbarSearchProps {
45
45
  /**
46
46
  * Provide an optional hook that is called each time the input is updated
47
47
  */
48
- onChange?: (event: '' | Partial<React.ChangeEventHandler<HTMLInputElement>>, value?: string) => void;
48
+ onChange?: (event: '' | ChangeEvent<HTMLInputElement>, value?: string) => void;
49
49
  /**
50
50
  * Optional callback called when the search value is cleared.
51
51
  */
@@ -4,8 +4,12 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import React from 'react';
7
+ import React, { RefObject } from 'react';
8
8
  interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {
9
+ /**
10
+ * The ref of the containing element, used for positioning and alignment of the menu
11
+ */
12
+ containerRef?: RefObject<HTMLDivElement>;
9
13
  /**
10
14
  * A collection of MenuItems to be rendered within this Menu.
11
15
  */
@@ -18,6 +22,10 @@ interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {
18
22
  * A label describing the Menu.
19
23
  */
20
24
  label?: string;
25
+ /**
26
+ * Specify how the menu should align with the button element
27
+ */
28
+ menuAlignment?: string;
21
29
  /**
22
30
  * The mode of this menu. Defaults to full.
23
31
  * `full` supports nesting and selectable menu items, but no icons.
@@ -34,7 +34,9 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
34
34
  let {
35
35
  children,
36
36
  className,
37
+ containerRef,
37
38
  label,
39
+ menuAlignment,
38
40
  mode = 'full',
39
41
  onClose,
40
42
  onOpen,
@@ -71,6 +73,15 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
71
73
  const [position, setPosition] = React.useState([-1, -1]);
72
74
  const focusableItems = childContext.state.items.filter(item => !item.disabled && item.ref.current);
73
75
 
76
+ // Getting the width from the parent container element - controlled
77
+ let actionButtonWidth;
78
+ if (containerRef?.current) {
79
+ const {
80
+ width: w
81
+ } = containerRef.current.getBoundingClientRect();
82
+ actionButtonWidth = w;
83
+ }
84
+
74
85
  // Set RTL based on document direction or `LayoutDirection`
75
86
  const {
76
87
  direction
@@ -184,6 +195,16 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
184
195
  }
185
196
  };
186
197
 
198
+ // Avoid that the Menu render incorrectly when the postion is set in the right side of the screen
199
+ if (actionButtonWidth && actionButtonWidth < axes.x.size && (menuAlignment === 'bottom' || menuAlignment === 'top')) {
200
+ axes.x.size = actionButtonWidth;
201
+ }
202
+
203
+ // if 'axes.x.anchor' is lower than 87px dynamically switch render side
204
+ if (actionButtonWidth && (menuAlignment === 'bottom-end' || menuAlignment === 'top-end') && axes.x.anchor >= 87 && actionButtonWidth < axes.x.size) {
205
+ const diff = axes.x.anchor + axes.x.reversedAnchor;
206
+ axes.x.anchor = axes.x.anchor + diff;
207
+ }
187
208
  const {
188
209
  max,
189
210
  size,
@@ -200,6 +221,14 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
200
221
  reversedAnchor - size >= 0 ? reversedAnchor - size + offset : false,
201
222
  // align at max (second fallback)
202
223
  max - spacing - size];
224
+ const topAlignment = menuAlignment === 'top' || menuAlignment === 'top-end' || menuAlignment === 'top-start';
225
+
226
+ // If the tooltip is not visible in the top, switch to the bototm
227
+ if (typeof options[0] === 'number' && topAlignment && options[0] >= 0 && !options[1] && axis === 'y') {
228
+ menu.current.style.transform = 'translate(0)';
229
+ } else if (topAlignment && !options[0] && axis === 'y') {
230
+ options[0] = anchor - offset;
231
+ }
203
232
 
204
233
  // Previous array `options`, has at least one item that is a number (the last one - second fallback).
205
234
  // That guarantees that the return of `find()` will always be a number
@@ -254,6 +283,7 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
254
283
  // visibility is needed for focusing elements.
255
284
  // opacity is only set once the position has been set correctly
256
285
  // to avoid a flicker effect when opening.
286
+ [`${prefix}--menu--box-shadow-top`]: menuAlignment && menuAlignment.slice(0, 3) === 'top',
257
287
  [`${prefix}--menu--open`]: open,
258
288
  [`${prefix}--menu--shown`]: position[0] >= 0 && position[1] >= 0,
259
289
  [`${prefix}--menu--with-icons`]: childContext.state.hasIcons
@@ -284,6 +314,10 @@ Menu.propTypes = {
284
314
  * A label describing the Menu.
285
315
  */
286
316
  label: PropTypes__default["default"].string,
317
+ /**
318
+ * Specify how the menu should align with the button element
319
+ */
320
+ menuAlignment: PropTypes__default["default"].string,
287
321
  /**
288
322
  * The mode of this menu. Defaults to full.
289
323
  * `full` supports nesting and selectable menu items, but no icons.
@@ -40,6 +40,7 @@ const MenuButton = /*#__PURE__*/React__default["default"].forwardRef(function Me
40
40
  kind = defaultButtonKind,
41
41
  label,
42
42
  size = 'lg',
43
+ menuAlignment = 'bottom',
43
44
  tabIndex = 0,
44
45
  ...rest
45
46
  } = _ref;
@@ -68,11 +69,16 @@ const MenuButton = /*#__PURE__*/React__default["default"].forwardRef(function Me
68
69
  }
69
70
  function handleOpen() {
70
71
  menuRef.current.style.inlineSize = `${width}px`;
72
+ menuRef.current.style.minInlineSize = `${width}px`;
73
+ if (menuAlignment !== 'bottom' && menuAlignment !== 'top') {
74
+ menuRef.current.style.inlineSize = `fit-content`;
75
+ }
71
76
  }
72
77
  const containerClasses = cx__default["default"](`${prefix}--menu-button__container`, className);
73
78
  const triggerClasses = cx__default["default"](`${prefix}--menu-button__trigger`, {
74
79
  [`${prefix}--menu-button__trigger--open`]: open
75
80
  });
81
+ const menuClasses = cx__default["default"](`${prefix}--menu-button__${menuAlignment}`);
76
82
  const buttonKind = validButtonKinds.includes(kind) ? kind : defaultButtonKind;
77
83
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, rest, {
78
84
  ref: ref,
@@ -91,6 +97,9 @@ const MenuButton = /*#__PURE__*/React__default["default"].forwardRef(function Me
91
97
  onMouseDown: handleMousedown,
92
98
  "aria-controls": open ? id : null
93
99
  }, label), /*#__PURE__*/React__default["default"].createElement(Menu.Menu, {
100
+ containerRef: triggerRef,
101
+ menuAlignment: menuAlignment,
102
+ className: menuClasses,
94
103
  ref: menuRef,
95
104
  id: id,
96
105
  label: label,
@@ -124,6 +133,10 @@ MenuButton.propTypes = {
124
133
  * Provide the label to be renderd on the trigger button.
125
134
  */
126
135
  label: PropTypes__default["default"].string.isRequired,
136
+ /**
137
+ * Experimental property. Specify how the menu should align with the button element
138
+ */
139
+ menuAlignment: PropTypes__default["default"].oneOf(['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end']),
127
140
  /**
128
141
  * Specify the size of the button and menu.
129
142
  */
@@ -317,13 +317,14 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
317
317
  size: 'mini'
318
318
  });
319
319
  }
320
+ const itemsSelectedText = selectedItems.length > 0 && selectedItems.map(item => item.text);
320
321
  return /*#__PURE__*/React__default["default"].createElement("div", {
321
322
  className: wrapperClasses
322
323
  }, /*#__PURE__*/React__default["default"].createElement("label", _rollupPluginBabelHelpers["extends"]({
323
324
  className: titleClasses
324
325
  }, getLabelProps()), titleText && titleText, selectedItems.length > 0 && /*#__PURE__*/React__default["default"].createElement("span", {
325
326
  className: `${prefix}--visually-hidden`
326
- }, clearSelectionDescription, " ", selectedItems.length, ",", clearSelectionText)), /*#__PURE__*/React__default["default"].createElement(index["default"], {
327
+ }, clearSelectionDescription, " ", selectedItems.length, ' ', itemsSelectedText, ",", clearSelectionText)), /*#__PURE__*/React__default["default"].createElement(index["default"], {
327
328
  onFocus: isFluid ? handleFocus : undefined,
328
329
  onBlur: isFluid ? handleFocus : undefined,
329
330
  type: type,
@@ -513,3 +513,78 @@ export declare namespace ActionableNotification {
513
513
  title: PropTypes.Requireable<string>;
514
514
  };
515
515
  }
516
+ /**
517
+ * StaticNotification
518
+ * ==================
519
+ */
520
+ export interface StaticNotificationProps extends HTMLAttributes<HTMLDivElement> {
521
+ /**
522
+ * Specify the content
523
+ */
524
+ children?: ReactNode;
525
+ /**
526
+ * Specify an optional className to be applied to the notification box
527
+ */
528
+ className?: string;
529
+ /**
530
+ * Specify what state the notification represents
531
+ */
532
+ kind?: 'error' | 'info' | 'info-square' | 'success' | 'warning' | 'warning-alt';
533
+ /**
534
+ * Specify whether you are using the low contrast variant of the StaticNotification.
535
+ */
536
+ lowContrast?: boolean;
537
+ /**
538
+ * Provide a description for "status" icon that can be read by screen readers
539
+ */
540
+ statusIconDescription?: string;
541
+ /**
542
+ * Specify the subtitle
543
+ */
544
+ subtitle?: string;
545
+ /**
546
+ * Specify the title
547
+ */
548
+ title?: string;
549
+ /**
550
+ * Specify the id for the element containing the title
551
+ */
552
+ titleId?: string;
553
+ }
554
+ export declare function StaticNotification({ children, title, titleId, subtitle, statusIconDescription, className, kind, lowContrast, ...rest }: StaticNotificationProps): import("react/jsx-runtime").JSX.Element;
555
+ export declare namespace StaticNotification {
556
+ var propTypes: {
557
+ /**
558
+ * Specify the content
559
+ */
560
+ children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
561
+ /**
562
+ * Specify an optional className to be applied to the notification box
563
+ */
564
+ className: PropTypes.Requireable<string>;
565
+ /**
566
+ * Specify what state the notification represents
567
+ */
568
+ kind: PropTypes.Requireable<string>;
569
+ /**
570
+ * Specify whether you are using the low contrast variant of the StaticNotification.
571
+ */
572
+ lowContrast: PropTypes.Requireable<boolean>;
573
+ /**
574
+ * Provide a description for "status" icon that can be read by screen readers
575
+ */
576
+ statusIconDescription: PropTypes.Requireable<string>;
577
+ /**
578
+ * Specify the subtitle
579
+ */
580
+ subtitle: PropTypes.Requireable<string>;
581
+ /**
582
+ * Specify the title
583
+ */
584
+ title: PropTypes.Requireable<string>;
585
+ /**
586
+ * Specify the id for the element containing the title
587
+ */
588
+ titleId: PropTypes.Requireable<string>;
589
+ };
590
+ }
@@ -688,8 +688,91 @@ ActionableNotification.propTypes = {
688
688
  title: PropTypes__default["default"].string
689
689
  };
690
690
 
691
+ /**
692
+ * StaticNotification
693
+ * ==================
694
+ */
695
+
696
+ function StaticNotification(_ref8) {
697
+ let {
698
+ children,
699
+ title,
700
+ titleId,
701
+ subtitle,
702
+ statusIconDescription,
703
+ className,
704
+ kind = 'error',
705
+ lowContrast,
706
+ ...rest
707
+ } = _ref8;
708
+ const prefix = usePrefix.usePrefix();
709
+ const containerClassName = cx__default["default"](className, {
710
+ [`${prefix}--inline-notification`]: true,
711
+ [`${prefix}--inline-notification--low-contrast`]: lowContrast,
712
+ [`${prefix}--inline-notification--${kind}`]: kind,
713
+ [`${prefix}--inline-notification--hide-close-button`]: true
714
+ });
715
+ const ref = React.useRef(null);
716
+ useNoInteractiveChildren.useInteractiveChildrenNeedDescription(ref, `interactive child node(s) should have an \`aria-describedby\` property with a value matching the value of \`titleId\``);
717
+ return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
718
+ ref: ref
719
+ }, rest, {
720
+ className: containerClassName
721
+ }), /*#__PURE__*/React__default["default"].createElement("div", {
722
+ className: `${prefix}--inline-notification__details`
723
+ }, /*#__PURE__*/React__default["default"].createElement(NotificationIcon, {
724
+ notificationType: "inline",
725
+ kind: kind,
726
+ iconDescription: statusIconDescription || `${kind} icon`
727
+ }), /*#__PURE__*/React__default["default"].createElement("div", {
728
+ className: `${prefix}--inline-notification__text-wrapper`
729
+ }, title && /*#__PURE__*/React__default["default"].createElement(Text.Text, {
730
+ as: "div",
731
+ id: titleId,
732
+ className: `${prefix}--inline-notification__title`
733
+ }, title), subtitle && /*#__PURE__*/React__default["default"].createElement(Text.Text, {
734
+ as: "div",
735
+ className: `${prefix}--inline-notification__subtitle`
736
+ }, subtitle), children)));
737
+ }
738
+ StaticNotification.propTypes = {
739
+ /**
740
+ * Specify the content
741
+ */
742
+ children: PropTypes__default["default"].node,
743
+ /**
744
+ * Specify an optional className to be applied to the notification box
745
+ */
746
+ className: PropTypes__default["default"].string,
747
+ /**
748
+ * Specify what state the notification represents
749
+ */
750
+ kind: PropTypes__default["default"].oneOf(['error', 'info', 'info-square', 'success', 'warning', 'warning-alt']),
751
+ /**
752
+ * Specify whether you are using the low contrast variant of the StaticNotification.
753
+ */
754
+ lowContrast: PropTypes__default["default"].bool,
755
+ /**
756
+ * Provide a description for "status" icon that can be read by screen readers
757
+ */
758
+ statusIconDescription: PropTypes__default["default"].string,
759
+ /**
760
+ * Specify the subtitle
761
+ */
762
+ subtitle: PropTypes__default["default"].string,
763
+ /**
764
+ * Specify the title
765
+ */
766
+ title: PropTypes__default["default"].string,
767
+ /**
768
+ * Specify the id for the element containing the title
769
+ */
770
+ titleId: PropTypes__default["default"].string
771
+ };
772
+
691
773
  exports.ActionableNotification = ActionableNotification;
692
774
  exports.InlineNotification = InlineNotification;
693
775
  exports.NotificationActionButton = NotificationActionButton;
694
776
  exports.NotificationButton = NotificationButton;
777
+ exports.StaticNotification = StaticNotification;
695
778
  exports.ToastNotification = ToastNotification;
@@ -4,4 +4,4 @@
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
- export { NotificationActionButton, type NotificationActionButtonProps, NotificationButton, type NotificationButtonProps, ToastNotification, type ToastNotificationProps, InlineNotification, type InlineNotificationProps, ActionableNotification, type ActionableNotificationProps, } from './Notification';
7
+ export { NotificationActionButton, type NotificationActionButtonProps, NotificationButton, type NotificationButtonProps, ToastNotification, type ToastNotificationProps, InlineNotification, type InlineNotificationProps, ActionableNotification, type ActionableNotificationProps, StaticNotification, type StaticNotificationProps, } from './Notification';
@@ -35,6 +35,7 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
35
35
  label = 'Options',
36
36
  renderIcon: IconElement = iconsReact.OverflowMenuVertical,
37
37
  size = defaultSize,
38
+ menuAlignment = 'bottom-start',
38
39
  tooltipAlignment,
39
40
  ...rest
40
41
  } = _ref;
@@ -45,11 +46,17 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
45
46
  open,
46
47
  x,
47
48
  y,
48
- handleClick,
49
+ handleClick: hookOnClick,
49
50
  handleMousedown,
50
51
  handleClose
51
52
  } = useAttachedMenu.useAttachedMenu(triggerRef);
53
+ function handleTriggerClick() {
54
+ if (triggerRef.current) {
55
+ hookOnClick();
56
+ }
57
+ }
52
58
  const containerClasses = cx__default["default"](className, `${prefix}--overflow-menu__container`);
59
+ const menuClasses = cx__default["default"](`${prefix}--overflow-menu__${menuAlignment}`);
53
60
  const triggerClasses = cx__default["default"](`${prefix}--overflow-menu`, {
54
61
  [`${prefix}--overflow-menu--open`]: open
55
62
  }, size !== defaultSize && `${prefix}--overflow-menu--${size}`);
@@ -62,7 +69,7 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
62
69
  "aria-haspopup": true,
63
70
  "aria-expanded": open,
64
71
  className: triggerClasses,
65
- onClick: handleClick,
72
+ onClick: handleTriggerClick,
66
73
  onMouseDown: handleMousedown,
67
74
  ref: triggerRef,
68
75
  label: label,
@@ -70,6 +77,9 @@ const OverflowMenu = /*#__PURE__*/React__default["default"].forwardRef(function
70
77
  }, /*#__PURE__*/React__default["default"].createElement(IconElement, {
71
78
  className: `${prefix}--overflow-menu__icon`
72
79
  })), /*#__PURE__*/React__default["default"].createElement(Menu.Menu, {
80
+ containerRef: triggerRef,
81
+ menuAlignment: menuAlignment,
82
+ className: menuClasses,
73
83
  id: id,
74
84
  size: size,
75
85
  open: open,
@@ -92,6 +102,10 @@ OverflowMenu.propTypes = {
92
102
  * A label describing the options available. Is used in the trigger tooltip and as the menu's accessible label.
93
103
  */
94
104
  label: PropTypes__default["default"].string,
105
+ /**
106
+ * Experimental property. Specify how the menu should align with the button element
107
+ */
108
+ menuAlignment: PropTypes__default["default"].oneOf(['top-start', 'top-end', 'bottom-start', 'bottom-end']),
95
109
  /**
96
110
  * Otionally provide a custom icon to be rendered on the trigger button.
97
111
  */
@@ -64,11 +64,11 @@ function Tooltip(_ref) {
64
64
  onTouchStart: onDragStart
65
65
  };
66
66
  function getChildEventHandlers(childProps) {
67
- const eventHandlerFunctions = ['onFocus', 'onBlur', 'onClick', 'onMouseEnter'];
67
+ const eventHandlerFunctions = Object.keys(triggerProps).filter(prop => prop.startsWith('on'));
68
68
  const eventHandlers = {};
69
69
  eventHandlerFunctions.forEach(functionName => {
70
70
  eventHandlers[functionName] = evt => {
71
- triggerProps[functionName]();
71
+ triggerProps[functionName](evt);
72
72
  if (childProps?.[functionName]) {
73
73
  childProps?.[functionName](evt);
74
74
  }
package/lib/index.js CHANGED
@@ -300,6 +300,7 @@ exports.ActionableNotification = Notification.ActionableNotification;
300
300
  exports.InlineNotification = Notification.InlineNotification;
301
301
  exports.NotificationActionButton = Notification.NotificationActionButton;
302
302
  exports.NotificationButton = Notification.NotificationButton;
303
+ exports.StaticNotification = Notification.StaticNotification;
303
304
  exports.ToastNotification = Notification.ToastNotification;
304
305
  exports.NumberInputSkeleton = NumberInput_Skeleton["default"];
305
306
  exports.NumberInput = NumberInput.NumberInput;
@@ -23,6 +23,18 @@ function useNoInteractiveChildren(ref) {
23
23
  });
24
24
  }
25
25
  }
26
+ function useInteractiveChildrenNeedDescription(ref) {
27
+ let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : `interactive child node(s) should have an \`aria-describedby\` property`;
28
+ if (process.env.NODE_ENV !== "production") {
29
+ // eslint-disable-next-line react-hooks/rules-of-hooks
30
+ React.useEffect(() => {
31
+ const node = ref.current ? getInteractiveContent(ref.current) : false;
32
+ if (node && !node.hasAttribute('aria-describedby')) {
33
+ throw new Error(`Error: ${message}.\n\nInstead found: ${node.outerHTML}`);
34
+ }
35
+ });
36
+ }
37
+ }
26
38
 
27
39
  /**
28
40
  * Determines if a given DOM node has interactive content, or is itself
@@ -96,4 +108,5 @@ function isFocusable(element) {
96
108
 
97
109
  exports.getInteractiveContent = getInteractiveContent;
98
110
  exports.getRoleContent = getRoleContent;
111
+ exports.useInteractiveChildrenNeedDescription = useInteractiveChildrenNeedDescription;
99
112
  exports.useNoInteractiveChildren = useNoInteractiveChildren;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/react",
3
3
  "description": "React components for the Carbon Design System",
4
- "version": "1.49.0-rc.0",
4
+ "version": "1.50.0-rc.0",
5
5
  "license": "Apache-2.0",
6
6
  "main": "lib/index.js",
7
7
  "module": "es/index.js",
@@ -49,9 +49,9 @@
49
49
  "dependencies": {
50
50
  "@babel/runtime": "^7.18.3",
51
51
  "@carbon/feature-flags": "^0.16.0",
52
- "@carbon/icons-react": "^11.35.0-rc.0",
52
+ "@carbon/icons-react": "^11.36.0-rc.0",
53
53
  "@carbon/layout": "^11.20.0",
54
- "@carbon/styles": "^1.49.0-rc.0",
54
+ "@carbon/styles": "^1.50.0-rc.0",
55
55
  "@ibm/telemetry-js": "^1.2.0",
56
56
  "classnames": "2.5.1",
57
57
  "copy-to-clipboard": "^3.3.1",
@@ -79,7 +79,7 @@
79
79
  "@babel/preset-react": "^7.22.3",
80
80
  "@babel/preset-typescript": "^7.21.5",
81
81
  "@carbon/test-utils": "^10.30.0",
82
- "@carbon/themes": "^11.30.0-rc.0",
82
+ "@carbon/themes": "^11.30.0",
83
83
  "@rollup/plugin-babel": "^6.0.0",
84
84
  "@rollup/plugin-commonjs": "^25.0.0",
85
85
  "@rollup/plugin-node-resolve": "^15.0.0",
@@ -119,7 +119,7 @@
119
119
  "rollup": "^2.79.1",
120
120
  "rollup-plugin-strip-banner": "^3.0.0",
121
121
  "sass": "^1.51.0",
122
- "sass-loader": "^13.0.0",
122
+ "sass-loader": "^14.0.0",
123
123
  "storybook": "^7.1.0",
124
124
  "storybook-addon-accessibility-checker": "^3.1.61-rc.2",
125
125
  "stream-browserify": "^3.0.0",
@@ -139,5 +139,5 @@
139
139
  "**/*.scss",
140
140
  "**/*.css"
141
141
  ],
142
- "gitHead": "79048666dc3d8f66c3d64b46de45b25ce13d9adf"
142
+ "gitHead": "fbec0e13b29a1c9b19ed22a1ae9b6f87107ba920"
143
143
  }