@carbon/react 1.53.1 → 1.54.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 (114) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +981 -1068
  2. package/es/components/Button/Button.d.ts +1 -1
  3. package/es/components/Button/Button.js +13 -89
  4. package/es/components/Button/ButtonBase.d.ts +10 -0
  5. package/es/components/Button/ButtonBase.js +110 -0
  6. package/es/components/CodeSnippet/CodeSnippet.js +1 -0
  7. package/es/components/ComboBox/ComboBox.js +13 -4
  8. package/es/components/ComboButton/index.js +1 -1
  9. package/es/components/ComposedModal/ComposedModal.js +19 -10
  10. package/es/components/DataTable/DataTable.js +1 -1
  11. package/es/components/DataTable/TableBatchAction.d.ts +1 -1
  12. package/es/components/DataTable/TableToolbarMenu.d.ts +5 -1
  13. package/es/components/DataTable/TableToolbarMenu.js +7 -0
  14. package/es/components/DatePicker/DatePicker.d.ts +4 -0
  15. package/es/components/DatePicker/DatePicker.js +37 -0
  16. package/es/components/IconButton/index.d.ts +1 -1
  17. package/es/components/IconButton/index.js +3 -4
  18. package/es/components/ListBox/ListBox.d.ts +8 -0
  19. package/es/components/ListBox/ListBox.js +15 -3
  20. package/es/components/Loading/Loading.d.ts +1 -1
  21. package/es/components/Menu/Menu.js +2 -0
  22. package/es/components/Modal/Modal.js +14 -5
  23. package/es/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  24. package/es/components/Notification/Notification.js +18 -6
  25. package/es/components/Pagination/Pagination.Skeleton.d.ts +25 -0
  26. package/es/components/Pagination/Pagination.d.ts +102 -0
  27. package/es/components/Pagination/Pagination.js +13 -14
  28. package/es/components/Pagination/index.d.ts +10 -0
  29. package/es/components/Popover/index.d.ts +1 -1
  30. package/es/components/Popover/index.js +175 -108
  31. package/es/components/RadioTile/RadioTile.d.ts +55 -0
  32. package/es/components/RadioTile/RadioTile.js +17 -17
  33. package/es/components/RadioTile/index.d.ts +10 -0
  34. package/es/components/Slider/Slider.Skeleton.js +6 -2
  35. package/es/components/Slug/index.js +23 -2
  36. package/es/components/Stack/HStack.d.ts +10 -0
  37. package/es/components/Stack/HStack.js +23 -0
  38. package/es/components/Stack/Stack.d.ts +1 -1
  39. package/es/components/Stack/Stack.js +2 -2
  40. package/es/components/Stack/VStack.d.ts +10 -0
  41. package/es/components/Stack/{index.js → VStack.js} +1 -8
  42. package/es/components/Stack/index.d.ts +3 -6
  43. package/es/components/StructuredList/StructuredList.d.ts +8 -0
  44. package/es/components/StructuredList/StructuredList.js +28 -10
  45. package/es/components/TileGroup/TileGroup.js +30 -24
  46. package/es/components/Toggletip/index.d.ts +1 -18
  47. package/es/components/Toggletip/index.js +27 -4
  48. package/es/components/Tooltip/Tooltip.js +23 -5
  49. package/es/feature-flags.js +2 -1
  50. package/es/index.d.ts +1 -0
  51. package/es/index.js +5 -4
  52. package/es/internal/FloatingMenu.js +26 -5
  53. package/es/internal/environment.js +5 -1
  54. package/es/internal/keyboard/navigation.js +6 -2
  55. package/es/internal/useOutsideClick.js +31 -0
  56. package/es/internal/wrapFocus.js +51 -1
  57. package/es/tools/createPropAdapter.js +40 -0
  58. package/lib/components/Button/Button.d.ts +1 -1
  59. package/lib/components/Button/Button.js +13 -90
  60. package/lib/components/Button/ButtonBase.d.ts +10 -0
  61. package/lib/components/Button/ButtonBase.js +119 -0
  62. package/lib/components/CodeSnippet/CodeSnippet.js +1 -0
  63. package/lib/components/ComboBox/ComboBox.js +13 -4
  64. package/lib/components/ComboButton/index.js +1 -1
  65. package/lib/components/ComposedModal/ComposedModal.js +17 -8
  66. package/lib/components/DataTable/DataTable.js +1 -1
  67. package/lib/components/DataTable/TableBatchAction.d.ts +1 -1
  68. package/lib/components/DataTable/TableToolbarMenu.d.ts +5 -1
  69. package/lib/components/DataTable/TableToolbarMenu.js +7 -0
  70. package/lib/components/DatePicker/DatePicker.d.ts +4 -0
  71. package/lib/components/DatePicker/DatePicker.js +37 -0
  72. package/lib/components/IconButton/index.d.ts +1 -1
  73. package/lib/components/IconButton/index.js +3 -4
  74. package/lib/components/ListBox/ListBox.d.ts +8 -0
  75. package/lib/components/ListBox/ListBox.js +15 -3
  76. package/lib/components/Loading/Loading.d.ts +1 -1
  77. package/lib/components/Menu/Menu.js +2 -0
  78. package/lib/components/Modal/Modal.js +14 -5
  79. package/lib/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  80. package/lib/components/Notification/Notification.js +15 -3
  81. package/lib/components/Pagination/Pagination.Skeleton.d.ts +25 -0
  82. package/lib/components/Pagination/Pagination.d.ts +102 -0
  83. package/lib/components/Pagination/Pagination.js +13 -14
  84. package/lib/components/Pagination/index.d.ts +10 -0
  85. package/lib/components/Popover/index.d.ts +1 -1
  86. package/lib/components/Popover/index.js +174 -107
  87. package/lib/components/RadioTile/RadioTile.d.ts +55 -0
  88. package/lib/components/RadioTile/RadioTile.js +17 -17
  89. package/lib/components/RadioTile/index.d.ts +10 -0
  90. package/lib/components/Slider/Slider.Skeleton.js +5 -1
  91. package/lib/components/Slug/index.js +23 -2
  92. package/lib/components/Stack/HStack.d.ts +10 -0
  93. package/lib/components/Stack/HStack.js +31 -0
  94. package/lib/components/Stack/Stack.d.ts +1 -1
  95. package/lib/components/Stack/Stack.js +3 -3
  96. package/lib/components/Stack/VStack.d.ts +10 -0
  97. package/lib/components/Stack/{index.js → VStack.js} +0 -8
  98. package/lib/components/Stack/index.d.ts +3 -6
  99. package/lib/components/StructuredList/StructuredList.d.ts +8 -0
  100. package/lib/components/StructuredList/StructuredList.js +27 -9
  101. package/lib/components/TileGroup/TileGroup.js +30 -24
  102. package/lib/components/Toggletip/index.d.ts +1 -18
  103. package/lib/components/Toggletip/index.js +27 -4
  104. package/lib/components/Tooltip/Tooltip.js +23 -5
  105. package/lib/feature-flags.js +2 -1
  106. package/lib/index.d.ts +1 -0
  107. package/lib/index.js +15 -14
  108. package/lib/internal/FloatingMenu.js +44 -4
  109. package/lib/internal/environment.js +5 -1
  110. package/lib/internal/keyboard/navigation.js +6 -2
  111. package/lib/internal/useOutsideClick.js +35 -0
  112. package/lib/internal/wrapFocus.js +51 -0
  113. package/lib/tools/createPropAdapter.js +44 -0
  114. package/package.json +9 -7
