@carbon/react 1.50.0-rc.0 → 1.51.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 (58) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1005 -1038
  2. package/es/components/Accordion/AccordionItem.js +10 -15
  3. package/es/components/ChatButton/ChatButton.Skeleton.js +40 -0
  4. package/es/components/ChatButton/ChatButton.js +81 -0
  5. package/es/components/ComposedModal/ComposedModal.js +32 -8
  6. package/es/components/Copy/Copy.js +1 -1
  7. package/es/components/DataTable/DataTable.d.ts +21 -0
  8. package/es/components/DataTable/DataTable.js +19 -0
  9. package/es/components/DataTable/TableCell.d.ts +28 -3
  10. package/es/components/DataTable/TableCell.js +22 -5
  11. package/es/components/DataTable/TableExpandRow.js +1 -1
  12. package/es/components/DataTable/TableHeader.js +2 -2
  13. package/es/components/DataTable/TableRow.js +12 -1
  14. package/es/components/DataTable/TableToolbarSearch.d.ts +11 -38
  15. package/es/components/DataTable/TableToolbarSearch.js +1 -1
  16. package/es/components/DataTable/tools/normalize.js +3 -1
  17. package/es/components/Modal/Modal.js +25 -6
  18. package/es/components/MultiSelect/MultiSelect.d.ts +4 -0
  19. package/es/components/MultiSelect/MultiSelect.js +10 -1
  20. package/es/components/NumberInput/NumberInput.js +1 -1
  21. package/es/components/PaginationNav/PaginationNav.d.ts +45 -0
  22. package/es/components/PaginationNav/PaginationNav.js +24 -25
  23. package/es/components/PaginationNav/index.d.ts +9 -0
  24. package/es/components/Tabs/Tabs.js +2 -1
  25. package/es/components/Tile/Tile.d.ts +2 -2
  26. package/es/components/Tile/Tile.js +2 -2
  27. package/es/index.d.ts +1 -0
  28. package/es/index.js +3 -1
  29. package/lib/components/Accordion/AccordionItem.js +9 -14
  30. package/lib/components/ChatButton/ChatButton.Skeleton.js +50 -0
  31. package/lib/components/ChatButton/ChatButton.js +91 -0
  32. package/lib/components/ComposedModal/ComposedModal.js +32 -7
  33. package/lib/components/Copy/Copy.js +1 -1
  34. package/lib/components/DataTable/DataTable.d.ts +21 -0
  35. package/lib/components/DataTable/DataTable.js +19 -0
  36. package/lib/components/DataTable/TableCell.d.ts +28 -3
  37. package/lib/components/DataTable/TableCell.js +27 -5
  38. package/lib/components/DataTable/TableExpandRow.js +1 -1
  39. package/lib/components/DataTable/TableHeader.js +2 -2
  40. package/lib/components/DataTable/TableRow.js +12 -1
  41. package/lib/components/DataTable/TableToolbarSearch.d.ts +11 -38
  42. package/lib/components/DataTable/TableToolbarSearch.js +1 -1
  43. package/lib/components/DataTable/tools/normalize.js +3 -1
  44. package/lib/components/Modal/Modal.js +25 -5
  45. package/lib/components/MultiSelect/MultiSelect.d.ts +4 -0
  46. package/lib/components/MultiSelect/MultiSelect.js +10 -1
  47. package/lib/components/NumberInput/NumberInput.js +1 -1
  48. package/lib/components/PaginationNav/PaginationNav.d.ts +45 -0
  49. package/lib/components/PaginationNav/PaginationNav.js +24 -25
  50. package/lib/components/PaginationNav/index.d.ts +9 -0
  51. package/lib/components/Tabs/Tabs.js +2 -1
  52. package/lib/components/Tile/Tile.d.ts +2 -2
  53. package/lib/components/Tile/Tile.js +2 -2
  54. package/lib/index.d.ts +1 -0
  55. package/lib/index.js +6 -2
  56. package/package.json +5 -5
  57. package/scss/components/chat-button/_chat-button.scss +9 -0
  58. package/scss/components/chat-button/_index.scss +9 -0
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
9
9
  import { ChevronRight } from '@carbon/icons-react';
