@carbon/react 1.34.1 → 1.35.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 (39) hide show
  1. package/es/components/ComposedModal/ComposedModal.d.ts +5 -1
  2. package/es/components/ComposedModal/ComposedModal.js +15 -0
  3. package/es/components/DataTable/DataTable.d.ts +27 -24
  4. package/es/components/DataTableSkeleton/DataTableSkeleton.d.ts +4 -62
  5. package/es/components/DataTableSkeleton/DataTableSkeleton.js +9 -17
  6. package/es/components/Modal/Modal.js +14 -0
  7. package/es/components/MultiSelect/FilterableMultiSelect.js +4 -9
  8. package/es/components/Select/Select.js +9 -1
  9. package/es/components/Tabs/Tabs.d.ts +3 -3
  10. package/es/components/Tabs/Tabs.js +2 -2
  11. package/es/components/Tile/Tile.js +11 -8
  12. package/es/components/Tooltip/Tooltip.js +1 -1
  13. package/es/components/UIShell/HeaderMenu.js +22 -3
  14. package/es/components/UIShell/SideNav.d.ts +6 -1
  15. package/es/components/UIShell/SideNav.js +27 -23
  16. package/es/components/UIShell/SideNavLink.js +17 -3
  17. package/es/components/UIShell/SideNavMenu.js +10 -2
  18. package/es/components/UIShell/_utils.js +1 -1
  19. package/es/internal/useNoInteractiveChildren.js +24 -1
  20. package/lib/components/ComposedModal/ComposedModal.d.ts +5 -1
  21. package/lib/components/ComposedModal/ComposedModal.js +15 -0
  22. package/lib/components/DataTable/DataTable.d.ts +27 -24
  23. package/lib/components/DataTableSkeleton/DataTableSkeleton.d.ts +4 -62
  24. package/lib/components/DataTableSkeleton/DataTableSkeleton.js +9 -17
  25. package/lib/components/Modal/Modal.js +14 -0
  26. package/lib/components/MultiSelect/FilterableMultiSelect.js +4 -9
  27. package/lib/components/Select/Select.js +9 -1
  28. package/lib/components/Tabs/Tabs.d.ts +3 -3
  29. package/lib/components/Tabs/Tabs.js +2 -2
  30. package/lib/components/Tile/Tile.js +10 -7
  31. package/lib/components/Tooltip/Tooltip.js +1 -1
  32. package/lib/components/UIShell/HeaderMenu.js +22 -3
  33. package/lib/components/UIShell/SideNav.d.ts +6 -1
  34. package/lib/components/UIShell/SideNav.js +26 -21
  35. package/lib/components/UIShell/SideNavLink.js +16 -2
  36. package/lib/components/UIShell/SideNavMenu.js +9 -1
  37. package/lib/components/UIShell/_utils.js +1 -1
  38. package/lib/internal/useNoInteractiveChildren.js +24 -0
  39. package/package.json +19 -18
@@ -1,4 +1,4 @@
1
- import React, { type MouseEvent, type KeyboardEvent, type HTMLAttributes, type ReactNode } from 'react';
1
+ import React, { type MouseEvent, type KeyboardEvent, type HTMLAttributes, type ReactNode, type RefObject } from 'react';
2
2
  export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
3
3
  /** Specify the content to be placed in the ModalBody. */
4
4
  children?: ReactNode;