@@ -14,7 +14,7 @@ export declare const ButtonTooltipAlignments: readonly ["start", "center", "end"
14
14
  export type ButtonTooltipAlignment = (typeof ButtonTooltipAlignments)[number];
15
15
  export declare const ButtonTooltipPositions: string[];
16
16
  export type ButtonTooltipPosition = (typeof ButtonTooltipPositions)[number];
17
- interface ButtonBaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
17
+ export interface ButtonBaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
18
18
  /**
19
19
  * Specify the message read by screen readers for the danger button variant
20
20
  */
@@ -8,11 +8,9 @@
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
10
  import React__default, { useRef } from 'react';
11
- import cx from 'classnames';
12
11
  import { IconButton } from '../IconButton/index.js';
13
12
  import { composeEventHandlers } from '../../tools/events.js';
14
- import { usePrefix } from '../../internal/usePrefix.js';
15
- import { useId } from '../../internal/useId.js';
13
+ import ButtonBase from './ButtonBase.js';
16
14
 
17
15
  const ButtonKinds = ['primary', 'secondary', 'danger', 'ghost', 'danger--primary', 'danger--ghost', 'danger--tertiary', 'tertiary'];
18
16
  const ButtonSizes = ['sm', 'md', 'lg', 'xl', '2xl'];
@@ -24,18 +22,13 @@ function isIconOnlyButton(hasIconOnly, _kind) {
24
22
  }
25
23
  return false;
26
24
  }
