@carbon/react 1.34.1 → 1.35.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) 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/Tabs/Tabs.d.ts +3 -3
  9. package/es/components/Tabs/Tabs.js +2 -2
  10. package/es/components/Tile/Tile.js +11 -8
  11. package/es/components/Tooltip/Tooltip.js +1 -1
  12. package/es/components/UIShell/HeaderMenu.js +22 -3
  13. package/es/components/UIShell/SideNav.d.ts +6 -1
  14. package/es/components/UIShell/SideNav.js +27 -23
  15. package/es/components/UIShell/SideNavLink.js +17 -3
  16. package/es/components/UIShell/SideNavMenu.js +10 -2
  17. package/es/components/UIShell/_utils.js +1 -1
  18. package/es/internal/useNoInteractiveChildren.js +24 -1
  19. package/lib/components/ComposedModal/ComposedModal.d.ts +5 -1
  20. package/lib/components/ComposedModal/ComposedModal.js +15 -0
  21. package/lib/components/DataTable/DataTable.d.ts +27 -24
  22. package/lib/components/DataTableSkeleton/DataTableSkeleton.d.ts +4 -62
  23. package/lib/components/DataTableSkeleton/DataTableSkeleton.js +9 -17
  24. package/lib/components/Modal/Modal.js +14 -0
  25. package/lib/components/MultiSelect/FilterableMultiSelect.js +4 -9
  26. package/lib/components/Tabs/Tabs.d.ts +3 -3
  27. package/lib/components/Tabs/Tabs.js +2 -2
  28. package/lib/components/Tile/Tile.js +10 -7
  29. package/lib/components/Tooltip/Tooltip.js +1 -1
  30. package/lib/components/UIShell/HeaderMenu.js +22 -3
  31. package/lib/components/UIShell/SideNav.d.ts +6 -1
  32. package/lib/components/UIShell/SideNav.js +26 -21
  33. package/lib/components/UIShell/SideNavLink.js +16 -2
  34. package/lib/components/UIShell/SideNavMenu.js +9 -1
  35. package/lib/components/UIShell/_utils.js +1 -1
  36. package/lib/internal/useNoInteractiveChildren.js +24 -0
  37. package/package.json +19 -18
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useRef, isValidElement } from 'react';
9
+ import React__default, { createContext, useRef, isValidElement } from 'react';
10
10
  import cx from 'classnames';
11
11
  import PropTypes from 'prop-types';
12
12
  import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
@@ -20,6 +20,7 @@ import { Tab, Escape } from '../../internal/keyboard/keys.js';
20
20
 
21
21
  // TO-DO: comment back in when footer is added for rails
22
22
  // import SideNavFooter from './SideNavFooter';