@@ -43,6 +43,10 @@ export interface ComposedModalProps extends HTMLAttributes<HTMLDivElement> {
43
43
  * Specify whether the Modal content should have any inner padding.
44
44
  */
45
45
  isFullWidth?: boolean;
46
+ /**
47
+ * Provide a ref to return focus to once the modal is closed.
48
+ */
49
+ launcherButtonRef?: RefObject<HTMLButtonElement>;
46
50
  /**
47
51
  * Specify an optional handler for closing modal.
48
52
  * Returning `false` here prevents closing modal.
@@ -81,6 +81,7 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
81
81
  selectorPrimaryFocus,
82
82
  selectorsFloatingMenus,
83
83
  size,
84
+ launcherButtonRef,
84
85
  ...rest
85
86
  } = _ref2;
86
87
  const prefix = usePrefix();
@@ -176,6 +177,13 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
176
177
  return child;
177
178
  }
178
179
  });
180
+ useEffect(() => {
181
+ if (!open && launcherButtonRef) {
182
+ setTimeout(() => {
183
+ launcherButtonRef?.current?.focus();
184
+ });
185
+ }
186
+ }, [open, launcherButtonRef]);
179
187
  useEffect(() => {
180
188
  const initialFocus = focusContainerElement => {
181
189
  const containerElement = focusContainerElement || innerModal.current;
@@ -252,6 +260,13 @@ ComposedModal.propTypes = {
252
260
  * Specify whether the Modal content should have any inner padding.
253
261
  */
254
262
  isFullWidth: PropTypes.bool,
263
+ /**
264
+ * Provide a ref to return focus to once the modal is closed.
265
+ */
266
+ // @ts-expect-error: Invalid derived type
267
+ launcherButtonRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
268
+ current: PropTypes.any
269
+ })]),
255
270
  /**
256
271
  * Specify an optional handler for closing modal.
257
272
  * Returning `false` here prevents closing modal.
@@ -46,9 +46,9 @@ declare const dataTableDefaultProps: {
46
46
  translateWithId: (id: any) => string;
47
47
  };
48
48
  export type DataTableSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
49
- export interface DataTableCell {
49
+ export interface DataTableCell<T> {
50
50
  id: string;
51
- value: unknown;
51
+ value: T;
52
52
  isEditable: boolean;
53
53
  isEditing: boolean;
54
54
  isValid: boolean;
@@ -57,9 +57,12 @@ export interface DataTableCell {
57
57
  header: string;
58
58
  };
59
59
  }
60
- export interface DataTableRow {
60
+ type DataTableCells<T extends any[]> = {
61
+ [K in keyof T]: DataTableCell<T[K]>;
62
+ };
63
+ export interface DataTableRow<ColTypes extends any[]> {
61
64
  id: string;
62
- cells: Array<DataTableCell>;
65
+ cells: DataTableCells<ColTypes>;
63
66
  disabled?: boolean;
64
67
  isExpanded?: boolean;
65
68
  isSelected?: boolean;
@@ -68,14 +71,14 @@ export interface DataTableHeader {
68
71
  key: string;
69
72
  header: React.ReactNode;
70
73
  }
71
- export interface DataTableRenderProps {
74
+ export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
72
75
  headers: Array<DataTableHeader>;
73
- rows: Array<DataTableRow>;
74
- selectedRows: Array<DataTableRow>;
76
+ rows: Array<DataTableRow<ColTypes> & RowType>;
77
+ selectedRows: Array<DataTableRow<ColTypes> & RowType>;
75
78
  getHeaderProps: (getHeaderPropsArgs: {
76
79
  header: DataTableHeader;
77
80
  isSortable?: boolean;
78
- onClick?: (e: MouseEvent, sortState: {
81
+ onClick?: (e: React.MouseEvent, sortState: {
79
82
  sortHeaderKey: string;
80
83
  sortDirection: DataTableSortState;
81
84
  }) => void;
@@ -102,7 +105,7 @@ export interface DataTableRenderProps {
102
105
  };
103
106
  getRowProps: (getRowPropsArgs: {
104
107
  onClick?: (e: MouseEvent) => void;
105
- row: DataTableRow;
108
+ row: DataTableRow<ColTypes>;
106
109
  [key: string]: unknown;
107
110
  }) => {
108
111
  ariaLabel: string;
@@ -115,7 +118,7 @@ export interface DataTableRenderProps {
115
118
  };
116
119
  getSelectionProps: (getSelectionPropsArgs: {
117
120
  onClick?: (e: MouseEvent) => void;
118
- row: DataTableRow;
121
+ row: DataTableRow<ColTypes>;
119
122
  [key: string]: unknown;
120
123
  }) => {
121
124
  ariaLabel: string;
@@ -155,7 +158,7 @@ export interface DataTableRenderProps {
155
158
  stickyHeader?: boolean;
156
159
  useStaticWidth?: boolean;
157
160
  };
158
- onInputChange: (e: Event, defaultValue?: string) => void;
161
+ onInputChange: (e: React.ChangeEvent<HTMLInputElement>, defaultValue?: string) => void;
159
162
  sortBy: (headerKey: string) => void;
160
163
  selectAll: () => void;
161
164
  selectRow: (rowId: string) => void;
@@ -163,11 +166,11 @@ export interface DataTableRenderProps {
163
166
  expandAll: () => void;
164
167
  radio: boolean | undefined;
165
168
  }
166
- export interface DataTableProps {
167
- children?: (renderProps: DataTableRenderProps) => React.ReactElement;
169
+ export interface DataTableProps<RowType, ColTypes extends any[]> {
170
+ children?: (renderProps: DataTableRenderProps<RowType, ColTypes>) => React.ReactElement;
168
171
  experimentalAutoAlign?: boolean;
169
172
  filterRows?: (filterRowsArgs: {
170
- cellsById: Record<string, DataTableCell>;
173
+ cellsById: Record<string, DataTableCell<RowType>>;
171
174
  getCellId: (rowId: string, header: string) => string;
172
175
  headers: Array<DataTableHeader>;
173
176
  inputValue: string;
@@ -178,10 +181,10 @@ export interface DataTableProps {
178
181
  locale?: string;
179
182
  overflowMenuOnHover?: boolean;
180
183
  radio?: boolean;
181
- render?: (renderProps: DataTableRenderProps) => React.ReactElement;
182
- rows: Array<Omit<DataTableRow, 'cells'>>;
184
+ render?: (renderProps: DataTableRenderProps<RowType, ColTypes>) => React.ReactElement;
185
+ rows: Array<Omit<DataTableRow<ColTypes>, 'cells'>>;
183
186
  size?: DataTableSize;
184
- sortRow?: (cellA: DataTableCell, cellB: DataTableCell, sortRowOptions: {
187
+ sortRow?: (cellA: DataTableCell<any>, cellB: DataTableCell<any>, sortRowOptions: {
185
188
  sortDirection: DataTableSortState;
186
189
  sortStates: Record<DataTableSortState, DataTableSortState>;
187
190
  locale: string;
@@ -191,13 +194,13 @@ export interface DataTableProps {
191
194
  useStaticWidth?: boolean;
192
195
  useZebraStyles?: boolean;
193
196
  }
194
- interface DataTableState {
195
- cellsById: Record<string, DataTableCell>;
197
+ interface DataTableState<ColTypes extends any[]> {
198
+ cellsById: Record<string, DataTableCell<ColTypes>>;
196
199
  filterInputValue: string | null;
197
200
  initialRowOrder: Array<string>;
198
201
  isExpandedAll: boolean;
199
202
  rowIds: Array<string>;
200
- rowsById: Record<string, DataTableRow>;
203
+ rowsById: Record<string, DataTableRow<ColTypes>>;
201
204
  shouldShowBatchActions: boolean;
202
205
  sortDirection: DataTableSortState;
203
206
  sortHeaderKey: string | null;
@@ -212,7 +215,7 @@ interface DataTableState {
212
215
  * and updating the state of the single entity will cascade updates to the
213
216
  * consumer.
214
217
  */