27
- const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref) {
28
- let {
25
+ const Button = /*#__PURE__*/React__default.forwardRef(function Button(props, ref) {
26
+ const tooltipRef = useRef(null);
27
+ const {
29
28
  as,
30
29
  children,
31
- className,
32
- dangerDescription = 'danger',
33
- disabled = false,
34
30
  hasIconOnly = false,
35
- href,
36
31
  iconDescription,
37
- isExpressive = false,
38
- isSelected,
39
32
  kind = 'primary',
40
33
  onBlur,
41
34
  onClick,
@@ -44,92 +37,21 @@ const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref)
44
37
  onMouseLeave,
45
38
  renderIcon: ButtonImageElement,
46
39
  size,
47
- tabIndex,
48
40
  tooltipAlignment = 'center',
49
41
  tooltipPosition = 'top',
50
- type = 'button',
51
42
  ...rest
52
- } = _ref;
53
- const tooltipRef = useRef(null);
54
- const prefix = usePrefix();
43
+ } = props;
55
44
  const handleClick = evt => {
56
45
  // Prevent clicks on the tooltip from triggering the button click event
57
46
  if (evt.target === tooltipRef.current) {
58
47
  evt.preventDefault();
59
48
  }
60
49
  };
61
- const buttonClasses = cx(className, {
62
- [`${prefix}--btn`]: true,
63
- [`${prefix}--btn--sm`]: size === 'sm' && !isExpressive,
64
- // TODO: V12 - Remove this class
65
- [`${prefix}--btn--md`]: size === 'md' && !isExpressive,
66
- // TODO: V12 - Remove this class
67
- [`${prefix}--btn--xl`]: size === 'xl',
68
- // TODO: V12 - Remove this class
69
- [`${prefix}--btn--2xl`]: size === '2xl',
70
- // TODO: V12 - Remove this class
71
- [`${prefix}--layout--size-${size}`]: size,
72
- [`${prefix}--btn--${kind}`]: kind,
73
- [`${prefix}--btn--disabled`]: disabled,
74
- [`${prefix}--btn--expressive`]: isExpressive,
75
- [`${prefix}--btn--icon-only`]: hasIconOnly,
76
- [`${prefix}--btn--selected`]: hasIconOnly && isSelected && kind === 'ghost'
77
- });
78
- const commonProps = {
79
- tabIndex,
80
- className: buttonClasses,
81
- ref
82
- };
83
- const buttonImage = !ButtonImageElement ? null : /*#__PURE__*/React__default.createElement(ButtonImageElement, {
84
- "aria-label": iconDescription,
85
- className: `${prefix}--btn__icon`,
86
- "aria-hidden": "true"
87
- });
88
50
  const iconOnlyImage = !ButtonImageElement ? null : /*#__PURE__*/React__default.createElement(ButtonImageElement, null);
89
- const dangerButtonVariants = ['danger', 'danger--tertiary', 'danger--ghost'];
90
- let component = 'button';
91
- const assistiveId = useId('danger-description');
92
- const {
93
- 'aria-pressed': ariaPressed,
94
- 'aria-describedby': ariaDescribedBy
95
- } = rest;
96
- let otherProps = {
97
- disabled,
98
- type,
99
- 'aria-describedby': dangerButtonVariants.includes(kind) ? assistiveId : ariaDescribedBy || undefined,
100
- 'aria-pressed': ariaPressed ?? (hasIconOnly && kind === 'ghost' ? isSelected : undefined)
101
- };
102
- const anchorProps = {
103
- href
104
- };
105
- let assistiveText = null;
106
- if (dangerButtonVariants.includes(kind)) {
107
- assistiveText = /*#__PURE__*/React__default.createElement("span", {
108
- id: assistiveId,
109
- className: `${prefix}--visually-hidden`
110
- }, dangerDescription);
111
- }
112
- if (as) {
113
- component = as;
114
- otherProps = {
115
- ...otherProps,
116
- ...anchorProps
117
- };
118
- } else if (href && !disabled) {
119
- component = 'a';
120
- otherProps = anchorProps;
121
- }
122
51
  if (!isIconOnlyButton(hasIconOnly)) {
123
- return /*#__PURE__*/React__default.createElement(component, {
124
- onMouseEnter,
125
- onMouseLeave,
126
- onFocus,
127
- onBlur,
128
- onClick,
129
- ...rest,
130
- ...commonProps,
131
- ...otherProps
132
- }, assistiveText, children, buttonImage);
52
+ return /*#__PURE__*/React__default.createElement(ButtonBase, _extends({
53
+ ref: ref
54
+ }, props));
133
55
  } else {
134
56
  let align = undefined;
135
57
  if (tooltipPosition === 'top' || tooltipPosition === 'bottom') {
@@ -146,7 +68,8 @@ const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref)
146
68
  if (tooltipPosition === 'right' || tooltipPosition === 'left') {
147
69
  align = tooltipPosition;
148
70
  }
149
- return /*#__PURE__*/React__default.createElement(IconButton, _extends({
71
+ return /*#__PURE__*/React__default.createElement(IconButton, _extends({}, rest, {
72
+ ref: ref,
150
73
  as: as,
151
74
  align: align,
152
75
  label: iconDescription,
@@ -156,8 +79,9 @@ const Button = /*#__PURE__*/React__default.forwardRef(function Button(_ref, ref)
156
79
  onMouseLeave: onMouseLeave,
157
80
  onFocus: onFocus,
158
81
  onBlur: onBlur,
159
- onClick: composeEventHandlers([onClick, handleClick])
160
- }, rest, commonProps, otherProps), iconOnlyImage ?? children);
82
+ onClick: composeEventHandlers([onClick, handleClick]),
83
+ renderIcon: iconOnlyImage ? null : ButtonImageElement // avoid doubling the icon.
84
+ }), iconOnlyImage ?? children);
161
85
  }
162
86
  });
163
87
  Button.displayName = 'Button';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
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
+ import React from 'react';
8
+ import { ButtonProps } from './Button';
9
+ declare const ButtonBase: React.ForwardRefExoticComponent<Omit<ButtonProps<React.ElementType<any>>, "ref"> & React.RefAttributes<unknown>>;
10
+ export default ButtonBase;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
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
+ import React__default from 'react';
9
+ import cx from 'classnames';
10
+ import { usePrefix } from '../../internal/usePrefix.js';
11
+ import { useId } from '../../internal/useId.js';
12
+
13
+ const ButtonBase = /*#__PURE__*/React__default.forwardRef(function ButtonBase(_ref, ref) {
14
+ let {
15
+ as,
16
+ children,
17
+ className,
18
+ dangerDescription = 'danger',
19
+ disabled = false,
20
+ hasIconOnly = false,
21
+ href,
22
+ iconDescription,
23
+ isExpressive = false,
24
+ isSelected,
25
+ kind = 'primary',
26
+ onBlur,
27
+ onClick,
28
+ onFocus,
29
+ onMouseEnter,
30
+ onMouseLeave,
31
+ renderIcon: ButtonImageElement,
32
+ size,
33
+ tabIndex,
34
+ type = 'button',
35
+ ...rest
36
+ } = _ref;
37
+ const prefix = usePrefix();
38
+ const buttonClasses = cx(className, {
39
+ [`${prefix}--btn`]: true,
40
+ [`${prefix}--btn--sm`]: size === 'sm' && !isExpressive,
41
+ // TODO: V12 - Remove this class
42
+ [`${prefix}--btn--md`]: size === 'md' && !isExpressive,
43
+ // TODO: V12 - Remove this class
44
+ [`${prefix}--btn--xl`]: size === 'xl',
45
+ // TODO: V12 - Remove this class
46
+ [`${prefix}--btn--2xl`]: size === '2xl',
47
+ // TODO: V12 - Remove this class
48
+ [`${prefix}--layout--size-${size}`]: size,
49
+ [`${prefix}--btn--${kind}`]: kind,
50
+ [`${prefix}--btn--disabled`]: disabled,
51
+ [`${prefix}--btn--expressive`]: isExpressive,
52
+ [`${prefix}--btn--icon-only`]: hasIconOnly && !className?.includes(`${prefix}--btn--icon-only`),
53
+ [`${prefix}--btn--selected`]: hasIconOnly && isSelected && kind === 'ghost'
54
+ });
55
+ const commonProps = {
56
+ tabIndex,
57
+ className: buttonClasses,
58
+ ref
59
+ };
60
+ const buttonImage = !ButtonImageElement ? null : /*#__PURE__*/React__default.createElement(ButtonImageElement, {
61
+ "aria-label": iconDescription,
62
+ className: `${prefix}--btn__icon`,
63
+ "aria-hidden": "true"
64
+ });
65
+ const dangerButtonVariants = ['danger', 'danger--tertiary', 'danger--ghost'];
66
+ let component = 'button';
67
+ const assistiveId = useId('danger-description');
68
+ const {
69
+ 'aria-pressed': ariaPressed,
70
+ 'aria-describedby': ariaDescribedBy
71
+ } = rest;
72
+ let otherProps = {
73
+ disabled,
74
+ type,
75
+ 'aria-describedby': dangerButtonVariants.includes(kind) ? assistiveId : ariaDescribedBy || undefined,
76
+ 'aria-pressed': ariaPressed ?? (hasIconOnly && kind === 'ghost' ? isSelected : undefined)
77
+ };
78
+ const anchorProps = {
79
+ href
80
+ };
81
+ let assistiveText = null;
82
+ if (dangerButtonVariants.includes(kind)) {
83
+ assistiveText = /*#__PURE__*/React__default.createElement("span", {
84
+ id: assistiveId,
85
+ className: `${prefix}--visually-hidden`
86
+ }, dangerDescription);
87
+ }
88
+ if (as) {
89
+ component = as;
90
+ otherProps = {
91
+ ...otherProps,
92
+ ...anchorProps
93
+ };
94
+ } else if (href && !disabled) {
95
+ component = 'a';
96
+ otherProps = anchorProps;
97
+ }
98
+ return /*#__PURE__*/React__default.createElement(component, {
99
+ onMouseEnter,
100
+ onMouseLeave,
101
+ onFocus,
102
+ onBlur,
103
+ onClick,
104
+ ...rest,
105
+ ...commonProps,
106
+ ...otherProps
107
+ }, assistiveText, children, buttonImage);
108
+ });
109
+
110
+ export { ButtonBase as default };
@@ -155,6 +155,7 @@ function CodeSnippet(_ref) {
155
155
  feedback: feedback,
156
156
  feedbackTimeout: feedbackTimeout
157
157
  }), /*#__PURE__*/React__default.createElement("code", {
158
+ "aria-live": "assertive",
158
159
  id: uid,
159
160
  ref: innerCodeRef
160
161
  }, children));