23
+ const SideNavContext = /*#__PURE__*/createContext({});
23
24
  function SideNavRenderFunction(_ref, ref) {
24
25
  let {
25
26
  expanded: expandedProp,
@@ -88,27 +89,25 @@ function SideNavRenderFunction(_ref, ref) {
88
89
  });
89
90
  let childrenToRender = children;
90
91
 
91
- // if a rail, pass the expansion state as a prop, so children can update themselves to match
92
- if (isRail) {
93
- childrenToRender = React__default.Children.map(children, child => {
94
- // if we are controlled, check for if we have hovered over or the expanded state, else just use the expanded state (uncontrolled)
95
- const currentExpansionState = controlled ? expandedViaHoverState || expanded : expanded;
96
- if ( /*#__PURE__*/isValidElement(child)) {
97
- const childJsxElement = child;
98
- // avoid spreading `isSideNavExpanded` to non-Carbon UI Shell children
99
- return /*#__PURE__*/React__default.cloneElement(childJsxElement, {
100
- ...(CARBON_SIDENAV_ITEMS.includes(childJsxElement.type?.displayName ?? childJsxElement.type?.name) ? {
101
- isSideNavExpanded: currentExpansionState
102
- } : {})
103
- });
104
- }
105
- return child;
106
- });
107
- }
92
+ // Pass the expansion state as a prop, so children can update themselves to match
93
+ childrenToRender = React__default.Children.map(children, child => {
94
+ // if we are controlled, check for if we have hovered over or the expanded state, else just use the expanded state (uncontrolled)
95
+ const currentExpansionState = controlled ? expandedViaHoverState || expanded : expanded;
96
+ if ( /*#__PURE__*/isValidElement(child)) {
97
+ const childJsxElement = child;
98
+ // avoid spreading `isSideNavExpanded` to non-Carbon UI Shell children
99
+ return /*#__PURE__*/React__default.cloneElement(childJsxElement, {
100
+ ...(CARBON_SIDENAV_ITEMS.includes(childJsxElement.type?.displayName ?? childJsxElement.type?.name) ? {
101
+ isSideNavExpanded: currentExpansionState
102
+ } : {})
103
+ });
104
+ }
105
+ return child;
106
+ });
108
107
  const eventHandlers = {};
109
108
  if (addFocusListeners) {
110
109
  eventHandlers.onFocus = event => {
111
- if (!event.currentTarget.contains(event.relatedTarget)) {
110
+ if (!event.currentTarget.contains(event.relatedTarget) && isRail) {
112
111
  handleToggle(event, true);
113
112
  }
114
113
  };
@@ -116,7 +115,7 @@ function SideNavRenderFunction(_ref, ref) {
116
115
  if (!event.currentTarget.contains(event.relatedTarget)) {
117
116
  handleToggle(event, false);
118
117
  }
119
- if (!event.currentTarget.contains(event.relatedTarget) && expanded) {
118
+ if (!event.currentTarget.contains(event.relatedTarget) && expanded && !isFixedNav) {
120
119
  if (onSideNavBlur) {
121
120
  onSideNavBlur();
122
121
  }
@@ -153,7 +152,11 @@ function SideNavRenderFunction(_ref, ref) {
153
152
  sideNavRef.current.focus();
154
153
  }
155
154
  });
156
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, isFixedNav ? null :
155
+ return /*#__PURE__*/React__default.createElement(SideNavContext.Provider, {
156
+ value: {
157
+ isRail
158
+ }
159
+ }, isFixedNav ? null :
157
160
  /*#__PURE__*/
158
161
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
159
162
  React__default.createElement("div", {
@@ -162,7 +165,8 @@ function SideNavRenderFunction(_ref, ref) {
162
165
  }), /*#__PURE__*/React__default.createElement("nav", _extends({
163
166
  tabIndex: -1,
164
167
  ref: navRef,
165
- className: `${prefix}--side-nav__navigation ${className}`
168
+ className: `${prefix}--side-nav__navigation ${className}`,
169
+ inert: !isRail && (expanded ? undefined : -1)
166
170
  }, accessibilityLabel, eventHandlers, other), childrenToRender));
167
171
  }
168
172
  const SideNav = /*#__PURE__*/React__default.forwardRef(SideNavRenderFunction);
@@ -249,4 +253,4 @@ SideNav.propTypes = {
249
253
 
250
254
  var SideNav$1 = SideNav;
251
255
 
252
- export { SideNav$1 as default };
256
+ export { SideNavContext, SideNav$1 as default };
@@ -8,12 +8,13 @@
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import cx from 'classnames';
10
10
  import PropTypes from 'prop-types';
11
- import React__default from 'react';
11
+ import React__default, { useContext } from 'react';
12
12
  import Link, { LinkPropTypes } from './Link.js';
13
13
  import SideNavIcon from './SideNavIcon.js';
14
14
  import SideNavItem from './SideNavItem.js';
15
15
  import SideNavLinkText from './SideNavLinkText.js';
16
16
  import { usePrefix } from '../../internal/usePrefix.js';
17
+ import { SideNavContext } from './SideNav.js';
17
18
 
18
19
  const SideNavLink = /*#__PURE__*/React__default.forwardRef(function SideNavLink(_ref, ref) {
19
20
  let {
@@ -21,9 +22,12 @@ const SideNavLink = /*#__PURE__*/React__default.forwardRef(function SideNavLink(
21
22
  className: customClassName,
22
23
  renderIcon: IconElement,
23
24
  isActive,
25
+ isSideNavExpanded,
24
26
  large = false,
27
+ tabIndex,
25
28
  ...rest
26
29
  } = _ref;
30
+ const isRail = useContext(SideNavContext);
27
31
  const prefix = usePrefix();
28
32
  const className = cx({
29
33
  [`${prefix}--side-nav__link`]: true,
@@ -34,7 +38,8 @@ const SideNavLink = /*#__PURE__*/React__default.forwardRef(function SideNavLink(
34
38
  large: large
35
39
  }, /*#__PURE__*/React__default.createElement(Link, _extends({}, rest, {
36
40
  className: className,
37
- ref: ref
41
+ ref: ref,
42
+ tabIndex: tabIndex === undefined ? !isSideNavExpanded && !isRail ? -1 : 0 : tabIndex
38
43
  }), IconElement && /*#__PURE__*/React__default.createElement(SideNavIcon, {
39
44
  small: true
40
45
  }, /*#__PURE__*/React__default.createElement(IconElement, null)), /*#__PURE__*/React__default.createElement(SideNavLinkText, null, children)));
@@ -54,6 +59,11 @@ SideNavLink.propTypes = {
54
59
  * Specify whether the link is the current page
55
60
  */
56
61
  isActive: PropTypes.bool,
62
+ /**
63
+ * Property to indicate if the side nav container is open (or not). Use to
64
+ * keep local state and styling in step with the SideNav expansion state.
65
+ */
66
+ isSideNavExpanded: PropTypes.bool,
57
67
  /**
58
68
  * Specify if this is a large variation of the SideNavLink
59
69
  */
@@ -61,7 +71,11 @@ SideNavLink.propTypes = {
61
71
  /**
62
72
  * Provide an icon to render in the side navigation link. Should be a React class.
63
73
  */
64
- renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
74
+ renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
75
+ /**
76
+ * Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
77
+ */
78
+ tabIndex: PropTypes.number
65
79
  };
66
80
  var SideNavLink$1 = SideNavLink;
67
81
 
@@ -8,9 +8,10 @@
8
8
  import { ChevronDown } from '@carbon/icons-react';
9
9
  import cx from 'classnames';
10
10
  import PropTypes from 'prop-types';
11
- import React__default, { useState } from 'react';
11
+ import React__default, { useContext, useState } from 'react';
12
12
  import SideNavIcon from './SideNavIcon.js';
13
13
  import { usePrefix } from '../../internal/usePrefix.js';
14
+ import { SideNavContext } from './SideNav.js';
14
15
  import { match } from '../../internal/keyboard/match.js';
15
16
  import { Escape } from '../../internal/keyboard/keys.js';
16
17
 
@@ -24,8 +25,10 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
24
25
  large = false,
25
26
  renderIcon: IconElement,
26
27
  isSideNavExpanded,
28
+ tabIndex,
27
29
  title
28
30
  } = props;
31
+ const isRail = useContext(SideNavContext);
29
32
  const prefix = usePrefix();
30
33
  const [isExpanded, setIsExpanded] = useState(defaultExpanded);
31
34
  const [prevExpanded, setPrevExpanded] = useState(defaultExpanded);
@@ -60,7 +63,8 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
60
63
  setIsExpanded(!isExpanded);
61
64
  },
62
65
  ref: ref,
63
- type: "button"
66
+ type: "button",
67
+ tabIndex: tabIndex === undefined ? !isSideNavExpanded && !isRail ? -1 : 0 : tabIndex
64
68
  }, IconElement && /*#__PURE__*/React__default.createElement(SideNavIcon, null, /*#__PURE__*/React__default.createElement(IconElement, null)), /*#__PURE__*/React__default.createElement("span", {
65
69
  className: `${prefix}--side-nav__submenu-title`,
66
70
  title: title
@@ -108,6 +112,10 @@ SideNavMenu.propTypes = {
108
112
  * Pass in a custom icon to render next to the `SideNavMenu` title
109
113
  */
110
114
  renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
115
+ /**
116
+ * Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
117
+ */
118
+ tabIndex: PropTypes.number,
111
119
  /**
112
120
  * Provide the text for the overall menu name
113
121
  */
@@ -5,6 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- const CARBON_SIDENAV_ITEMS = ['SideNavFooter', 'SideNavHeader', 'SideNavItems', 'SideNavMenu'];
8
+ const CARBON_SIDENAV_ITEMS = ['SideNavFooter', 'SideNavHeader', 'SideNavItems', 'SideNavMenu', 'SideNavLink'];
9
9
 
10
10
  export { CARBON_SIDENAV_ITEMS };
@@ -43,6 +43,29 @@ function getInteractiveContent(node) {
43
43
  return null;
44
44
  }
45
45
 
46
+ /**
47
+ * Determines if a given DOM node has a role, or has itself a role.
48
+ * It returns the node with a role if one is found
49
+ *
50
+ * @param {HTMLElement} node
51
+ * @returns {HTMLElement}
52
+ */
53
+ function getRoleContent(node) {
54
+ if (!node || !node.childNodes) {
55
+ return null;
56
+ }
57
+ if (node?.getAttribute?.('role') && node.getAttribute('role') !== '') {
58
+ return node;
59
+ }
60
+ for (const childNode of node.childNodes) {
61
+ const roleNode = getRoleContent(childNode);
62
+ if (roleNode) {
63
+ return roleNode;
64
+ }
65
+ }
66
+ return null;
67
+ }
68
+
46
69
  /**
47
70
  * Determines if the given element is focusable, or not
48
71
  *
@@ -71,4 +94,4 @@ function isFocusable(element) {
71
94
  }
72
95
  }
73
96
 
74
- export { getInteractiveContent, useNoInteractiveChildren };
97
+ export { getInteractiveContent, getRoleContent, useNoInteractiveChildren };
@@ -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.
@@ -91,6 +91,7 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
91
91
  selectorPrimaryFocus,
92
92
  selectorsFloatingMenus,
93
93
  size,
94
+ launcherButtonRef,
94
95
  ...rest
95
96
  } = _ref2;
96
97
  const prefix = usePrefix.usePrefix();
@@ -186,6 +187,13 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
186
187
  return child;
187
188
  }
188
189
  });
190
+ React.useEffect(() => {
191
+ if (!open && launcherButtonRef) {
192
+ setTimeout(() => {
193
+ launcherButtonRef?.current?.focus();
194
+ });
195
+ }
196
+ }, [open, launcherButtonRef]);
189
197
  React.useEffect(() => {
190
198
  const initialFocus = focusContainerElement => {
191
199
  const containerElement = focusContainerElement || innerModal.current;
@@ -262,6 +270,13 @@ ComposedModal.propTypes = {
262
270
  * Specify whether the Modal content should have any inner padding.
263
271
  */
264
272
  isFullWidth: PropTypes__default["default"].bool,
273
+ /**
274
+ * Provide a ref to return focus to once the modal is closed.
275
+ */
276
+ // @ts-expect-error: Invalid derived type
277
+ launcherButtonRef: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].shape({
278
+ current: PropTypes__default["default"].any
279
+ })]),
265
280
  /**
266
281
  * Specify an optional handler for closing modal.
267
282
  * 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;
@@ -25,13 +25,13 @@ var _span, _span2;
25
25
  const DataTableSkeleton = _ref => {
26
26
  let {
27
27
  headers,
28
- rowCount,
29
- columnCount,
30
- zebra,
31
- compact,
28
+ rowCount = 5,
29
+ columnCount = 5,
30
+ zebra = false,
31
+ compact = false,
32
32
  className,
33
- showHeader,
34
- showToolbar,
33
+ showHeader = true,
34
+ showToolbar = true,
35
35
  ...rest
36
36
  } = _ref;
37
37
  const prefix = usePrefix.usePrefix();
@@ -93,9 +93,9 @@ DataTableSkeleton.propTypes = {
93
93
  /**
94
94
  * Optionally specify the displayed headers
95
95
  */
96
- headers: PropTypes__default["default"].oneOfType([PropTypes__default["default"].array, PropTypes__default["default"].shape({
97
- key: PropTypes__default["default"].string
98
- })]),
96
+ headers: PropTypes__default["default"].arrayOf(PropTypes__default["default"].shape({
97
+ header: PropTypes__default["default"].node.isRequired
98
+ }).isRequired),
99
99
  /**
100
100
  * Specify the number of rows that you want to render in the skeleton state
101
101
  */
@@ -113,13 +113,5 @@ DataTableSkeleton.propTypes = {
113
113
  */
114
114
  zebra: PropTypes__default["default"].bool
115
115
  };
116
- DataTableSkeleton.defaultProps = {
117
- rowCount: 5,
118
- columnCount: 5,
119
- zebra: false,
120
- compact: false,
121
- showHeader: true,
122
- showToolbar: true
123
- };
124
116
 
125
117
  exports["default"] = DataTableSkeleton;
@@ -63,6 +63,7 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
63
63
  preventCloseOnClickOutside,
64
64
  // eslint-disable-line
65
65
  isFullWidth,
66
+ launcherButtonRef,
66
67
  ...rest
67
68
  } = _ref;
68
69
  const prefix = usePrefix.usePrefix();
@@ -160,6 +161,13 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
160
161
  React.useEffect(() => {
161
162
  toggleClass["default"](document.body, `${prefix}--body--with-modal-open`, open);
162
163
  }, [open, prefix]);
164
+ React.useEffect(() => {
165
+ if (!open && launcherButtonRef) {
166
+ setTimeout(() => {
167
+ launcherButtonRef?.current?.focus();
168
+ });
169
+ }
170
+ }, [open, launcherButtonRef]);
163
171
  React.useEffect(() => {
164
172
  const initialFocus = focusContainerElement => {
165
173
  const containerElement = focusContainerElement || innerModal.current;
@@ -292,6 +300,12 @@ Modal.propTypes = {
292
300
  * Specify whether or not the Modal content should have any inner padding.
293
301
  */
294
302
  isFullWidth: PropTypes__default["default"].bool,
303
+ /**
304
+ * Provide a ref to return focus to once the modal is closed.
305
+ */
306
+ launcherButtonRef: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].shape({
307
+ current: PropTypes__default["default"].any
308
+ })]),
295
309
  /**
296
310
  * Specify a label to be read by screen readers on the modal root node
297
311
  */
@@ -44,8 +44,6 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
44
44
 
45
45
  const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(function FilterableMultiSelect(_ref, ref) {
46
46
  let {
47
- ['aria-label']: ariaLabel,
48
- ariaLabel: deprecatedAriaLabel,
49
47
  className: containerClassName,
50
48
  compareItems,
51
49
  direction,
@@ -324,9 +322,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
324
322
  setInputValue('');
325
323
  }
326
324
  });
327
- const menuProps = getMenuProps({
328
- 'aria-label': ariaLabel
329
- }, {
325
+ const menuProps = getMenuProps({}, {
330
326
  suppressRefError: true
331
327
  });
332
328
  const handleFocus = evt => {
@@ -341,7 +337,6 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
341
337
  }, titleText ? /*#__PURE__*/React__default["default"].createElement("label", _rollupPluginBabelHelpers["extends"]({
342
338
  className: titleClasses
343
339
  }, labelProps), titleText) : null, /*#__PURE__*/React__default["default"].createElement(index["default"], {
344
- "aria-label": deprecatedAriaLabel || ariaLabel,
345
340
  onFocus: isFluid ? handleFocus : null,
346
341
  onBlur: isFluid ? handleFocus : null,
347
342
  className: className,
@@ -431,14 +426,15 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
431
426
  });
432
427
  FilterableMultiSelect.propTypes = {
433
428
  /**
429
+ * Deprecated, aria-label is no longer needed
434
430
  * Specify a label to be read by screen readers on the container node
435
431
  */
436
- ['aria-label']: PropTypes__default["default"].string,
432
+ ['aria-label']: deprecate["default"](PropTypes__default["default"].string, 'ariaLabel / aria-label props are no longer required for FilterableMultiSelect'),
437
433
  /**
438
434
  * Deprecated, please use `aria-label` instead.
439
435
  * Specify a label to be read by screen readers on the container note.
440
436
  */
441
- ariaLabel: deprecate["default"](PropTypes__default["default"].string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
437
+ ariaLabel: deprecate["default"](PropTypes__default["default"].string, 'ariaLabel / aria-label props are no longer required for FilterableMultiSelect'),
442
438
  /**
443
439
  * Specify the direction of the multiselect dropdown. Can be either top or bottom.
444
440
  */
@@ -551,7 +547,6 @@ FilterableMultiSelect.propTypes = {
551
547
  warnText: PropTypes__default["default"].node
552
548
  };
553
549
  FilterableMultiSelect.defaultProps = {
554
- ['aria-label']: 'Choose an item',
555
550
  compareItems: sorting.defaultCompareItems,
556
551
  direction: 'bottom',
557
552
  disabled: false,