10
10
  import cx from 'classnames';
11
11
  import PropTypes from 'prop-types';
12
- import React__default, { useState, useContext, useRef } from 'react';
12
+ import React__default, { useState, useContext } from 'react';
13
13
  import '../Text/index.js';
14
14
  import { useId } from '../../internal/useId.js';
15
15
  import deprecate from '../../prop-types/deprecate.js';
@@ -51,7 +51,15 @@ function AccordionItem(_ref) {
51
51
  });
52
52
  const Toggle = renderToggle || renderExpando; // remove renderExpando in next major release
53
53
 
54
- const content = useRef(null);
54
+ const content = React__default.useCallback(node => {
55
+ if (!node) {
56
+ return;
57
+ }
58
+ if (isOpen) {
59
+ // accordion closes
60
+ node.style.maxBlockSize = '';
61
+ }
62
+ }, [isOpen]);
55
63
  if (open !== prevIsOpen) {
56
64
  setIsOpen(open);
57
65
  setPrevIsOpen(open);
@@ -60,19 +68,6 @@ function AccordionItem(_ref) {
60
68
  // When the AccordionItem heading is clicked, toggle the open state of the
61
69
  // panel
62
70
  function onClick(event) {
63
- // type guard for ref
64
- if (!content.current) {
65
- return;
66
- }
67
- if (isOpen) {
68
- // accordion closes
69
- content.current.style.maxBlockSize = '';
70
- } else {
71
- // accordion opens
72
- content.current.style.maxBlockSize =
73
- // Scroll height plus top/bottom padding
74
- content.current.scrollHeight + 32 + 'px';
75
- }
76
71
  const nextValue = !isOpen;
77
72
  setIsOpen(nextValue);
78
73
  if (onHeadingClick) {
@@ -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
+ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
+ import PropTypes from 'prop-types';
10
+ import React__default from 'react';
11
+ import cx from 'classnames';
12
+ import { usePrefix } from '../../internal/usePrefix.js';
13
+
14
+ const ChatButtonSkeleton = _ref => {
15
+ let {
16
+ className,
17
+ size,
18
+ ...rest
19
+ } = _ref;
20
+ const prefix = usePrefix();
21
+ const skeletonClasses = cx(className, `${prefix}--skeleton`, `${prefix}--btn`, `${prefix}--chat-btn`, {
22
+ [`${prefix}--layout--size-${size}`]: size
23
+ });
24
+ return /*#__PURE__*/React__default.createElement("div", _extends({
25
+ className: skeletonClasses
26
+ }, rest));
27
+ };
28
+ ChatButtonSkeleton.propTypes = {
29
+ /**
30
+ * Specify an optional className to add.
31
+ */
32
+ className: PropTypes.string,
33
+ /**
34
+ * Specify the size of the `ChatButtonSkeleton`, from the following list of sizes:
35
+ */
36
+ size: PropTypes.oneOf(['sm', 'md', 'lg'])
37
+ };
38
+ var ChatButtonSkeleton$1 = ChatButtonSkeleton;
39
+
40
+ export { ChatButtonSkeleton$1 as default };
@@ -0,0 +1,81 @@
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 { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
+ import PropTypes from 'prop-types';
10
+ import React__default from 'react';
11
+ import cx from 'classnames';
12
+ import Button from '../Button/Button.js';
13
+ import '../Button/Button.Skeleton.js';
14
+ import { usePrefix } from '../../internal/usePrefix.js';
15
+
16
+ const ChatButton = /*#__PURE__*/React__default.forwardRef(function ChatButton(_ref, ref) {
17
+ let {
18
+ className,
19
+ children,
20
+ disabled,
21
+ isQuickAction,
22
+ isSelected,
23
+ kind,
24
+ size,
25
+ ...other
26
+ } = _ref;
27
+ const prefix = usePrefix();
28
+ const classNames = cx(className, {
29
+ [`${prefix}--chat-btn`]: true,
30
+ [`${prefix}--chat-btn--quick-action`]: isQuickAction,
31
+ [`${prefix}--chat-btn--quick-action--selected`]: isSelected
32
+ });
33
+ const allowedSizes = ['sm', 'md', 'lg'];
34
+ if (isQuickAction) {
35
+ kind = 'ghost';
36
+ size = 'sm';
37
+ } else {
38
+ // Do not allow size larger than `lg`
39
+ size = allowedSizes.includes(size) ? size : 'lg';
40
+ }
41
+ return /*#__PURE__*/React__default.createElement(Button, _extends({
42
+ disabled: disabled,
43
+ className: classNames,
44
+ kind: kind,
45
+ ref: ref,
46
+ size: size
47
+ }, other), children);
48
+ });
49
+ ChatButton.propTypes = {
50
+ /**
51
+ * Provide the contents of your Select
52
+ */
53
+ children: PropTypes.node,
54
+ /**
55
+ * Specify an optional className to be applied to the node containing the label and the select box
56
+ */
57
+ className: PropTypes.string,
58
+ /**
59
+ * Specify whether the `ChatButton` should be disabled
60
+ */
61
+ disabled: PropTypes.bool,
62
+ /**
63
+ * Specify whether the `ChatButton` should be rendered as a quick action button
64
+ */
65
+ isQuickAction: PropTypes.bool,
66
+ /**
67
+ * Specify whether the quick action `ChatButton` should be rendered as selected. This disables the input
68
+ */
69
+ isSelected: PropTypes.bool,
70
+ /**
71
+ * Specify the kind of `ChatButton` you want to create
72
+ */
73
+ kind: PropTypes.oneOf(['primary', 'secondary', 'danger', 'ghost', 'tertiary']),
74
+ /**
75
+ * Specify the size of the `ChatButton`, from the following list of sizes:
76
+ */
77
+ size: PropTypes.oneOf(['sm', 'md', 'lg'])
78
+ };
79
+ var ChatButton$1 = ChatButton;
80
+
81
+ export { ChatButton$1 as default };
@@ -6,11 +6,14 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useState, useRef, useEffect } from 'react';
9
+ import React__default, { useRef, useState, useEffect } from 'react';
10
10
  import { isElement } from 'react-is';
11
11
  import PropTypes from 'prop-types';
12
12
  import { ModalHeader } from './ModalHeader.js';
13
13
  import { ModalFooter } from './ModalFooter.js';
14
+ import debounce from 'lodash.debounce';
15
+ import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
16
+ import mergeRefs from '../../tools/mergeRefs.js';
14
17
  import cx from 'classnames';
15
18
  import toggleClass from '../../tools/toggleClass.js';
16
19
  import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
@@ -28,18 +31,39 @@ const ModalBody = /*#__PURE__*/React__default.forwardRef(function ModalBody(_ref
28
31
  ...rest
29
32
  } = _ref;
30
33
  const prefix = usePrefix();
31
- const contentClass = cx(`${prefix}--modal-content`, hasForm && `${prefix}--modal-content--with-form`, hasScrollingContent && `${prefix}--modal-scroll-content`, customClassName);
32
- const hasScrollingContentProps = hasScrollingContent ? {
34
+ const contentRef = useRef(null);
35
+ const [isScrollable, setIsScrollable] = useState(false);
36
+ const contentClass = cx({
37
+ [`${prefix}--modal-content`]: true,
38
+ [`${prefix}--modal-content--with-form`]: hasForm,
39
+ [`${prefix}--modal-scroll-content`]: hasScrollingContent || isScrollable,
40
+ customClassName
41
+ });
42
+ useIsomorphicEffect(() => {
43
+ if (contentRef.current) {
44
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
45
+ }
46
+ function handler() {
47
+ if (contentRef.current) {
48
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
49
+ }
50
+ }
51
+ const debouncedHandler = debounce(handler, 200);
52
+ window.addEventListener('resize', debouncedHandler);
53
+ return () => {
54
+ debouncedHandler.cancel();
55
+ window.removeEventListener('resize', debouncedHandler);
56
+ };
57
+ }, []);
58
+ const hasScrollingContentProps = hasScrollingContent || isScrollable ? {
33
59
  tabIndex: 0,
34
60
  role: 'region'
35
61
  } : {};
36
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", _extends({
62
+ return /*#__PURE__*/React__default.createElement("div", _extends({
37
63
  className: contentClass
38
64
  }, hasScrollingContentProps, rest, {
39
- ref: ref
40
- }), children), hasScrollingContent && /*#__PURE__*/React__default.createElement("div", {
41
- className: `${prefix}--modal-content--overflow-indicator`
42
- }));
65
+ ref: mergeRefs(contentRef, ref)
66
+ }), children);
43
67
  });
