@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
@@ -4,9 +4,6 @@
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 { ReactNode } from 'react';
8
- import { Stack } from './Stack';
9
- import { ForwardRefReturn } from '../../types/common';
10
- declare const HStack: ForwardRefReturn<ReactNode>;
11
- declare const VStack: ForwardRefReturn<ReactNode>;
12
- export { HStack, Stack, VStack };
7
+ export { HStack } from './HStack';
8
+ export { VStack } from './VStack';
9
+ export { Stack, type StackProps } from './Stack';
@@ -144,6 +144,10 @@ export interface StructuredListRowProps extends DivAttrs {
144
144
  * Provide a handler that is invoked on the key down event for the control
145
145
  */
146
146
  onKeyDown?(event: KeyboardEvent): void;
147
+ /**
148
+ * Mark if this row should be selectable
149
+ */
150
+ selection?: boolean;
147
151
  }
148
152
  export declare function StructuredListRow(props: StructuredListRowProps): import("react/jsx-runtime").JSX.Element;
149
153
  export declare namespace StructuredListRow {
@@ -172,6 +176,10 @@ export declare namespace StructuredListRow {
172
176
  * Provide a handler that is invoked on the key down event for the control,
173
177
  */
174
178
  onKeyDown: PropTypes.Requireable<(...args: any[]) => any>;
179
+ /**
180
+ * Mark if this row should be selectable
181
+ */
182
+ selection: PropTypes.Requireable<boolean>;
175
183
  };
176
184
  }
177
185
  export interface StructuredListInputProps extends DivAttrs {
@@ -6,15 +6,18 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useState } from 'react';
9
+ import React__default, { useState, useRef } from 'react';
10
10
  import PropTypes from 'prop-types';
11
11
  import cx from 'classnames';
12
12
  import { useId } from '../../internal/useId.js';
13
13
  import deprecate from '../../prop-types/deprecate.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
15
  import '../Text/index.js';
16
+ import { RadioButtonChecked, RadioButton } from '@carbon/icons-react';
17
+ import { useOutsideClick } from '../../internal/useOutsideClick.js';
16
18
  import { Text } from '../Text/Text.js';
17
19
 
20
+ var _StructuredListCell, _RadioButtonChecked, _RadioButton;
18
21
  const GridSelectedRowStateContext = /*#__PURE__*/React__default.createContext(null);
19
22
  const GridSelectedRowDispatchContext = /*#__PURE__*/React__default.createContext(null);
20
23
  function StructuredListWrapper(props) {
@@ -137,6 +140,7 @@ function StructuredListRow(props) {
137
140
  className,
138
141
  head,
139
142
  onClick,
143
+ selection,
140
144
  ...other
141
145
  } = props;
142
146
  const [hasFocusWithin, setHasFocusWithin] = useState(false);
@@ -149,25 +153,35 @@ function StructuredListRow(props) {
149
153
  };
150
154
  const classes = cx(`${prefix}--structured-list-row`, {
151
155
  [`${prefix}--structured-list-row--header-row`]: head,
152
- [`${prefix}--structured-list-row--focused-within`]: hasFocusWithin,
156
+ [`${prefix}--structured-list-row--focused-within`]: hasFocusWithin && !selection || hasFocusWithin && selection && (selectedRow === id || selectedRow === null),
157
+ // Ensure focus on the first item when navigating through Tab keys and no row is selected (selectedRow === null)
153
158
  [`${prefix}--structured-list-row--selected`]: selectedRow === id
154
159
  }, className);
160
+ const itemRef = useRef(null);
161
+ const handleClick = () => {
162
+ setHasFocusWithin(false);
163
+ };
164
+ useOutsideClick(itemRef, handleClick);
155
165
  return head ? /*#__PURE__*/React__default.createElement("div", _extends({
156
166
  role: "row"
157
167
  }, other, {
158
- className: classes,
159
- "aria-busy": "true"
160
- }), children) :
168
+ className: classes
169
+ }), selection && (_StructuredListCell || (_StructuredListCell = /*#__PURE__*/React__default.createElement(StructuredListCell, {
170
+ head: true
171
+ }))), children) :
161
172
  /*#__PURE__*/
162
173
  // eslint-disable-next-line jsx-a11y/interactive-supports-focus