@@ -238,7 +238,9 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
238
238
  const titleClasses = cx(`${prefix}--label`, {
239
239
  [`${prefix}--label--disabled`]: disabled
240
240
  });
241
- const comboBoxHelperId = !helperText ? undefined : `combobox-helper-text-${comboBoxInstanceId}`;
241
+ const helperTextId = `combobox-helper-text-${comboBoxInstanceId}`;
242
+ const warnTextId = `combobox-warn-text-${comboBoxInstanceId}`;
243
+ const invalidTextId = `combobox-invalid-text-${comboBoxInstanceId}`;
242
244
  const helperClasses = cx(`${prefix}--form__helper-text`, {
243
245
  [`${prefix}--form__helper-text--disabled`]: disabled
244
246
  });
@@ -376,6 +378,11 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
376
378
  }
377
379
  }
378
380
  } : {};
381
+
382
+ // The input should be described by the appropriate message text id
383
+ // when both the message is supplied *and* when the component is in
384
+ // the matching state (invalid, warn, etc).
385
+ const ariaDescribedBy = invalid && invalidText && invalidTextId || warn && warnText && warnTextId || helperText && !isFluid && helperTextId || undefined;
379
386
  return /*#__PURE__*/React__default.createElement("div", {
380
387
  className: wrapperClasses
381
388
  }, titleText && /*#__PURE__*/React__default.createElement(Text, _extends({
@@ -388,11 +395,13 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
388
395
  disabled: disabled,
389
396
  invalid: invalid,
390
397
  invalidText: invalidText,
398
+ invalidTextId: invalidTextId,
391
399
  isOpen: isOpen,
392
400
  light: light,
393
401
  size: size,
394
402
  warn: warn,
395
- warnText: warnText
403
+ warnText: warnText,
404
+ warnTextId: warnTextId
396
405
  }, /*#__PURE__*/React__default.createElement("div", {
397
406
  className: `${prefix}--list-box__field`
398
407
  }, /*#__PURE__*/React__default.createElement("input", _extends({
@@ -410,7 +419,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
410
419
  }, inputProps, rest, readOnlyEventHandlers, {
411
420
  readOnly: readOnly,
412
421
  ref: mergeRefs(textInput, ref),
413
- "aria-describedby": helperText && !invalid && !warn && !isFluid ? comboBoxHelperId : undefined
422
+ "aria-describedby": ariaDescribedBy
414
423
  })), invalid && /*#__PURE__*/React__default.createElement(WarningFilled, {
415
424
  className: `${prefix}--list-box__invalid-icon`
416
425
  }), showWarning && /*#__PURE__*/React__default.createElement(WarningAltFilled, {
@@ -449,7 +458,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
449
458
  }));
450
459
  }) : null)), helperText && !invalid && !warn && !isFluid && (_Text || (_Text = /*#__PURE__*/React__default.createElement(Text, {
451
460
  as: "div",
452
- id: comboBoxHelperId,
461
+ id: helperTextId,
453
462
  className: helperClasses
454
463
  }, helperText))));