44
68
  ModalBody.propTypes = {
45
69
  /**
@@ -41,7 +41,7 @@ function Copy(_ref) {
41
41
  handleFadeOut();
42
42
  }, [handleFadeOut]);
43
43
  const handleAnimationEnd = event => {
44
- if (event.animationName === 'hide-feedback') {
44
+ if (event.animationName === `${prefix}--hide-feedback`) {
45
45
  setAnimation('');
46
46
  }
47
47
  };
@@ -53,6 +53,7 @@ export interface DataTableRow<ColTypes extends any[]> {
53
53
  export interface DataTableHeader {
54
54
  key: string;
55
55
  header: React.ReactNode;
56
+ slug?: React.ReactElement;
56
57
  }
57
58
  export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
58
59
  headers: Array<DataTableHeader>;
@@ -152,6 +153,12 @@ export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
152
153
  stickyHeader?: boolean;
153
154
  useStaticWidth?: boolean;
154
155
  };
156
+ getCellProps: (getCellPropsArgs: {
157
+ cell: DataTableCell<ColTypes>;
158
+ }) => {
159
+ [key: string]: unknown;
160
+ hasSlugHeader?: boolean;
161
+ };
155
162
  onInputChange: (e: React.ChangeEvent<HTMLInputElement>, defaultValue?: string) => void;
156
163
  sortBy: (headerKey: string) => void;
157
164
  selectAll: () => void;
@@ -334,6 +341,7 @@ declare class DataTable<RowType, ColTypes extends any[]> extends React.Component
334
341
  sortDirection: DataTableSortState;
335
342
  isSortable: boolean | undefined;
336
343
  isSortHeader: boolean;
344
+ slug: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
337
345
  onClick: (event: any) => void;
338
346
  };
339
347
  /**
@@ -468,6 +476,19 @@ declare class DataTable<RowType, ColTypes extends any[]> extends React.Component
468
476
  stickyHeader: boolean | undefined;
469
477
  useStaticWidth: boolean | undefined;
470
478
  };
479
+ /**
480
+ * Get the props associated with the given table cell.
481
+ *
482
+ * @param {object} config
483
+ * @param {object} config.cell the cell we want the props for
484
+ * @returns {object}
485
+ */
486
+ getCellProps: ({ cell, ...rest }: {
487
+ [x: string]: any;
488
+ cell: any;
489
+ }) => {
490
+ hasSlugHeader: any;
491
+ };
471
492
  /**
472
493
  * Helper utility to get all the currently selected rows
473
494
  * @returns {Array<string>} the array of rowIds that are currently selected
@@ -103,6 +103,7 @@ class DataTable extends React__default.Component {
103
103
  sortDirection,
104
104
  isSortable,
105
105
  isSortHeader: sortHeaderKey === header.key,
106
+ slug: header.slug,
106
107
  onClick: event => {
107
108
  const nextSortState = getNextSortState(this.props, this.state, {
108
109
  key: header.key
@@ -339,6 +340,23 @@ class DataTable extends React__default.Component {
339
340
  useStaticWidth
340
341
  };
341
342
  });
343
+ /**
344
+ * Get the props associated with the given table cell.
345
+ *
346
+ * @param {object} config
347
+ * @param {object} config.cell the cell we want the props for
348
+ * @returns {object}
349
+ */
350
+ _defineProperty(this, "getCellProps", _ref4 => {
351
+ let {
352
+ cell,
353
+ ...rest
354
+ } = _ref4;
355
+ return {
356
+ ...rest,
357
+ hasSlugHeader: cell.hasSlugHeader
358
+ };
359
+ });
342
360
  /**
343
361
  * Helper utility to get all the currently selected rows
344
362
  * @returns {Array<string>} the array of rowIds that are currently selected
@@ -612,6 +630,7 @@ class DataTable extends React__default.Component {
612
630
  getBatchActionProps: this.getBatchActionProps,
613
631
  getTableProps: this.getTableProps,
614
632
  getTableContainerProps: this.getTableContainerProps,
633
+ getCellProps: this.getCellProps,
615
634
  // Custom event handlers
616
635
  onInputChange: this.handleOnInputValueChange,
617
636
  // Expose internal state change actions
@@ -4,7 +4,32 @@
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 { TdHTMLAttributes } from 'react';
8
- export type TableCellProps = TdHTMLAttributes<HTMLTableCellElement>;
9
- declare const TableCell: React.FC<TableCellProps>;
7
+ import React from 'react';
8
+ import { ReactAttr } from '../../types/common';
9
+ interface TableCellProps extends ReactAttr<HTMLTableCellElement> {
10
+ /**
11
+ * Pass in children that will be embedded in the table header label
12
+ */
13
+ children?: React.ReactNode;
14
+ /**
15
+ * Specify an optional className to be applied to the container node
16
+ */
17
+ className?: string;
18
+ /**
19
+ * The width of the expanded row's internal cell
20
+ */
21
+ colSpan?: number;
22
+ /**
23
+ * Specify if the table cell is in an AI column
24
+ */
25
+ hasSlugHeader?: boolean;
26
+ /**
27
+ * The id of the matching th node in the table head. Addresses a11y concerns outlined here: https://www.ibm.com/able/guidelines/ci162/info_and_relationships.html and https://www.w3.org/TR/WCAG20-TECHS/H43
28
+ */
29
+ headers?: string;
30
+ }
31
+ declare const TableCell: {
32
+ ({ children, className, hasSlugHeader, colSpan, ...rest }: TableCellProps): import("react/jsx-runtime").JSX.Element;
33
+ displayName: string;
34
+ };
10
35
  export default TableCell;