163
- React__default.createElement("div", _extends({
164
- "aria-busy": "true"
165
- }, other, {
174
+ React__default.createElement("div", _extends({}, other, {
166
175
  role: "row",
167
176
  className: classes,
177
+ ref: itemRef,
168
178
  onClick: event => {
169
179
  setSelectedRow?.(id);
170
180
  onClick && onClick(event);
181
+ if (selection) {
182
+ // focus items only when selection is enabled
183
+ setHasFocusWithin(true);
184
+ }
171
185
  },
172
186
  onFocus: () => {
173
187
  setHasFocusWithin(true);
@@ -178,7 +192,7 @@ function StructuredListRow(props) {
178
192
  onKeyDown: onKeyDown
179
193
  }), /*#__PURE__*/React__default.createElement(GridRowContext.Provider, {
180
194
  value: value
181
- }, children));
195
+ }, selection && /*#__PURE__*/React__default.createElement(StructuredListCell, null, selectedRow === id ? _RadioButtonChecked || (_RadioButtonChecked = /*#__PURE__*/React__default.createElement(RadioButtonChecked, null)) : _RadioButton || (_RadioButton = /*#__PURE__*/React__default.createElement(RadioButton, null))), children));
182
196
  }
183
197
  StructuredListRow.propTypes = {
184
198
  /**
@@ -204,7 +218,11 @@ StructuredListRow.propTypes = {
204
218
  /**
205
219
  * Provide a handler that is invoked on the key down event for the control,
206
220
  */
207
- onKeyDown: PropTypes.func
221
+ onKeyDown: PropTypes.func,
222
+ /**
223
+ * Mark if this row should be selectable
224
+ */
225
+ selection: PropTypes.bool
208
226
  };
209
227
  function StructuredListInput(props) {
210
228
  const defaultId = useId('structureListInput');
@@ -9,7 +9,6 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
9
9
  import PropTypes from 'prop-types';
10
10
  import React__default, { useState } from 'react';
11
11
  import RadioTile from '../RadioTile/RadioTile.js';
12
- import { warning } from '../../internal/warning.js';
13
12
  import { usePrefix } from '../../internal/usePrefix.js';
14
13
  import { noopFn } from '../../internal/noopFn.js';
15
14
 
@@ -36,28 +35,35 @@ const TileGroup = props => {
36
35
  setSelected(valueSelected);
37
36
  setPrevValueSelected(valueSelected);
38
37
  }
39
- const getRadioTiles = () => {
40
- const childrenArray = React__default.Children.toArray(children);
41
- const radioTiles = childrenArray.map(tileRadio => {
42
- const tileRadioProps = tileRadio.props ?? undefined;
43
- const {
44
- value,
45
- ...other
46
- } = tileRadioProps;
47
- /* istanbul ignore if */
48
- if (typeof tileRadioProps.checked !== 'undefined') {
49
- process.env.NODE_ENV !== "production" ? warning(false, `Instead of using the checked property on the RadioTile, set
50
- the defaultSelected property or valueSelected property on the TileGroup.`) : void 0;
51
- }
52
- return /*#__PURE__*/React__default.createElement(RadioTile, _extends({}, other, {
53
- name: name,
54
- key: value,
55
- value: value,
56
- onChange: handleChange,
57
- checked: value === selected
58
- }));
59
- });
60
- return radioTiles;
38
+ const getRadioTilesWithWrappers = children => {
39
+ const traverseAndModifyChildren = children => {
40
+ return React__default.Children.map(children, child => {
41
+ // If RadioTile found, return it with necessary props
42
+ if (child.type === RadioTile) {
43
+ const {
44
+ value,
45
+ ...otherProps
46
+ } = child.props;
47
+ return /*#__PURE__*/React__default.createElement(RadioTile, _extends({}, otherProps, {
48
+ name: name,
49
+ key: value,
50
+ value: value,
51
+ onChange: handleChange,
52
+ checked: value === selected
53
+ }));
54
+ } else if (child.props && child.props.children) {
55
+ // If the child is not RadioTile and has children, recheck the children
56
+ return /*#__PURE__*/React__default.cloneElement(child, {
57
+ ...child.props,
58
+ children: traverseAndModifyChildren(child.props.children)
59
+ });
60
+ } else {
61
+ // If the child is neither a RadioTile nor has children, return it as is
62
+ return child;
63
+ }
64
+ });
65
+ };
66
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, traverseAndModifyChildren(children));
61
67
  };
62
68
  const handleChange = (newSelection, value, evt) => {
63
69
  if (newSelection !== selected) {
@@ -75,7 +81,7 @@ const TileGroup = props => {
75
81
  return /*#__PURE__*/React__default.createElement("fieldset", {
76
82
  className: className ?? `${prefix}--tile-group`,
77
83
  disabled: disabled
78
- }, renderLegend(legend), /*#__PURE__*/React__default.createElement("div", null, getRadioTiles()));
84
+ }, renderLegend(legend), /*#__PURE__*/React__default.createElement("div", null, getRadioTilesWithWrappers(children)));
79
85
  };
80
86
  TileGroup.propTypes = {
81
87
  /**
@@ -89,24 +89,7 @@ export type ToggleTipButtonProps<T extends React.ElementType> = PolymorphicProps
89
89
  * `ToggletipButton` controls the visibility of the Toggletip through mouse
90
90
  * clicks and keyboard interactions.
91
91
  */
92
- export declare function ToggletipButton<T extends React.ElementType>({ children, className: customClassName, label, as: BaseComponent, ...rest }: ToggleTipButtonProps<T>): import("react/jsx-runtime").JSX.Element;
93
- export declare namespace ToggletipButton {
94
- var propTypes: {
95
- /**
96
- * Custom children to be rendered as the content of the label
97
- */
98
- children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
99
- /**
100
- * Provide a custom class name to be added to the outermost node in the
101
- * component
102
- */
103
- className: PropTypes.Requireable<string>;
104
- /**
105
- * Provide an accessible label for this button
106
- */
107
- label: PropTypes.Requireable<string>;
108
- };
109
- }
92
+ export declare const ToggletipButton: React.ForwardRefExoticComponent<Omit<ToggleTipButtonProps<React.ElementType<any>>, "ref"> & React.RefAttributes<unknown>>;
110
93
  interface ToggletipContentProps {
111
94
  children?: ReactNode;
112
95
  className?: string | undefined;
@@ -150,7 +150,28 @@ Toggletip.propTypes = {
150
150
  /**
151
151
  * Specify how the toggletip should align with the button
152
152
  */
153
- align: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top']),
153
+ align: PropTypes.oneOf(['top', 'top-left',
154
+ // deprecated use top-start instead
155
+ 'top-right',
156
+ // deprecated use top-end instead
157
+
158
+ 'bottom', 'bottom-left',
159
+ // deprecated use bottom-start instead
160
+ 'bottom-right',
161
+ // deprecated use bottom-end instead
162
+
163
+ 'left', 'left-bottom',
164
+ // deprecated use left-end instead
165
+ 'left-top',
166
+ // deprecated use left-start instead
167
+
168
+ 'right', 'right-bottom',
169
+ // deprecated use right-end instead
170
+ 'right-top',
171
+ // deprecated use right-start instead
172
+
173
+ // new values to match floating-ui
174
+ 'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
154
175
  /**
155
176
  * Provide a custom element or component to render the top-level node for the
156
177
  * component.
@@ -178,7 +199,7 @@ Toggletip.propTypes = {
178
199
  * `ToggletipButton` controls the visibility of the Toggletip through mouse
179
200
  * clicks and keyboard interactions.
180
201
  */
181
- function ToggletipButton(_ref3) {
202
+ const ToggletipButton = /*#__PURE__*/React__default.forwardRef(function ToggletipButton(_ref3, ref) {
182
203
  let {
183
204
  children,
184
205
  className: customClassName,
@@ -198,9 +219,10 @@ function ToggletipButton(_ref3) {
198
219
  return /*#__PURE__*/React__default.createElement("button", _extends({}, toggletip?.buttonProps, {
199
220
  "aria-label": label,
200
221
  type: "button",
201
- className: className
222
+ className: className,
223
+ ref: ref
202
224
  }, rest), children);
203
- }
225
+ });
204
226
  ToggletipButton.propTypes = {
205
227
  /**
206
228
  * Custom children to be rendered as the content of the label
@@ -216,6 +238,7 @@ ToggletipButton.propTypes = {
216
238
  */
217
239
  label: PropTypes.string
218
240
  };
241
+ ToggletipButton.displayName = 'ToggletipButton';
219
242
  /**
220
243
  * `ToggletipContent` is a wrapper around `PopoverContent`. It places the
221
244
  * `children` passed in as a prop inside of `PopoverContent` so that they will
@@ -34,7 +34,6 @@ function Tooltip(_ref) {
34
34
  closeOnActivation = false,
35
35
  ...rest
36
36
  } = _ref;
37
- const containerRef = useRef(null);
38
37
  const tooltipRef = useRef(null);
39
38
  const [open, setOpen] = useDelayedState(defaultOpen);
40
39
  const [isDragging, setIsDragging] = useState(false);
@@ -130,8 +129,7 @@ function Tooltip(_ref) {
130
129
  highContrast: true,
131
130
  onKeyDown: onKeyDown,
132
131
  onMouseLeave: onMouseLeave,
133
- open: open,
134
- ref: containerRef
132
+ open: open
135
133
  }), /*#__PURE__*/React__default.createElement("div", {
136
134
  className: `${prefix}--tooltip-trigger__wrapper`
137
135
  }, child !== undefined ? /*#__PURE__*/React__default.cloneElement(child, {
@@ -141,7 +139,6 @@ function Tooltip(_ref) {
141
139
  "aria-hidden": open ? 'false' : 'true',
142
140
  className: `${prefix}--tooltip-content`,
143
141
  id: id,
144
- ref: tooltipRef,
145
142
  role: "tooltip"
146
143
  }, label || description));
147
144
  }
@@ -149,7 +146,28 @@ Tooltip.propTypes = {
149
146
  /**
150
147
  * Specify how the trigger should align with the tooltip
151
148
  */
152
- align: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top']),
149
+ align: PropTypes.oneOf(['top', 'top-left',
150
+ // deprecated use top-start instead
151
+ 'top-right',
152
+ // deprecated use top-end instead
153
+
154
+ 'bottom', 'bottom-left',
155
+ // deprecated use bottom-start instead
156
+ 'bottom-right',
157
+ // deprecated use bottom-end instead
158
+
159
+ 'left', 'left-bottom',
160
+ // deprecated use left-end instead
161
+ 'left-top',
162
+ // deprecated use left-start instead
163
+
164
+ 'right', 'right-bottom',
165
+ // deprecated use right-end instead
166
+ 'right-top',
167
+ // deprecated use right-start instead
168
+
169
+ // new values to match floating-ui
170
+ 'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
153
171
  /**
154
172
  * Pass in the child to which the tooltip will be applied
155
173
  */
@@ -12,5 +12,6 @@ FeatureFlags.merge({
12
12
  'enable-css-grid': true,
13
13
  'enable-v11-release': true,
14
14
  'enable-experimental-tile-contrast': false,
15
- 'enable-v12-tile-radio-icons': false
15
+ 'enable-v12-tile-radio-icons': false,
16
+ 'enable-v12-structured-list-visible-icons': false
16
17
  });
package/es/index.d.ts CHANGED
@@ -74,6 +74,7 @@ export * from './components/SkeletonIcon';
74
74
  export * from './components/SkeletonPlaceholder';
75
75
  export * from './components/SkeletonText';
76
76
  export * from './components/Slider';
77
+ export * from './components/Stack';
77
78
  export * from './components/StructuredList';
78
79
  export * from './components/Switch';
79
80
  export * from './components/Tab';
package/es/index.js CHANGED
@@ -73,6 +73,7 @@ export { NumberInput } from './components/NumberInput/NumberInput.js';
73
73
  export { default as OrderedList } from './components/OrderedList/OrderedList.js';
74
74
  export { default as OverflowMenu } from './components/OverflowMenu/index.js';
75
75
  export { default as OverflowMenuItem } from './components/OverflowMenuItem/OverflowMenuItem.js';
76
+ export { default as Pagination } from './components/Pagination/Pagination.js';
76
77
  export { default as PaginationSkeleton } from './components/Pagination/Pagination.Skeleton.js';
77
78
  export { default as PaginationNav } from './components/PaginationNav/PaginationNav.js';
78
79
  export { default as PrimaryButton } from './components/PrimaryButton/PrimaryButton.js';
@@ -81,6 +82,7 @@ export { ProgressIndicator, ProgressStep } from './components/ProgressIndicator/
81
82
  export { default as RadioButton } from './components/RadioButton/RadioButton.js';
82
83
  export { default as RadioButtonSkeleton } from './components/RadioButton/RadioButton.Skeleton.js';
83
84
  export { default as RadioButtonGroup } from './components/RadioButtonGroup/RadioButtonGroup.js';
85
+ export { default as RadioTile } from './components/RadioTile/RadioTile.js';
84
86
  export { default as Search } from './components/Search/Search.js';
85
87
  export { default as SearchSkeleton } from './components/Search/Search.Skeleton.js';
86
88
  export { default as SecondaryButton } from './components/SecondaryButton/SecondaryButton.js';
@@ -92,6 +94,9 @@ export { default as SkeletonIcon } from './components/SkeletonIcon/SkeletonIcon.
92
94
  export { default as SkeletonPlaceholder } from './components/SkeletonPlaceholder/SkeletonPlaceholder.js';
93
95
  export { default as SkeletonText } from './components/SkeletonText/SkeletonText.js';
94
96
  export { default as Slider } from './components/Slider/index.js';
97
+ export { HStack } from './components/Stack/HStack.js';
98
+ export { VStack } from './components/Stack/VStack.js';
99
+ export { Stack } from './components/Stack/Stack.js';
95
100
  export { StructuredListBody, StructuredListCell, StructuredListHead, StructuredListInput, StructuredListRow, StructuredListWrapper } from './components/StructuredList/StructuredList.js';
96
101
  export { default as StructuredListSkeleton } from './components/StructuredList/StructuredList.Skeleton.js';
97
102
  export { default as Switch } from './components/Switch/Switch.js';
@@ -154,7 +159,6 @@ export { Slug as unstable__Slug, SlugActions as unstable__SlugActions, SlugConte
154
159
  export { default as unstable__AiSkeletonPlaceholder } from './components/AiSkeleton/AiSkeletonPlaceholder.js';
155
160
  export { default as unstable__AiSkeletonIcon } from './components/AiSkeleton/AiSkeletonIcon.js';
156
161
  export { default as unstable__AiSkeletonText } from './components/AiSkeleton/AiSkeletonText.js';
157
- export { HStack, VStack } from './components/Stack/index.js';
158
162
  export { DefinitionTooltip } from './components/Tooltip/DefinitionTooltip.js';
159
163
  export { Tooltip } from './components/Tooltip/Tooltip.js';
160
164
  import './components/Text/index.js';
@@ -221,9 +225,6 @@ export { default as TableToolbarSearch } from './components/DataTable/TableToolb
221
225
  export { default as TableToolbarMenu } from './components/DataTable/TableToolbarMenu.js';
222
226
  export { default as FilterableMultiSelect } from './components/MultiSelect/FilterableMultiSelect.js';
223
227
  export { default as MultiSelect } from './components/MultiSelect/MultiSelect.js';
224
- export { default as Pagination } from './components/Pagination/Pagination.js';
225
228
  export { default as ControlledPasswordInput } from './components/TextInput/ControlledPasswordInput.js';
226
229
  export { default as PasswordInput } from './components/TextInput/PasswordInput.js';
227
- export { default as RadioTile } from './components/RadioTile/RadioTile.js';
228
230
  export { default as TreeNode } from './components/TreeView/TreeNode.js';
229
- export { Stack } from './components/Stack/Stack.js';
@@ -13,8 +13,11 @@ import window from 'window-or-global';
13
13
  import OptimizedResize from './OptimizedResize.js';
14
14
  import { selectorTabbable, selectorFocusable } from './keyboard/navigation.js';
15
15
  import { warning } from './warning.js';
16
- import wrapFocus from './wrapFocus.js';
16
+ import wrapFocus, { wrapFocusWithoutSentinels } from './wrapFocus.js';
17
17
  import { PrefixContext } from './usePrefix.js';
18
+ import * as FeatureFlags from '@carbon/feature-flags';
19
+ import { match } from './keyboard/match.js';
20
+ import { Tab } from './keyboard/keys.js';
18
21
 
19
22
  /**
20
23
  * The structure for the position of floating menu.
@@ -348,6 +351,19 @@ class FloatingMenu extends React__default.Component {
348
351
  });
349
352
  }
350
353
  });
354
+ /**
355
+ * Keydown handler for when focus wrap behavior is enabled
356
+ * @param {Event} event
357
+ */
358
+ _defineProperty(this, "handleKeyDown", event => {
359
+ if (match(event, Tab) && this._menuBody) {
360
+ wrapFocusWithoutSentinels({
361
+ containerNode: this._menuBody,
362
+ currentActiveNode: event.target,
363
+ event
364
+ });
365
+ }
366
+ });
351
367
  }
352
368
  componentWillUnmount() {
353
369
  this.hResize.release();
@@ -376,19 +392,24 @@ class FloatingMenu extends React__default.Component {
376
392
  const {
377
393
  context: prefix
378
394
  } = this;
395
+ const focusTrapWithoutSentinels = FeatureFlags.enabled('enable-experimental-focus-wrap-without-sentinels');
379
396
  if (typeof document !== 'undefined') {
380
397
  const {
381
398
  focusTrap,
382
399
  target
383
400
  } = this.props;
384
- return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React__default.createElement("div", {
385
- onBlur: focusTrap ? this.handleBlur : null
386
- }, /*#__PURE__*/React__default.createElement("span", {
401
+ return /*#__PURE__*/ReactDOM.createPortal(
402
+ /*#__PURE__*/
403
+ //eslint-disable-next-line jsx-a11y/no-static-element-interactions
404
+ React__default.createElement("div", {
405
+ onBlur: focusTrap && !focusTrapWithoutSentinels ? this.handleBlur : () => {},
406
+ onKeyDown: focusTrapWithoutSentinels ? this.handleKeyDown : () => {}
407
+ }, !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
387
408
  ref: this.startSentinel,
388
409
  tabIndex: "0",
389
410
  role: "link",
390
411
  className: `${prefix}--visually-hidden`
391
- }, "Focus sentinel"), this._getChildrenWithProps(), /*#__PURE__*/React__default.createElement("span", {
412
+ }, "Focus sentinel"), this._getChildrenWithProps(), !focusTrapWithoutSentinels && /*#__PURE__*/React__default.createElement("span", {
392
413
  ref: this.endSentinel,
393
414
  tabIndex: "0",
394
415
  role: "link",
@@ -10,6 +10,10 @@
10
10
  *
11
11
  * @see https://github.com/facebook/fbjs/blob/4d1751311d3f67af2dcce2e40df8512a23c7b9c6/packages/fbjs/src/core/ExecutionEnvironment.js#L12
12
12
  */
13
- const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
13
+ const canUseDOM = !!(typeof window !== 'undefined' &&
14
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
15
+ window.document &&
16
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
17
+ window.document.createElement);
14
18
 
15
19
  export { canUseDOM };
@@ -39,7 +39,9 @@ const getNextIndex = (key, index, arrayLength) => {
39
39
  */
40
40
  const DOCUMENT_POSITION_BROAD_PRECEDING =
41
41
  // Checks `typeof Node` for `react-docgen`
42
- typeof Node !== 'undefined' && Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINS;
42
+ typeof Node !== 'undefined' &&
43
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
44
+ Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINS;
43
45
 
44
46
  /**
45
47
  * A flag `node.compareDocumentPosition(target)` returns,
@@ -47,7 +49,9 @@ typeof Node !== 'undefined' && Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_
47
49
  */
48
50
  const DOCUMENT_POSITION_BROAD_FOLLOWING =
49
51
  // Checks `typeof Node` for `react-docgen`
50
- typeof Node !== 'undefined' && Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINED_BY;
52
+ typeof Node !== 'undefined' &&
53
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
54
+ Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINED_BY;
51
55
 
52
56
  /**
53
57
  * CSS selector that selects major nodes that are sequential-focusable.
@@ -0,0 +1,31 @@
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 { useRef, useEffect } from 'react';
9
+ import { useEvent } from './useEvent.js';
10
+ import { canUseDOM } from './environment.js';
11
+
12
+ function useOutsideClick(ref, callback) {
13
+ const savedCallback = useRef(callback);
14
+ useEffect(() => {
15
+ savedCallback.current = callback;
16
+ });
17
+
18
+ // We conditionally guard the `useEvent` hook for SSR. `canUseDOM` can be
19
+ // treated as a constant as it will be false when executed in a Node.js
20
+ // environment and true when executed in the browser
21
+ if (canUseDOM) {
22
+ // eslint-disable-next-line react-hooks/rules-of-hooks
23
+ useEvent(window, 'click', event => {
24
+ if (ref.current && !ref.current.contains(event.target)) {
25
+ savedCallback.current(event);
26
+ }
27
+ });
28
+ }
29
+ }
30
+
31
+ export { useOutsideClick };
@@ -6,7 +6,9 @@
6
6
  */
7
7
 
8
8
  import findLast from 'lodash.findlast';
9
+ import { useEffect } from 'react';
9
10
  import { DOCUMENT_POSITION_BROAD_PRECEDING, selectorTabbable, DOCUMENT_POSITION_BROAD_FOLLOWING } from './keyboard/navigation.js';
11
+ import { tabbable } from 'tabbable';
10
12
 
11
13
  /**
12
14
  * @param {Node} node A DOM node.
@@ -60,4 +62,52 @@ function wrapFocus(_ref) {
60
62
  }
61
63
  }
62
64
 
63
- export { wrapFocus as default, elementOrParentIsFloatingMenu };
65
+ /**
66
+ * Ensures the focus is kept in the given `containerNode`, implementing "focus-wrap" behavior.
67
+ * Note: This must be called *before* focus moves using onKeyDown or similar.
68
+ * @param {object} options The options.
69
+ * @param {Node|null} options.containerNode
70
+ * @param {EventTarget} options.currentActiveNode The DOM node that has focus.
71
+ * @param {KeyboardEvent} options.event The DOM event
72
+ */
73
+ function wrapFocusWithoutSentinels(_ref2) {
74
+ let {
75
+ containerNode,
76
+ currentActiveNode,
77
+ event
78
+ } = _ref2;
79
+ if (['blur', 'focusout', 'focusin', 'focus'].includes(event.type) && process.env.NODE_ENV !== "production") {
80
+ // eslint-disable-next-line react-hooks/rules-of-hooks
81
+ useEffect(() => {
82
+ throw new Error(`Error: wrapFocusWithoutSentinels(...) called in unsupported ${event.type} event.\n\nCall wrapFocusWithoutSentinels(...) from onKeyDown instead.`);
83
+ });
84
+ }
85
+
86
+ // The reason we're using tabbable is because it returns the tabbable
87
+ // items *in tab order*, whereas using our `selectorTabbable` only
88
+ // returns in DOM order
89
+ const tabbables = tabbable(containerNode);
90
+ const firstTabbable = tabbables[0];
91
+ const lastTabbable = tabbables[tabbables.length - 1];
92
+
93
+ // console.log(`---------------------------------`);
94
+ // console.log(containerNode);
95
+ // console.log(tabbables);
96
+ // console.log(firstTabbable);
97
+ // console.log(lastTabbable);
98
+ // console.log(currentActiveNode);
99
+
100
+ // The shift key is used to determine if focus is moving forwards or backwards
101
+ if (currentActiveNode === lastTabbable && !event.shiftKey) {
102
+ // Cancel the current movement of focus because we're going to place it ourselves
103
+ event.preventDefault();
104
+ firstTabbable.focus();
105
+ }
106
+ if (currentActiveNode === firstTabbable && event.shiftKey) {
107
+ // Cancel the current movement of focus because we're going to place it ourselves
108
+ event.preventDefault();
109
+ lastTabbable.focus();
110
+ }
111
+ }
112
+
113
+ export { wrapFocus as default, elementOrParentIsFloatingMenu, wrapFocusWithoutSentinels };
@@ -0,0 +1,40 @@
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
+ /**
9
+ * Create an adapter that converts an object of props with potentially deprecated
10
+ * prop names to the replacement prop names in a newer version. Useful for guarding
11
+ * against breaking changes when a prop has been renamed
12
+ *
13
+ * @param {Array} spec - an array of options which specify a text or regex
14
+ * matcher alongside a replacement if there is a match
15
+ * @returns {Function}
16
+ */
17
+ function mapPopoverAlignProp(align) {
18
+ switch (align) {
19
+ case 'top-left':
20
+ return 'top-start';
21
+ case 'top-right':
22
+ return 'top-end';
23
+ case 'bottom-left':
24
+ return 'bottom-start';
25
+ case 'bottom-right':
26
+ return 'bottom-end';
27
+ case 'left-bottom':
28
+ return 'left-end';
29
+ case 'left-top':
30
+ return 'left-start';
31
+ case 'right-bottom':
32
+ return 'right-end';
33
+ case 'right-top':
34
+ return 'right-start';
35
+ default:
36
+ return align;
37
+ }
38
+ }
39
+
40
+ export { mapPopoverAlignProp };
@@ -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
  */