215
- declare class DataTable extends React.Component<DataTableProps & typeof dataTableDefaultProps, DataTableState> {
218
+ declare class DataTable<RowType, ColTypes extends any[]> extends React.Component<DataTableProps<RowType, ColTypes> & typeof dataTableDefaultProps, DataTableState<ColTypes>> {
216
219
  instanceId: number;
217
220
  static defaultProps: {
218
221
  filterRows: ({ rowIds, headers, cellsById, inputValue, getCellId, }: {
@@ -344,7 +347,7 @@ declare class DataTable extends React.Component<DataTableProps & typeof dataTabl
344
347
  getHeaderProps: ({ header, onClick, isSortable, ...rest }: {
345
348
  [key: string]: unknown;
346
349
  header: DataTableHeader;
347
- onClick?: ((e: MouseEvent, sortState: {
350
+ onClick?: ((e: React.MouseEvent, sortState: {
348
351
  sortHeaderKey: string;
349
352
  sortDirection: DataTableSortState;
350
353
  }) => void) | undefined;
@@ -402,7 +405,7 @@ declare class DataTable extends React.Component<DataTableProps & typeof dataTabl
402
405
  getRowProps: ({ row, onClick, ...rest }: {
403
406
  [key: string]: unknown;
404
407
  onClick?: ((e: MouseEvent) => void) | undefined;
405
- row: DataTableRow;
408
+ row: DataTableRow<ColTypes>;
406
409
  }) => {
407
410
  key: string;
408
411
  onExpand: any;
@@ -424,7 +427,7 @@ declare class DataTable extends React.Component<DataTableProps & typeof dataTabl
424
427
  getSelectionProps: ({ onClick, row, ...rest }?: {
425
428
  [key: string]: unknown;
426
429
  onClick?: ((e: MouseEvent) => void) | undefined;
427
- row: DataTableRow;
430
+ row: DataTableRow<ColTypes>;
428
431
  }) => {
429
432
  checked: boolean | undefined;
430
433
  onSelect: any;
@@ -4,13 +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 PropTypes from 'prop-types';
8
- import { TableHTMLAttributes } from 'react';
7
+ import React, { type FunctionComponent, TableHTMLAttributes } from 'react';
9
8
  export interface DataTableSkeletonHeader {
10
9
  /**
11
- * Optionally specify header label
10
+ * Specify header label
12
11
  */
13
- header?: string;
12
+ header: React.ReactNode;
14
13
  /**
15
14
  * Optionally specify header key
16
15
  */
@@ -47,62 +46,5 @@ export interface DataTableSkeletonProps extends TableHTMLAttributes<HTMLTableEle
47
46
  */
48
47
  zebra?: boolean;
49
48
  }
50
- declare const DataTableSkeleton: {
51
- ({ headers, rowCount, columnCount, zebra, compact, className, showHeader, showToolbar, ...rest }: {
52
- [x: string]: any;
53
- headers: any;
54
- rowCount: any;
55
- columnCount: any;
56
- zebra: any;
57
- compact: any;
58
- className: any;
59
- showHeader: any;
60
- showToolbar: any;
61
- }): JSX.Element;
62
- propTypes: {
63
- /**
64
- * Specify an optional className to add.
65
- */
66
- className: PropTypes.Requireable<string>;
67
- /**
68
- * Specify the number of columns that you want to render in the skeleton state
69
- */
70
- columnCount: PropTypes.Requireable<number>;
71
- /**
72
- * Optionally specify whether you want the Skeleton to be rendered as a
73
- * compact DataTable
74
- */
75
- compact: PropTypes.Requireable<boolean>;
76
- /**
77
- * Optionally specify the displayed headers
78
- */
79
- headers: PropTypes.Requireable<NonNullable<any[] | PropTypes.InferProps<{
80
- key: PropTypes.Requireable<string>;
81
- }> | null | undefined>>;
82
- /**
83
- * Specify the number of rows that you want to render in the skeleton state
84
- */
85
- rowCount: PropTypes.Requireable<number>;
86
- /**
87
- * Specify if the table header should be rendered as part of the skeleton.
88
- */
89
- showHeader: PropTypes.Requireable<boolean>;
90
- /**
91
- * Specify if the table toolbar should be rendered as part of the skeleton.
92
- */
93
- showToolbar: PropTypes.Requireable<boolean>;
94
- /**
95
- * Optionally specify whether you want the DataTable to be zebra striped
96
- */
97
- zebra: PropTypes.Requireable<boolean>;
98
- };
99
- defaultProps: {
100
- rowCount: number;
101
- columnCount: number;
102
- zebra: boolean;
103
- compact: boolean;
104
- showHeader: boolean;
105
- showToolbar: boolean;
106
- };
107
- };
49
+ declare const DataTableSkeleton: FunctionComponent<DataTableSkeletonProps>;
108
50
  export default DataTableSkeleton;
@@ -15,13 +15,13 @@ var _span, _span2;
15
15
  const DataTableSkeleton = _ref => {
16
16
  let {
17
17
  headers,
18
- rowCount,
19
- columnCount,
20
- zebra,
21
- compact,
18
+ rowCount = 5,
19
+ columnCount = 5,
20
+ zebra = false,
21
+ compact = false,
22
22
  className,
23
- showHeader,
24
- showToolbar,
23
+ showHeader = true,
24
+ showToolbar = true,
25
25
  ...rest
26
26
  } = _ref;
27
27
  const prefix = usePrefix();
@@ -83,9 +83,9 @@ DataTableSkeleton.propTypes = {
83
83
  /**
84
84
  * Optionally specify the displayed headers
85
85
  */
86
- headers: PropTypes.oneOfType([PropTypes.array, PropTypes.shape({
87
- key: PropTypes.string
88
- })]),
86
+ headers: PropTypes.arrayOf(PropTypes.shape({
87
+ header: PropTypes.node.isRequired
88
+ }).isRequired),
89
89
  /**
90
90
  * Specify the number of rows that you want to render in the skeleton state
91
91
  */
@@ -103,13 +103,5 @@ DataTableSkeleton.propTypes = {
103
103
  */
104
104
  zebra: PropTypes.bool
105
105
  };
106
- DataTableSkeleton.defaultProps = {
107
- rowCount: 5,
108
- columnCount: 5,
109
- zebra: false,
110
- compact: false,
111
- showHeader: true,
112
- showToolbar: true
113
- };
114
106
 
115
107
  export { DataTableSkeleton as default };
@@ -53,6 +53,7 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
53
53
  preventCloseOnClickOutside,
54
54
  // eslint-disable-line
55
55
  isFullWidth,
56
+ launcherButtonRef,
56
57
  ...rest
57
58
  } = _ref;
58
59
  const prefix = usePrefix();
@@ -150,6 +151,13 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
150
151
  useEffect(() => {
151
152
  toggleClass(document.body, `${prefix}--body--with-modal-open`, open);
152
153
  }, [open, prefix]);
154
+ useEffect(() => {
155
+ if (!open && launcherButtonRef) {
156
+ setTimeout(() => {
157
+ launcherButtonRef?.current?.focus();
158
+ });
159
+ }
160
+ }, [open, launcherButtonRef]);
153
161
  useEffect(() => {
154
162
  const initialFocus = focusContainerElement => {
155
163
  const containerElement = focusContainerElement || innerModal.current;
@@ -282,6 +290,12 @@ Modal.propTypes = {
282
290
  * Specify whether or not the Modal content should have any inner padding.
283
291
  */
284
292
  isFullWidth: PropTypes.bool,
293
+ /**
294
+ * Provide a ref to return focus to once the modal is closed.
295
+ */
296
+ launcherButtonRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
297
+ current: PropTypes.any
298
+ })]),
285
299
  /**
286
300
  * Specify a label to be read by screen readers on the modal root node
287
301
  */
@@ -32,8 +32,6 @@ import { Space, Enter, Delete, Escape, Tab, Home, End } from '../../internal/key
32
32
 
33
33
  const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function FilterableMultiSelect(_ref, ref) {
34
34
  let {
35
- ['aria-label']: ariaLabel,
36
- ariaLabel: deprecatedAriaLabel,
37
35
  className: containerClassName,
38
36
  compareItems,
39
37
  direction,
@@ -312,9 +310,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
312
310
  setInputValue('');
313
311
  }
314
312
  });
315
- const menuProps = getMenuProps({
316
- 'aria-label': ariaLabel
317
- }, {
313
+ const menuProps = getMenuProps({}, {
318
314
  suppressRefError: true
319
315
  });
320
316
  const handleFocus = evt => {
@@ -329,7 +325,6 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
329
325
  }, titleText ? /*#__PURE__*/React__default.createElement("label", _extends({
330
326
  className: titleClasses
331
327
  }, labelProps), titleText) : null, /*#__PURE__*/React__default.createElement(ListBox, {
332
- "aria-label": deprecatedAriaLabel || ariaLabel,
333
328
  onFocus: isFluid ? handleFocus : null,
334
329
  onBlur: isFluid ? handleFocus : null,
335
330
  className: className,
@@ -419,14 +414,15 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
419
414
  });
420
415
  FilterableMultiSelect.propTypes = {
421
416
  /**
417
+ * Deprecated, aria-label is no longer needed
422
418
  * Specify a label to be read by screen readers on the container node
423
419
  */
424
- ['aria-label']: PropTypes.string,
420
+ ['aria-label']: deprecate(PropTypes.string, 'ariaLabel / aria-label props are no longer required for FilterableMultiSelect'),
425
421
  /**
426
422
  * Deprecated, please use `aria-label` instead.
427
423
  * Specify a label to be read by screen readers on the container note.
428
424
  */
429
- ariaLabel: deprecate(PropTypes.string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
425
+ ariaLabel: deprecate(PropTypes.string, 'ariaLabel / aria-label props are no longer required for FilterableMultiSelect'),
430
426
  /**
431
427
  * Specify the direction of the multiselect dropdown. Can be either top or bottom.
432
428
  */
@@ -539,7 +535,6 @@ FilterableMultiSelect.propTypes = {
539
535
  warnText: PropTypes.node
540
536
  };
541
537
  FilterableMultiSelect.defaultProps = {
542
- ['aria-label']: 'Choose an item',
543
538
  compareItems: defaultCompareItems,
544
539
  direction: 'bottom',
545
540
  disabled: false,
@@ -15,6 +15,7 @@ import { usePrefix } from '../../internal/usePrefix.js';
15
15
  import '../FluidForm/FluidForm.js';
16
16
  import { FormContext } from '../FluidForm/FormContext.js';
17
17
  import setupGetInstanceId from '../../tools/setupGetInstanceId.js';
18
+ import { composeEventHandlers } from '../../tools/events.js';
18
19
 
19
20
  const getInstanceId = setupGetInstanceId();
20
21
  const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref) {
@@ -37,6 +38,7 @@ const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref)
37
38
  size,
38
39
  warn = false,
39
40
  warnText,
41
+ onChange,
40
42
  ...other
41
43
  } = _ref;
42
44
  const prefix = usePrefix();
@@ -44,6 +46,7 @@ const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref)
44
46
  isFluid
45
47
  } = useContext(FormContext);
46
48
  const [isFocused, setIsFocused] = useState(false);
49
+ const [title, setTitle] = useState('');
47
50
  const {
48
51
  current: selectInstanceId
49
52
  } = useRef(getInstanceId());
@@ -96,6 +99,9 @@ const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref)
96
99
  const handleFocus = evt => {
97
100
  setIsFocused(evt.type === 'focus' ? true : false);
98
101
  };
102
+ const handleChange = evt => {
103
+ setTitle(evt?.target?.value);
104
+ };
99
105
  const readOnlyEventHandlers = {
100
106
  onMouseDown: evt => {
101
107
  // NOTE: does not prevent click
@@ -119,7 +125,9 @@ const Select = /*#__PURE__*/React__default.forwardRef(function Select(_ref, ref)
119
125
  className: inputClasses,
120
126
  disabled: disabled || undefined,
121
127
  "aria-invalid": invalid || undefined,
122
- "aria-readonly": readOnly || undefined
128
+ "aria-readonly": readOnly || undefined,
129
+ title: title,
130
+ onChange: composeEventHandlers([onChange, handleChange])
123
131
  }, readOnlyEventHandlers, {
124
132
  ref: ref
125
133
  }), children), /*#__PURE__*/React__default.createElement(ChevronDown, {
@@ -115,7 +115,7 @@ export interface TabListProps extends DivAttributes {
115
115
  /**
116
116
  * Provide the props that describe the left overflow button
117
117
  */
118
- leftOverflowButtonProps: HTMLAttributes<HTMLButtonElement>;
118
+ leftOverflowButtonProps?: HTMLAttributes<HTMLButtonElement>;
119
119
  /**
120
120
  * Specify whether to use the light component variant
121
121
  */
@@ -123,7 +123,7 @@ export interface TabListProps extends DivAttributes {
123
123
  /**
124
124
  * Provide the props that describe the right overflow button
125
125
  */
126
- rightOverflowButtonProps: HTMLAttributes<HTMLButtonElement>;
126
+ rightOverflowButtonProps?: HTMLAttributes<HTMLButtonElement>;
127
127
  /**
128
128
  * Optionally provide a delay (in milliseconds) passed to the lodash
129
129
  * debounce of the onScroll handler. This will impact the responsiveness
@@ -299,7 +299,7 @@ export interface TabPanelsProps {
299
299
  */
300
300
  children?: ReactNode;
301
301
  }
302
- declare function TabPanels({ children }: TabPanelsProps): JSX.Element[] | null | undefined;
302
+ declare function TabPanels({ children }: TabPanelsProps): JSX.Element;
303
303
  declare namespace TabPanels {
304
304
  var propTypes: {
305
305
  /**
@@ -791,11 +791,11 @@ function TabPanels(_ref8) {
791
791
  let {
792
792
  children
793
793
  } = _ref8;
794
- return React__default.Children.map(children, (child, index) => {
794
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, React__default.Children.map(children, (child, index) => {
795
795
  return /*#__PURE__*/React__default.createElement(TabPanelContext.Provider, {
796
796
  value: index
797
797
  }, child);
798
- });
798
+ }));
799
799
  }
800
800
  TabPanels.propTypes = {
801
801
  /**
@@ -15,9 +15,10 @@ import deprecate from '../../prop-types/deprecate.js';
15
15
  import { composeEventHandlers } from '../../tools/events.js';
16
16
  import { usePrefix } from '../../internal/usePrefix.js';
17
17
  import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
18
- import { getInteractiveContent } from '../../internal/useNoInteractiveChildren.js';
18
+ import { getInteractiveContent, getRoleContent } from '../../internal/useNoInteractiveChildren.js';
19
19
  import { useMergedRefs } from '../../internal/useMergedRefs.js';
20
20
  import { useFeatureFlag } from '../FeatureFlags/index.js';
21
+ import { useId } from '../../internal/useId.js';
21
22
  import { matches } from '../../internal/keyboard/match.js';
22
23
  import { Enter, Space } from '../../internal/keyboard/keys.js';
23
24
 
@@ -375,10 +376,10 @@ const ExpandableTile = /*#__PURE__*/React__default.forwardRef(function Expandabl
375
376
  if (!aboveTheFold.current || !belowTheFold.current) {
376
377
  return;
377
378
  }
378
- if (!getInteractiveContent(belowTheFold.current)) {
379
- setInteractive(false);
380
- return;
381
- } else if (!getInteractiveContent(aboveTheFold.current)) {
379
+
380
+ // Interactive elements or elements that are given a role should be treated
381
+ // the same because elements with a role can not be rendered inside a `button`
382
+ if (!getInteractiveContent(belowTheFold.current) && !getRoleContent(belowTheFold.current) && !getInteractiveContent(aboveTheFold.current) && !getRoleContent(aboveTheFold.current)) {
382
383
  setInteractive(false);
383
384
  }
384
385
  }, []);
@@ -403,11 +404,11 @@ const ExpandableTile = /*#__PURE__*/React__default.forwardRef(function Expandabl
403
404
  resizeObserver.observe(aboveTheFold.current);
404
405
  return () => resizeObserver.disconnect();
405
406
  }, []);
407
+ const belowTheFoldId = useId('expandable-tile-interactive');
406
408
  return interactive ? /*#__PURE__*/React__default.createElement("div", _extends({
407
409
  // @ts-expect-error: Needlesly strict & deep typing for the element type
408
410
  ref: ref,
409
- className: interactiveClassNames,
410
- "aria-expanded": isExpanded
411
+ className: interactiveClassNames
411
412
  }, rest), /*#__PURE__*/React__default.createElement("div", {
412
413
  ref: tileContent
413
414
  }, /*#__PURE__*/React__default.createElement("div", {
@@ -416,13 +417,15 @@ const ExpandableTile = /*#__PURE__*/React__default.forwardRef(function Expandabl
416
417
  }, childrenAsArray[0]), /*#__PURE__*/React__default.createElement("button", {
417
418
  type: "button",
418
419
  "aria-expanded": isExpanded,
420
+ "aria-controls": belowTheFoldId,
419
421
  onKeyUp: composeEventHandlers([onKeyUp, handleKeyUp]),
420
422
  onClick: composeEventHandlers([onClick, handleClick]),
421
423
  "aria-label": isExpanded ? tileExpandedIconText : tileCollapsedIconText,
422
424
  className: chevronInteractiveClassNames
423
425
  }, _ChevronDown || (_ChevronDown = /*#__PURE__*/React__default.createElement(ChevronDown, null))), /*#__PURE__*/React__default.createElement("div", {
424
426
  ref: belowTheFold,
425
- className: `${prefix}--tile-content`
427
+ className: `${prefix}--tile-content`,
428
+ id: belowTheFoldId
426
429
  }, childrenAsArray[1]))) : /*#__PURE__*/React__default.createElement("button", _extends({
427
430
  type: "button"
428
431
  // @ts-expect-error: Needlesly strict & deep typing for the element type
@@ -100,7 +100,7 @@ function Tooltip(_ref) {
100
100
  ...triggerProps,
101
101
  ...getChildEventHandlers(child.props)
102
102
  }) : null), /*#__PURE__*/React__default.createElement(PopoverContent, {
103
- "aria-hidden": "true",
103
+ "aria-hidden": open ? 'false' : 'true',
104
104
  className: `${prefix}--tooltip-content`,
105
105
  id: id,
106
106
  ref: tooltipRef,
@@ -13,6 +13,7 @@ import PropTypes from 'prop-types';
13
13
  import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
14
14
  import { PrefixContext } from '../../internal/usePrefix.js';
15
15
  import deprecate from '../../prop-types/deprecate.js';
16
+ import { composeEventHandlers } from '../../tools/events.js';
16
17
  import { matches } from '../../internal/keyboard/match.js';
17
18
  import { Enter, Space, Escape } from '../../internal/keyboard/keys.js';
18
19
 
@@ -142,6 +143,9 @@ class HeaderMenu extends React__default.Component {
142
143
  menuLinkName,
143
144
  focusRef,
144
145
  // eslint-disable-line no-unused-vars
146
+ onBlur,
147
+ onClick,
148
+ onKeyDown,
145
149
  ...rest
146
150
  } = this.props;
147
151
  const hasActiveChildren = React__default.Children.toArray(children).some(child => child.props.isActive || child.props.isCurrentPage);
@@ -171,9 +175,9 @@ class HeaderMenu extends React__default.Component {
171
175
  // - href can be set to javascript:void(0), ideally this will be a button
172
176
  return /*#__PURE__*/React__default.createElement("li", _extends({}, rest, {
173
177
  className: itemClassName,
174
- onKeyDown: this.handleMenuClose,
175
- onClick: this.handleOnClick,
176
- onBlur: this.handleOnBlur
178
+ onKeyDown: composeEventHandlers([onKeyDown, this.handleMenuClose]),
179
+ onClick: composeEventHandlers([onClick, this.handleOnClick]),
180
+ onBlur: composeEventHandlers([onBlur, this.handleOnBlur])
177
181
  }), /*#__PURE__*/React__default.createElement("a", _extends({
178
182
  // eslint-disable-line jsx-a11y/role-supports-aria-props,jsx-a11y/anchor-is-valid
179
183
  "aria-haspopup": "menu" // eslint-disable-line jsx-a11y/aria-proptypes
@@ -218,6 +222,21 @@ _defineProperty(HeaderMenu, "propTypes", {
218
222
  * Provide a label for the link text
219
223
  */
220
224
  menuLinkName: PropTypes.string.isRequired,
225
+ /**
226
+ * Optionally provide an onBlur handler that is called when the underlying
227
+ * button fires it's onblur event
228
+ */
229
+ onBlur: PropTypes.func,
230
+ /**
231
+ * Optionally provide an onClick handler that is called when the underlying
232
+ * button fires it's onclick event
233
+ */
234
+ onClick: PropTypes.func,
235
+ /**
236
+ * Optionally provide an onKeyDown handler that is called when the underlying
237
+ * button fires it's onkeydown event
238
+ */
239
+ onKeyDown: PropTypes.func,
221
240
  /**
222
241
  * Optional component to render instead of string
223
242
  */