@@ -5,11 +5,28 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import wrapComponent from '../../tools/wrapComponent.js';
8
+ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
+ import React__default from 'react';
10
+ import cx from 'classnames';
11
+ import { usePrefix } from '../../internal/usePrefix.js';
9
12
 
10
- const TableCell = wrapComponent({
11
- name: 'TableCell',
12
- type: 'td'
13
- });
13
+ const TableCell = _ref => {
14
+ let {
15
+ children,
16
+ className,
17
+ hasSlugHeader,
18
+ colSpan,
19
+ ...rest
20
+ } = _ref;
21
+ const prefix = usePrefix();
22
+ const tableCellClassNames = cx(className, {
23
+ [`${prefix}--table-cell--column-slug`]: hasSlugHeader
24
+ });
25
+ return /*#__PURE__*/React__default.createElement("td", _extends({
26
+ className: tableCellClassNames ? tableCellClassNames : undefined,
27
+ colSpan: colSpan
28
+ }, rest), children);
29
+ };
30
+ TableCell.displayName = 'TableCell';
14
31
 
15
32
  export { TableCell as default };
@@ -48,7 +48,7 @@ const TableExpandRow = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
48
48
  [`${prefix}--parent-row`]: true,
49
49
  [`${prefix}--expandable-row`]: isExpanded,