455
464
  });
@@ -152,7 +152,7 @@ ComboButton.propTypes = {
152
152
  /**
153
153
  * Specify how the trigger tooltip should be aligned.
154
154
  */
155
- tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
155
+ tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-start', 'top-right', 'top-end', 'bottom', 'bottom-left', 'bottom-start', 'bottom-right', 'bottom-end', 'left', 'right']),
156
156
  /**
157
157
  * Optional method that takes in a message id and returns an
158
158
  * internationalized string.
@@ -17,10 +17,11 @@ import mergeRefs from '../../tools/mergeRefs.js';
17
17
  import cx from 'classnames';
18
18
  import toggleClass from '../../tools/toggleClass.js';
19
19
  import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
20
- import wrapFocus from '../../internal/wrapFocus.js';
20
+ import wrapFocus, { wrapFocusWithoutSentinels } from '../../internal/wrapFocus.js';
21
21
  import { usePrefix } from '../../internal/usePrefix.js';
22
+ import { useFeatureFlag } from '../FeatureFlags/index.js';
22
23
  import { match } from '../../internal/keyboard/match.js';
23
- import { Escape } from '../../internal/keyboard/keys.js';
24
+ import { Escape, Tab } from '../../internal/keyboard/keys.js';
24
25
 
25
26
  const ModalBody = /*#__PURE__*/React__default.forwardRef(function ModalBody(_ref, ref) {
26
27
  let {
@@ -114,6 +115,7 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
114
115
  const button = useRef(null);
115
116
  const startSentinel = useRef(null);
116
117
  const endSentinel = useRef(null);
118
+ const focusTrapWithoutSentinels = useFeatureFlag('enable-experimental-focus-wrap-without-sentinels');
117
119
 
118
120
  // Keep track of modal open/close state
119
121
  // and propagate it to the document.body
@@ -131,12 +133,19 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
131
133
  };
132
134
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
133
135
 
134
- function handleKeyDown(evt) {
135
- evt.stopPropagation();
136
- if (match(evt, Escape)) {
137
- closeModal(evt);
136
+ function handleKeyDown(event) {
137
+ event.stopPropagation();
138
+ if (match(event, Escape)) {
139
+ closeModal(event);
140
+ }
141
+ if (focusTrapWithoutSentinels && open && match(event, Tab) && innerModal.current) {
142
+ wrapFocusWithoutSentinels({
143
+ containerNode: innerModal.current,
144
+ currentActiveNode: event.target,
145
+ event: event
146
+ });
138
147
  }
139
- onKeyDown?.(evt);
148
+ onKeyDown?.(event);
140
149
  }
141
150
  function handleMousedown(evt) {
142
151
  evt.stopPropagation();
@@ -244,7 +253,7 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
244
253
  role: "presentation",
245
254
  ref: ref,
246
255
  "aria-hidden": !open,
247
- onBlur: handleBlur,
256
+ onBlur: !focusTrapWithoutSentinels ? handleBlur : () => {},
248
257
  onMouseDown: handleMousedown,
249
258
  onKeyDown: handleKeyDown,
250
259
  className: modalClass
@@ -254,14 +263,14 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
254
263
  "aria-modal": "true",
255
264
  "aria-label": ariaLabel ? ariaLabel : generatedAriaLabel,
256
265
  "aria-labelledby": ariaLabelledBy
257
- }, /*#__PURE__*/React__default.createElement("button", {
266
+ }, !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("button", {
258
267
  type: "button",
259
268
  ref: startSentinel,
260
269
  className: `${prefix}--visually-hidden`
261
270
  }, "Focus sentinel"), /*#__PURE__*/React__default.createElement("div", {
262
271
  ref: innerModal,
263
272
  className: `${prefix}--modal-container-body`
264
- }, normalizedSlug, childrenWithProps), /*#__PURE__*/React__default.createElement("button", {
273
+ }, normalizedSlug, childrenWithProps), !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("button", {
265
274
  type: "button",
266
275
  ref: endSentinel,
267
276
  className: `${prefix}--visually-hidden`
@@ -314,7 +314,7 @@ class DataTable extends React__default.Component {
314
314
  isSortable,
315
315
  useStaticWidth,
316
316
  stickyHeader,
317
- overflowMenuOnHover = true,
317
+ overflowMenuOnHover = false,
318
318
  experimentalAutoAlign
319
319
  } = this.props;
320
320
  return {
@@ -24,7 +24,7 @@ export interface TableBatchActionProps extends React.ButtonHTMLAttributes<HTMLBu
24
24
  declare const TableBatchAction: {
25
25
  ({ renderIcon, iconDescription, ...props }: {
26
26
  [x: string]: any;
27
- renderIcon?: import("@carbon/icons-react/lib/CarbonIcon").CarbonIconType | undefined;
27
+ renderIcon?: import("@carbon/icons-react").CarbonIconType | undefined;
28
28
  iconDescription?: string | undefined;
29
29
  }): import("react/jsx-runtime").JSX.Element;
30
30
  propTypes: {
@@ -8,13 +8,17 @@ import React from 'react';
8
8
  export interface TableToolbarMenuProps extends React.HTMLAttributes<HTMLDivElement> {
9
9
  children: React.ReactNode;
10
10
  /**
11
- * Provide an optional class name for the toolbar menu
11
+ * Provide an optional class name for the toolbar menu trigger button
12
12
  */
13
13
  className?: string;
14
14
  /**
15
15
  * The description of the menu icon.
16
16
  */
17
17
  iconDescription?: string;
18
+ /**
19
+ * Provide an optional class name for the toolbar menu
20
+ */
21
+ menuOptionsClass?: string;
18
22
  /**
19
23
  * Optional prop to allow overriding the default menu icon
20
24
  */
@@ -20,16 +20,19 @@ const TableToolbarMenu = _ref => {
20
20
  renderIcon = Settings,
21
21
  iconDescription = defaultIconDescription,
22
22
  children,
23
+ menuOptionsClass,
23
24
  ...rest
24
25
  } = _ref;
25
26
  const prefix = usePrefix();
26
27
  const toolbarActionClasses = cx(className, `${prefix}--toolbar-action ${prefix}--overflow-menu`);
28
+ const menuOptionsClasses = cx(menuOptionsClass, `${prefix}--toolbar-action__menu`);
27
29
  return /*#__PURE__*/React__default.createElement(OverflowMenu, _extends({
28
30
  "aria-label": iconDescription,
29
31
  renderIcon: renderIcon,
30
32
  className: toolbarActionClasses,
31
33
  title: iconDescription,
32
34
  iconDescription: iconDescription,
35
+ menuOptionsClass: menuOptionsClasses,
33
36
  flipped: true
34
37
  }, rest), children);
35
38
  };
@@ -43,6 +46,10 @@ TableToolbarMenu.propTypes = {
43
46
  * The description of the menu icon.
44
47
  */
45
48
  iconDescription: PropTypes.string,
49
+ /**
50
+ * Provide an optional class name for the toolbar menu
51
+ */
52
+ menuOptionsClass: PropTypes.string,
46
53
  /**
47
54
  * Optional prop to allow overriding the default menu icon
48
55
  */
@@ -102,6 +102,10 @@ interface DatePickerProps {
102
102
  * The `open` event handler.
103
103
  */
104
104
  onOpen?: flatpickr.Options.Hook;
105
+ /**
106
+ * flatpickr prop passthrough. Controls how dates are parsed.
107
+ */
108
+ parseDate?: (date: string) => Date | false;
105
109
  /**
106
110
  * whether the DatePicker is to be readOnly
107
111
  * if boolean applies to all inputs
@@ -158,6 +158,7 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
158
158
  readOnly = false,
159
159
  short = false,
160
160
  value,
161
+ parseDate: parseDateProp,
161
162
  ...rest
162
163
  } = _ref;
163
164
  const prefix = usePrefix();
@@ -267,6 +268,37 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
267
268
  } else {
268
269
  localeData = l10n[locale];
269
270
  }
271
+
272
+ /**
273
+ * parseDate is called before the date is actually set.
274
+ * It attempts to parse the input value and return a valid date string.
275
+ * Flatpickr's default parser results in odd dates when given invalid
276
+ * values, so instead here we normalize the month/day to `1` if given
277
+ * a value outside the acceptable range.
278
+ */
279
+ let parseDate;
280
+ if (!parseDateProp && dateFormat === 'm/d/Y') {
281
+ // This function only supports the default dateFormat.
282
+ parseDate = date => {
283
+ // Month must be 1-12. If outside these bounds, `1` should be used.
284
+ const month = date.split('/')[0] <= 12 && date.split('/')[0] > 0 ? parseInt(date.split('/')[0]) : 1;
285
+ const year = parseInt(date.split('/')[2]);
286
+ if (month && year) {
287
+ // The month and year must be provided to be able to determine
288
+ // the number of days in the month.
289
+ const daysInMonth = new Date(year, month, 0).getDate();
290
+ // If the day does not fall within the days in the month, `1` should be used.
291
+ const day = date.split('/')[1] <= daysInMonth && date.split('/')[1] > 0 ? parseInt(date.split('/')[1]) : 1;
292
+ return new Date(`${year}/${month}/${day}`);
293
+ } else {
294
+ // With no month and year, we cannot calculate anything.
295
+ // Returning false gives flatpickr an invalid date, which will clear the input
296
+ return false;
297
+ }
298
+ };
299
+ } else if (parseDateProp) {
300
+ parseDate = parseDateProp;
301
+ }
270
302
  const {
271
303
  current: start
272
304
  } = startInputField;
@@ -285,6 +317,7 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
285
317
  [enableOrDisable]: enableOrDisableArr,
286
318
  minDate: minDate,
287
319
  maxDate: maxDate,
320
+ parseDate: parseDate,
288
321
  plugins: [datePickerType === 'range' ? carbonFlatpickrRangePlugin({
289
322
  input: endInputField.current
290
323
  }) : () => {}, appendTo ? carbonFlatpickrAppendToPlugin({
@@ -696,6 +729,10 @@ DatePicker.propTypes = {
696
729
  * `(dates: Date[], dStr: string, fp: Instance, data?: any):void;`
697
730
  */
698
731
  onOpen: PropTypes.func,
732
+ /**
733
+ * flatpickr prop passthrough. Controls how dates are parsed.
734
+ */
735
+ parseDate: PropTypes.func,
699
736
  /**
700
737
  * whether the DatePicker is to be readOnly
701
738
  * if boolean applies to all inputs
@@ -13,7 +13,7 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
13
13
  /**
14
14
  * Specify how the trigger should align with the tooltip
15
15
  */
16
- align?: 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
16
+ align?: 'top' | 'top-left' | 'top-start' | 'top-right' | 'top-end' | 'bottom' | 'bottom-left' | 'bottom-start' | 'bottom-right' | 'bottom-end' | 'left' | 'right';
17
17
  /**
18
18
  * Provide an icon or asset to be rendered inside of the IconButton
19
19
  */
@@ -8,12 +8,11 @@
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
10
  import React__default from 'react';
11
- import Button from '../Button/Button.js';
12
- import '../Button/Button.Skeleton.js';
13
11
  import cx from 'classnames';
14
12
  import '../Tooltip/DefinitionTooltip.js';
15
13
  import { Tooltip } from '../Tooltip/Tooltip.js';
16
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
+ import ButtonBase from '../Button/ButtonBase.js';
17
16
 
18
17
  const IconButtonKinds = ['primary', 'secondary', 'ghost', 'tertiary'];
19
18
  const IconButton = /*#__PURE__*/React__default.forwardRef(function IconButton(_ref, ref) {
@@ -45,7 +44,7 @@ const IconButton = /*#__PURE__*/React__default.forwardRef(function IconButton(_r
45
44
  enterDelayMs: enterDelayMs,
46
45
  label: label,
47
46
  leaveDelayMs: leaveDelayMs
48
- }, /*#__PURE__*/React__default.createElement(Button, _extends({}, rest, {
47
+ }, /*#__PURE__*/React__default.createElement(ButtonBase, _extends({}, rest, {
49
48
  disabled: disabled,
50
49
  kind: kind,
51
50
  ref: ref,
@@ -59,7 +58,7 @@ IconButton.propTypes = {
59
58
  /**
60
59
  * Specify how the trigger should align with the tooltip
61
60
  */
62
- align: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
61
+ align: PropTypes.oneOf(['top', 'top-left', 'top-start', 'top-right', 'top-end', 'bottom', 'bottom-left', 'bottom-start', 'bottom-right', 'bottom-end', 'left', 'right']),
63
62
  /**
64
63
  * Provide an icon or asset to be rendered inside of the IconButton
65
64
  */
@@ -21,6 +21,10 @@ export interface ListBoxProps extends Omit<ReactAttr<HTMLDivElement>, ExcludedAt
21
21
  * Specify the text to be displayed when the control is invalid
22
22
  */
23
23
  invalidText?: React.ReactNode;
24
+ /**
25
+ * Specify the id to be applied to the element containing the invalid text
26
+ */
27
+ invalidTextId?: string;
24
28
  /**
25
29
  * Specify if the control should render open
26
30
  */
@@ -50,6 +54,10 @@ export interface ListBoxProps extends Omit<ReactAttr<HTMLDivElement>, ExcludedAt
50
54
  * Provide the text that is displayed when the control is in warning state
51
55
  */
52
56
  warnText?: React.ReactNode;
57
+ /**
58
+ * Specify the id to be applied to the element containing the warn text
59
+ */
60
+ warnTextId?: string;
53
61
  }
54
62
  export type ListBoxComponent = ForwardRefReturn<HTMLDivElement, ListBoxProps>;
55
63
  /**