50
50
  [`${prefix}--data-table--selected`]: isSelected,
51
- [`${prefix}--parent-row--slug`]: rowHasSlug
51
+ [`${prefix}--data-table--slug-row`]: rowHasSlug
52
52
  }, rowClassName);
53
53
  const previousValue = isExpanded ? 'collapsed' : undefined;
54
54
  return /*#__PURE__*/React__default.createElement("tr", _extends({}, rest, {
@@ -124,13 +124,13 @@ const TableHeader = /*#__PURE__*/React__default.forwardRef(function TableHeader(
124
124
  className: `${prefix}--table-sort__flex`
125
125
  }, /*#__PURE__*/React__default.createElement("div", {
126
126
  className: `${prefix}--table-header-label`
127
- }, children), normalizedSlug, /*#__PURE__*/React__default.createElement(ArrowUp, {
127
+ }, children), /*#__PURE__*/React__default.createElement(ArrowUp, {
128
128
  size: 20,
129
129
  className: `${prefix}--table-sort__icon`
130
130
  }), /*#__PURE__*/React__default.createElement(ArrowsVertical, {
131
131
  size: 20,
132
132
  className: `${prefix}--table-sort__icon-unsorted`
133
- }))));
133
+ }), normalizedSlug)));
134
134
  });
135
135
  TableHeader.propTypes = {
136
136
  /**
@@ -13,10 +13,21 @@ import { usePrefix } from '../../internal/usePrefix.js';
13
13
 
14
14
  const TableRow = props => {
15
15
  const prefix = usePrefix();
16
+ let rowHasSlug;
17
+ if (props?.children) {
18
+ React__default.Children.toArray(props.children).map(child => {
19
+ if (child.type?.displayName === 'TableSlugRow') {
20
+ if (child.props.slug) {
21
+ rowHasSlug = true;
22
+ }
23
+ }
24
+ });
25
+ }
16
26
  // Remove unnecessary props if provided to this component, these are
17
27
  // only useful in `TableExpandRow`
18
28
  const className = cx(props.className, {
19
- [`${prefix}--data-table--selected`]: props.isSelected
29
+ [`${prefix}--data-table--selected`]: props.isSelected,
30
+ [`${prefix}--data-table--slug-row`]: rowHasSlug
20
31
  });
21
32
  const cleanProps = {
22
33
  ...omit(props, ['ariaLabel', 'aria-label', 'aria-controls', 'onExpand', 'isExpanded', 'isSelected']),
@@ -6,12 +6,12 @@
6
6
  */
7
7
  import PropTypes from 'prop-types';
8
8
  import { ChangeEvent, FocusEvent, ReactNode } from 'react';
9
- export interface TableToolbarSearchProps {
10
- children?: ReactNode;
11
- /**
12
- * Provide an optional class name for the search container
13
- */
14
- className?: string;
9
+ import { SearchProps } from '../Search';
10
+ import { InternationalProps } from '../../types/common';
11
+ export type TableToolbarTranslationKey = 'carbon.table.toolbar.search.label' | 'carbon.table.toolbar.search.placeholder';
12
+ type ExcludedInheritedProps = 'defaultValue' | 'labelText' | 'onBlur' | 'onChange' | 'onExpand' | 'onFocus' | 'tabIndex';
13
+ export type TableToolbarSearchHandleExpand = (event: FocusEvent<HTMLInputElement>, newValue?: boolean) => void;
14
+ export interface TableToolbarSearchProps extends Omit<SearchProps, ExcludedInheritedProps>, InternationalProps<TableToolbarTranslationKey> {
15
15
  /**
16
16
  * Specifies if the search should initially render in an expanded state
17
17
  */
@@ -20,70 +20,43 @@ export interface TableToolbarSearchProps {
20
20
  * Provide an optional default value for the Search component
21
21
  */
22
22
  defaultValue?: string;
23
- /**
24
- * Specifies if the search should be disabled
25
- */
26
- disabled?: boolean;
27
23
  /**
28
24
  * Specifies if the search should expand
29
25
  */
30
26
  expanded?: boolean;
31
- /**
32
- * Provide an optional id for the search container
33
- */
34
- id?: string;
35
27
  /**
36
28
  * Provide an optional label text for the Search component icon
37
29
  */
38
- labelText?: string;
30
+ labelText?: ReactNode;
39
31
  /**
40
32
  * Provide an optional function to be called when the search input loses focus, this will be
41
33
  * passed the event as the first parameter and a function to handle the expanding of the search
42
34
  * input as the second
43
35
  */
44
- onBlur?: (event: FocusEvent<HTMLInputElement>, handleExpand: (event: FocusEvent<HTMLInputElement>, value: boolean) => void) => void;
36
+ onBlur?(event: FocusEvent<HTMLInputElement>, handleExpand: TableToolbarSearchHandleExpand): void;
45
37
  /**
46
38
  * Provide an optional hook that is called each time the input is updated
47
39
  */
48
40
  onChange?: (event: '' | ChangeEvent<HTMLInputElement>, value?: string) => void;
49
- /**
50
- * Optional callback called when the search value is cleared.
51
- */
52
- onClear?: () => void;
53
41
  /**
54
42
  * Provide an optional hook that is called each time the input is expanded
55
43
  */
56
- onExpand?: (event: FocusEvent<HTMLInputElement>, value: boolean) => void;
44
+ onExpand?(event: FocusEvent<HTMLInputElement>, newExpand: boolean): void;
57
45
  /**
58
46
  * Provide an optional function to be called when the search input gains focus, this will be
59
47
  * passed the event as the first parameter and a function to handle the expanding of the search
60
48
  * input as the second.
61
49
  */
62
- onFocus?: (event: FocusEvent<HTMLInputElement>, handleExpand: (event: FocusEvent<HTMLInputElement>, value: boolean) => void) => void;
50
+ onFocus?(event: FocusEvent<HTMLInputElement>, handleExpand: TableToolbarSearchHandleExpand): void;
63
51
  /**
64
- * Whether the search should be allowed to expand
52
+ * Whether the search should be allowed to expand.
65
53
  */
66
54
  persistent?: boolean;
67
- /**
68
- * Provide an optional placeholder text for the Search component
69
- */
70
- placeholder?: string;
71
55
  /**
72
56
  * Provide an optional className for the overall container of the Search
73
57
  */
74
58
  searchContainerClass?: string;
75
- /**
76
- * Specify the size of the Search
77
- */
78
- size?: 'sm' | 'md' | 'lg';
79
- /**
80
- * Optional prop to specify the tabIndex of the <Search> (in expanded state) or the container (in collapsed state)
81
- */
82
59
  tabIndex?: number | string;
83
- /**
84
- * Provide custom text for the component for each translation id
85
- */
86
- translateWithId?: (id: string) => string;
87
60
  }
88
61
  declare const TableToolbarSearch: {
89
62
  ({ className, searchContainerClass, onChange: onChangeProp, onClear, translateWithId: t, placeholder, labelText, expanded: expandedProp, defaultExpanded, defaultValue, disabled, onExpand, persistent, id, onBlur, onFocus, size, tabIndex, ...rest }: TableToolbarSearchProps): import("react/jsx-runtime").JSX.Element;
@@ -48,7 +48,7 @@ const TableToolbarSearch = _ref => {
48
48
  const {
49
49
  current: controlled
50
50
  } = useRef(expandedProp !== undefined);
51
- const [expandedState, setExpandedState] = useState(defaultExpanded || defaultValue);
51
+ const [expandedState, setExpandedState] = useState(Boolean(defaultExpanded || defaultValue));
52
52
  const expanded = controlled ? expandedProp : expandedState;
53
53
  const [value, setValue] = useState(defaultValue || '');
54
54
  const uniqueId = useMemo(getInstanceId, []);
@@ -48,7 +48,8 @@ const normalize = function (rows, headers) {
48
48
  }
49
49
  headers.forEach((_ref, i) => {
50
50
  let {
51
- key
51
+ key,
52
+ slug
52
53
  } = _ref;
53
54
  const id = getCellId(row.id, key);
54
55
  // Initialize the cell info and state values, namely for editing
@@ -59,6 +60,7 @@ const normalize = function (rows, headers) {
59
60
  isEditing: false,
60
61
  isValid: true,
61
62
  errors: null,
63
+ hasSlugHeader: !!slug,
62
64
  info: {
63
65
  header: key
64
66
  }
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import PropTypes from 'prop-types';
10
- import React__default, { useRef, useEffect } from 'react';
10
+ import React__default, { useRef, useState, useEffect } from 'react';
11
11
  import cx from 'classnames';
12
12
  import { Close } from '@carbon/icons-react';
13
13
  import toggleClass from '../../tools/toggleClass.js';
@@ -17,6 +17,8 @@ import ButtonSet from '../ButtonSet/ButtonSet.js';
17
17
  import InlineLoading from '../InlineLoading/InlineLoading.js';
18
18
  import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
19
19
  import wrapFocus, { elementOrParentIsFloatingMenu } from '../../internal/wrapFocus.js';
20
+ import debounce from 'lodash.debounce';
21
+ import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
20
22
  import setupGetInstanceId from '../../tools/setupGetInstanceId.js';
21
23
  import { usePrefix } from '../../internal/usePrefix.js';
22
24
  import { IconButton } from '../IconButton/index.js';
@@ -66,9 +68,11 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
66
68
  const prefix = usePrefix();
67
69
  const button = useRef(null);
68
70
  const secondaryButton = useRef();
71
+ const contentRef = useRef(null);
69
72
  const innerModal = useRef(null);
70
73
  const startTrap = useRef(null);
71
74
  const endTrap = useRef(null);
75
+ const [isScrollable, setIsScrollable] = useState(false);
72
76
  const modalInstanceId = `modal-${getInstanceId()}`;
73
77
  const modalLabelId = `${prefix}--modal-header__label--${modalInstanceId}`;
74
78
  const modalHeadingId = `${prefix}--modal-header__heading--${modalInstanceId}`;
@@ -134,7 +138,7 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
134
138
  [`${prefix}--modal-container--full-width`]: isFullWidth
135
139
  });
136
140
  const contentClasses = cx(`${prefix}--modal-content`, {
137
- [`${prefix}--modal-scroll-content`]: hasScrollingContent
141
+ [`${prefix}--modal-scroll-content`]: hasScrollingContent || isScrollable
138
142
  });
139
143
  const footerClasses = cx(`${prefix}--modal-footer`, {
140
144
  [`${prefix}--modal-footer--three-button`]: Array.isArray(secondaryButtons) && secondaryButtons.length === 2
@@ -146,7 +150,7 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
146
150
  const modalHeadingStr = asStringOrUndefined(modalHeading);
147
151
  const ariaLabel = modalLabelStr || ariaLabelProp || modalAriaLabel || modalHeadingStr;
148
152
  const getAriaLabelledBy = modalLabel ? modalLabelId : modalHeadingId;
149
- const hasScrollingContentProps = hasScrollingContent ? {
153
+ const hasScrollingContentProps = hasScrollingContent || isScrollable ? {
150
154
  tabIndex: 0,
151
155
  role: 'region',
152
156
  'aria-label': ariaLabel,
@@ -194,6 +198,22 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
194
198
  focusButton(innerModal.current);
195
199
  }
196
200
  }, [open, selectorPrimaryFocus, danger, prefix]);
201
+ useIsomorphicEffect(() => {
202
+ if (contentRef.current) {
203
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
204
+ }
205
+ function handler() {
206
+ if (contentRef.current) {
207
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
208
+ }
209
+ }
210
+ const debouncedHandler = debounce(handler, 200);
211
+ window.addEventListener('resize', debouncedHandler);
212
+ return () => {
213
+ debouncedHandler.cancel();
214
+ window.removeEventListener('resize', debouncedHandler);
215
+ };
216
+ }, []);
197
217
 
198
218
  // Slug is always size `lg`
199
219
  let normalizedSlug;
@@ -237,11 +257,10 @@ const Modal = /*#__PURE__*/React__default.forwardRef(function Modal(_ref, ref) {
237
257
  id: modalHeadingId,
238
258
  className: `${prefix}--modal-header__heading`
239
259
  }, modalHeading), normalizedSlug, !passiveModal && modalButton), /*#__PURE__*/React__default.createElement("div", _extends({
260
+ ref: contentRef,
240
261
  id: modalBodyId,
241
262
  className: contentClasses
242
- }, hasScrollingContentProps), children), hasScrollingContent && /*#__PURE__*/React__default.createElement("div", {
243
- className: `${prefix}--modal-content--overflow-indicator`
244
- }), !passiveModal && /*#__PURE__*/React__default.createElement(ButtonSet, {
263
+ }, hasScrollingContentProps), children), !passiveModal && /*#__PURE__*/React__default.createElement(ButtonSet, {
245
264
  className: footerClasses,
246
265
  "aria-busy": loadingActive
247
266
  }, Array.isArray(secondaryButtons) && secondaryButtons.length <= 2 ? secondaryButtons.map((_ref3, i) => {