@carbon/react 1.50.0 → 1.51.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 (44) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +844 -926
  2. package/README.md +19 -0
  3. package/es/components/AiSkeleton/AiSkeletonIcon.d.ts +32 -0
  4. package/es/components/AiSkeleton/AiSkeletonPlaceholder.d.ts +24 -0
  5. package/es/components/AiSkeleton/AiSkeletonText.d.ts +55 -0
  6. package/es/components/AiSkeleton/index.d.ts +10 -0
  7. package/es/components/ComposedModal/ComposedModal.js +32 -8
  8. package/es/components/Copy/Copy.js +1 -1
  9. package/es/components/DataTable/DataTable.d.ts +2 -2
  10. package/es/components/DataTable/TableToolbarSearch.d.ts +11 -38
  11. package/es/components/DataTable/TableToolbarSearch.js +1 -1
  12. package/es/components/Modal/Modal.js +25 -6
  13. package/es/components/MultiSelect/MultiSelect.d.ts +4 -0
  14. package/es/components/MultiSelect/MultiSelect.js +10 -1
  15. package/es/components/NumberInput/NumberInput.js +1 -1
  16. package/es/components/PaginationNav/PaginationNav.d.ts +45 -0
  17. package/es/components/PaginationNav/PaginationNav.js +24 -25
  18. package/es/components/PaginationNav/index.d.ts +9 -0
  19. package/es/components/Tabs/Tabs.js +2 -1
  20. package/es/components/Tile/Tile.d.ts +2 -2
  21. package/es/components/Tile/Tile.js +2 -2
  22. package/es/index.js +1 -1
  23. package/lib/components/AiSkeleton/AiSkeletonIcon.d.ts +32 -0
  24. package/lib/components/AiSkeleton/AiSkeletonPlaceholder.d.ts +24 -0
  25. package/lib/components/AiSkeleton/AiSkeletonText.d.ts +55 -0
  26. package/lib/components/AiSkeleton/index.d.ts +10 -0
  27. package/lib/components/ComposedModal/ComposedModal.js +32 -7
  28. package/lib/components/Copy/Copy.js +1 -1
  29. package/lib/components/DataTable/DataTable.d.ts +2 -2
  30. package/lib/components/DataTable/TableToolbarSearch.d.ts +11 -38
  31. package/lib/components/DataTable/TableToolbarSearch.js +1 -1
  32. package/lib/components/Modal/Modal.js +25 -5
  33. package/lib/components/MultiSelect/MultiSelect.d.ts +4 -0
  34. package/lib/components/MultiSelect/MultiSelect.js +10 -1
  35. package/lib/components/NumberInput/NumberInput.js +1 -1
  36. package/lib/components/PaginationNav/PaginationNav.d.ts +45 -0
  37. package/lib/components/PaginationNav/PaginationNav.js +24 -25
  38. package/lib/components/PaginationNav/index.d.ts +9 -0
  39. package/lib/components/Tabs/Tabs.js +2 -1
  40. package/lib/components/Tile/Tile.d.ts +2 -2
  41. package/lib/components/Tile/Tile.js +2 -2
  42. package/lib/index.js +2 -2
  43. package/package.json +4 -4
  44. package/scss/components/skeleton-styles/_ai-skeleton-styles.scss +9 -0
@@ -27,23 +27,23 @@ function translateWithId(messageId) {
27
27
 
28
28
  // https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
29
29
  function usePrevious(value) {
30
- const ref = useRef();
30
+ const ref = useRef(null);
31
31
  useEffect(() => {
32
32
  ref.current = value;
33
33
  });
34
34
  return ref.current;
35
35
  }
36
- function getCuts(page, totalItems, itemsThatFit) {
36
+ function calculateCuts(page, totalItems, itemsDisplayedOnPage) {
37
37
  let splitPoint = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
38
- if (itemsThatFit >= totalItems) {
38
+ if (itemsDisplayedOnPage >= totalItems) {
39
39
  return {
40
40
  front: 0,
41
41
  back: 0
42
42
  };
43
43
  }
44
- const split = splitPoint || Math.ceil(itemsThatFit / 2) - 1;
44
+ const split = splitPoint || Math.ceil(itemsDisplayedOnPage / 2) - 1;
45
45
  let frontHidden = page + 1 - split;
46
- let backHidden = totalItems - page - (itemsThatFit - split) + 1;
46
+ let backHidden = totalItems - page - (itemsDisplayedOnPage - split) + 1;
47
47
  if (frontHidden <= 1) {
48
48
  backHidden -= frontHidden <= 0 ? Math.abs(frontHidden) + 1 : 0;
49
49
  frontHidden = 0;
@@ -93,15 +93,15 @@ function PaginationItem(_ref2) {
93
93
  }),
94
94
  onClick: onClick,
95
95
  "data-page": page,
96
- "aria-current": isActive ? 'page' : null
96
+ "aria-current": isActive ? 'page' : undefined
97
97
  }, /*#__PURE__*/React__default.createElement("span", {
98
98
  className: `${prefix}--pagination-nav__accessibility-label`
99
99
  }, isActive ? `${t('carbon.pagination-nav.active')}, ${itemLabel}` : itemLabel), page));
100
100
  }
101
101
  function PaginationOverflow(_ref3) {
102
102
  let {
103
- fromIndex,
104
- count,
103
+ fromIndex = NaN,
104
+ count = NaN,
105
105
  onSelect,
106
106
  // eslint-disable-next-line react/prop-types
107
107
  disableOverflow,
@@ -135,7 +135,7 @@ function PaginationOverflow(_ref3) {
135
135
  "aria-label": `Select ${t('carbon.pagination-nav.item')} number`,
136
136
  onChange: e => {
137
137
  const index = Number(e.target.value);
138
- onSelect(index);
138
+ onSelect?.(index);
139
139
  }
140
140
  }, _option || (_option = /*#__PURE__*/React__default.createElement("option", {
141
141
  value: "",
@@ -155,7 +155,7 @@ function PaginationOverflow(_ref3) {
155
155
  page: fromIndex + 1,
156
156
  translateWithId: t,
157
157
  onClick: () => {
158
- onSelect(fromIndex);
158
+ onSelect?.(fromIndex);
159
159
  }
160
160
  });
161
161
  }
@@ -165,7 +165,7 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
165
165
  let {
166
166
  className,
167
167
  onChange = () => {},
168
- totalItems,
168
+ totalItems = NaN,
169
169
  disableOverflow,
170
170
  itemsShown = 10,
171
171
  page = 0,
@@ -174,8 +174,8 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
174
174
  ...rest
175
175
  } = _ref4;
176
176
  const [currentPage, setCurrentPage] = useState(page);
177
- const [itemsThatFit, setItemsThatFit] = useState(itemsShown >= 4 ? itemsShown : 4);
178
- const [cuts, setCuts] = useState(getCuts(currentPage, totalItems, itemsThatFit));
177
+ const [itemsDisplayedOnPage, setItemsDisplayedOnPage] = useState(itemsShown >= 4 ? itemsShown : 4);
178
+ const [cuts, setCuts] = useState(calculateCuts(currentPage, totalItems, itemsDisplayedOnPage));
179
179
  const prevPage = usePrevious(currentPage);
180
180
  const prefix = usePrefix();
181
181
  const [isOverflowDisabled, setIsOverFlowDisabled] = useState(disableOverflow);
@@ -206,7 +206,7 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
206
206
  }
207
207
  }
208
208
  function pageWouldBeHidden(page) {
209
- const startOffset = itemsThatFit <= 4 && page > 1 ? 0 : 1;
209
+ const startOffset = itemsDisplayedOnPage <= 4 && page > 1 ? 0 : 1;
210
210
  const wouldBeHiddenInFront = page >= startOffset && page <= cuts.front;
211
211
  const wouldBeHiddenInBack = page >= totalItems - cuts.back - 1 && page <= totalItems - 2;
212
212
  return wouldBeHiddenInFront || wouldBeHiddenInBack;
@@ -219,20 +219,20 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
219
219
 
220
220
  // re-calculate cuts if props.totalItems or props.itemsShown change
221
221
  useEffect(() => {
222
- setItemsThatFit(itemsShown >= 4 ? itemsShown : 4);
223
- setCuts(getCuts(currentPage, totalItems, itemsShown));
222
+ setItemsDisplayedOnPage(itemsShown >= 4 ? itemsShown : 4);
223
+ setCuts(calculateCuts(currentPage, totalItems, itemsShown));
224
224
  }, [totalItems, itemsShown]); // eslint-disable-line react-hooks/exhaustive-deps
225
225
 
226
226
  // update cuts if necessary whenever currentPage changes
227
227
  useEffect(() => {
228
228
  if (pageWouldBeHidden(currentPage)) {
229
- const delta = currentPage - prevPage || 0;
229
+ const delta = currentPage - (prevPage || 0);
230
230
  if (delta > 0) {
231
- const splitPoint = itemsThatFit - 3;
232
- setCuts(getCuts(currentPage, totalItems, itemsThatFit, splitPoint));
231
+ const splitPoint = itemsDisplayedOnPage - 3;
232
+ setCuts(calculateCuts(currentPage, totalItems, itemsDisplayedOnPage, splitPoint));
233
233
  } else {
234
- const splitPoint = itemsThatFit > 4 ? 2 : 1;
235
- setCuts(getCuts(currentPage, totalItems, itemsThatFit, splitPoint));
234
+ const splitPoint = itemsDisplayedOnPage > 4 ? 2 : 1;
235
+ setCuts(calculateCuts(currentPage, totalItems, itemsDisplayedOnPage, splitPoint));
236
236
  }
237
237
  }
238
238
  }, [currentPage]); // eslint-disable-line react-hooks/exhaustive-deps
@@ -243,7 +243,7 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
243
243
  const classNames = cx(`${prefix}--pagination-nav`, className);
244
244
  const backwardButtonDisabled = !loop && currentPage === 0;
245
245
  const forwardButtonDisabled = !loop && currentPage === totalItems - 1;
246
- const startOffset = itemsThatFit <= 4 && currentPage > 1 ? 0 : 1;
246
+ const startOffset = itemsDisplayedOnPage <= 4 && currentPage > 1 ? 0 : 1;
247
247
  return /*#__PURE__*/React__default.createElement("nav", _extends({
248
248
  className: classNames,
249
249
  ref: ref
@@ -259,7 +259,7 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
259
259
  }),
260
260
  // render first item if at least 5 items can be displayed or
261
261
  // 4 items can be displayed and the current page is either 0 or 1
262
- (itemsThatFit >= 5 || itemsThatFit <= 4 && currentPage <= 1) && /*#__PURE__*/React__default.createElement(PaginationItem, {
262
+ (itemsDisplayedOnPage >= 5 || itemsDisplayedOnPage <= 4 && currentPage <= 1) && /*#__PURE__*/React__default.createElement(PaginationItem, {
263
263
  page: 1,
264
264
  translateWithId: t,
265
265
  isActive: currentPage === 0,
@@ -401,6 +401,5 @@ PaginationNav.propTypes = {
401
401
  */
402
402
  translateWithId: PropTypes.func
403
403
  };
404
- var PaginationNav$1 = PaginationNav;
405
404
 
406
- export { PaginationNav$1 as default };
405
+ export { PaginationNav as default };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright IBM Corp. 2020
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import PaginationNav from './PaginationNav';
8
+ export default PaginationNav;
9
+ export { PaginationNav };
@@ -228,7 +228,8 @@ function TabList(_ref2) {
228
228
  function onKeyDown(event) {
229
229
  if (matches(event, [ArrowRight, ArrowLeft, Home, End])) {
230
230
  event.preventDefault();
231
- const activeTabs = tabs.current.filter(tab => !tab.disabled);
231
+ const filtredTabs = tabs.current.filter(tab => tab !== null);
232
+ const activeTabs = filtredTabs.filter(tab => !tab.disabled);
232
233
  const currentIndex = activeTabs.indexOf(tabs.current[activation === 'automatic' ? selectedIndex : activeIndex]);
233
234
  const nextIndex = tabs.current.indexOf(activeTabs[getNextIndex(event, activeTabs.length, currentIndex)]);
234
235
  if (activation === 'automatic') {
@@ -180,11 +180,11 @@ export interface TileAboveTheFoldContentProps {
180
180
  */
181
181
  children?: ReactNode;
182
182
  }
183
- export declare const TileAboveTheFoldContent: React.ForwardRefExoticComponent<TileAboveTheFoldContentProps & React.RefAttributes<HTMLSpanElement>>;
183
+ export declare const TileAboveTheFoldContent: React.ForwardRefExoticComponent<TileAboveTheFoldContentProps & React.RefAttributes<HTMLDivElement>>;
184
184
  export interface TileBelowTheFoldContentProps {
185
185
  /**
186
186
  * The child nodes.
187
187
  */
188
188
  children?: ReactNode;
189
189
  }
190
- export declare const TileBelowTheFoldContent: React.ForwardRefExoticComponent<TileBelowTheFoldContentProps & React.RefAttributes<HTMLSpanElement>>;
190
+ export declare const TileBelowTheFoldContent: React.ForwardRefExoticComponent<TileBelowTheFoldContentProps & React.RefAttributes<HTMLDivElement>>;
@@ -604,7 +604,7 @@ const TileAboveTheFoldContent = /*#__PURE__*/React__default.forwardRef(function
604
604
  children
605
605
  } = _ref5;
606
606
  const prefix = usePrefix();
607
- return /*#__PURE__*/React__default.createElement("span", {
607
+ return /*#__PURE__*/React__default.createElement("div", {
608
608
  ref: ref,
609
609
  className: `${prefix}--tile-content__above-the-fold`
610
610
  }, children);
@@ -621,7 +621,7 @@ const TileBelowTheFoldContent = /*#__PURE__*/React__default.forwardRef(function
621
621
  children
622
622
  } = _ref6;
623
623
  const prefix = usePrefix();
624
- return /*#__PURE__*/React__default.createElement("span", {
624
+ return /*#__PURE__*/React__default.createElement("div", {
625
625
  ref: ref,
626
626
  className: `${prefix}--tile-content__below-the-fold`
627
627
  }, children);
package/es/index.js CHANGED
@@ -72,6 +72,7 @@ export { default as OrderedList } from './components/OrderedList/OrderedList.js'
72
72
  export { default as OverflowMenu } from './components/OverflowMenu/index.js';
73
73
  export { default as OverflowMenuItem } from './components/OverflowMenuItem/OverflowMenuItem.js';
74
74
  export { default as PaginationSkeleton } from './components/Pagination/Pagination.Skeleton.js';
75
+ export { default as PaginationNav } from './components/PaginationNav/PaginationNav.js';
75
76
  export { default as PrimaryButton } from './components/PrimaryButton/PrimaryButton.js';
76
77
  export { default as ProgressIndicatorSkeleton } from './components/ProgressIndicator/ProgressIndicator.Skeleton.js';
77
78
  export { ProgressIndicator, ProgressStep } from './components/ProgressIndicator/ProgressIndicator.js';
@@ -218,7 +219,6 @@ export { default as TableToolbarMenu } from './components/DataTable/TableToolbar
218
219
  export { default as FilterableMultiSelect } from './components/MultiSelect/FilterableMultiSelect.js';
219
220
  export { default as MultiSelect } from './components/MultiSelect/MultiSelect.js';
220
221
  export { default as Pagination } from './components/Pagination/Pagination.js';
221
- export { default as PaginationNav } from './components/PaginationNav/PaginationNav.js';
222
222
  export { default as ControlledPasswordInput } from './components/TextInput/ControlledPasswordInput.js';
223
223
  export { default as PasswordInput } from './components/TextInput/PasswordInput.js';
224
224
  export { default as RadioTile } from './components/RadioTile/RadioTile.js';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import PropTypes from 'prop-types';
8
+ import React from 'react';
9
+ interface AiSkeletonIconProps {
10
+ /**
11
+ * Specify an optional className to add.
12
+ */
13
+ className?: string;
14
+ /**
15
+ * The CSS styles.
16
+ */
17
+ style?: React.CSSProperties;
18
+ }
19
+ declare const AiSkeletonIcon: {
20
+ ({ className, ...rest }: AiSkeletonIconProps): import("react/jsx-runtime").JSX.Element;
21
+ propTypes: {
22
+ /**
23
+ * Specify an optional className to add.
24
+ */
25
+ className: PropTypes.Requireable<string>;
26
+ /**
27
+ * The CSS styles.
28
+ */
29
+ style: PropTypes.Requireable<object>;
30
+ };
31
+ };
32
+ export default AiSkeletonIcon;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import PropTypes from 'prop-types';
8
+ export interface AiSkeletonPlaceholderProps {
9
+ /**
10
+ * Add a custom class to the component to set the height and width
11
+ */
12
+ className?: string;
13
+ }
14
+ declare const AiSkeletonPlaceholder: {
15
+ ({ className, ...other }: AiSkeletonPlaceholderProps): import("react/jsx-runtime").JSX.Element;
16
+ propTypes: {
17
+ /**
18
+ * Add a custom class to the component
19
+ * to set the height and width
20
+ */
21
+ className: PropTypes.Requireable<string>;
22
+ };
23
+ };
24
+ export default AiSkeletonPlaceholder;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import PropTypes from 'prop-types';
8
+ interface AiSkeletonTextProps {
9
+ /**
10
+ * Specify an optional className to be applied to the container node.
11
+ */
12
+ className?: string;
13
+ /**
14
+ * Generates skeleton text at a larger size.
15
+ */
16
+ heading?: boolean;
17
+ /**
18
+ * The number of lines shown if paragraph is true.
19
+ */
20
+ lineCount?: number;
21
+ /**
22
+ * Set this to true to generate multiple lines of text.
23
+ */
24
+ paragraph?: boolean;
25
+ /**
26
+ * Width (in px or %) of single line of text or max-width of paragraph lines.
27
+ */
28
+ width?: string;
29
+ }
30
+ declare const AiSkeletonText: {
31
+ ({ className, ...rest }: AiSkeletonTextProps): import("react/jsx-runtime").JSX.Element;
32
+ propTypes: {
33
+ /**
34
+ * Specify an optional className to be applied to the container node
35
+ */
36
+ className: PropTypes.Requireable<string>;
37
+ /**
38
+ * generates skeleton text at a larger size
39
+ */
40
+ heading: PropTypes.Requireable<boolean>;
41
+ /**
42
+ * the number of lines shown if paragraph is true
43
+ */
44
+ lineCount: PropTypes.Requireable<number>;
45
+ /**
46
+ * will generate multiple lines of text
47
+ */
48
+ paragraph: PropTypes.Requireable<boolean>;
49
+ /**
50
+ * width (in px or %) of single line of text or max-width of paragraph lines
51
+ */
52
+ width: PropTypes.Requireable<string>;
53
+ };
54
+ };
55
+ export default AiSkeletonText;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import AiSkeletonPlaceholder from './AiSkeletonPlaceholder';
8
+ import AiSkeletonIcon from './AiSkeletonIcon';
9
+ import AiSkeletonText from './AiSkeletonText';
10
+ export { AiSkeletonText, AiSkeletonIcon, AiSkeletonPlaceholder };
@@ -15,6 +15,9 @@ var reactIs = require('react-is');
15
15
  var PropTypes = require('prop-types');
16
16
  var ModalHeader = require('./ModalHeader.js');
17
17
  var ModalFooter = require('./ModalFooter.js');
18
+ var debounce = require('lodash.debounce');
19
+ var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
20
+ var mergeRefs = require('../../tools/mergeRefs.js');
18
21
  var cx = require('classnames');
19
22
  var toggleClass = require('../../tools/toggleClass.js');
20
23
  var requiredIfGivenPropIsTruthy = require('../../prop-types/requiredIfGivenPropIsTruthy.js');
@@ -27,6 +30,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
27
30
 
28
31
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
29
32
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
33
+ var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
30
34
  var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
31
35
 
32
36
  const ModalBody = /*#__PURE__*/React__default["default"].forwardRef(function ModalBody(_ref, ref) {
@@ -38,18 +42,39 @@ const ModalBody = /*#__PURE__*/React__default["default"].forwardRef(function Mod
38
42
  ...rest
39
43
  } = _ref;
40
44
  const prefix = usePrefix.usePrefix();
41
- const contentClass = cx__default["default"](`${prefix}--modal-content`, hasForm && `${prefix}--modal-content--with-form`, hasScrollingContent && `${prefix}--modal-scroll-content`, customClassName);
42
- const hasScrollingContentProps = hasScrollingContent ? {
45
+ const contentRef = React.useRef(null);
46
+ const [isScrollable, setIsScrollable] = React.useState(false);
47
+ const contentClass = cx__default["default"]({
48
+ [`${prefix}--modal-content`]: true,
49
+ [`${prefix}--modal-content--with-form`]: hasForm,
50
+ [`${prefix}--modal-scroll-content`]: hasScrollingContent || isScrollable,
51
+ customClassName
52
+ });
53
+ useIsomorphicEffect["default"](() => {
54
+ if (contentRef.current) {
55
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
56
+ }
57
+ function handler() {
58
+ if (contentRef.current) {
59
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
60
+ }
61
+ }
62
+ const debouncedHandler = debounce__default["default"](handler, 200);
63
+ window.addEventListener('resize', debouncedHandler);
64
+ return () => {
65
+ debouncedHandler.cancel();
66
+ window.removeEventListener('resize', debouncedHandler);
67
+ };
68
+ }, []);
69
+ const hasScrollingContentProps = hasScrollingContent || isScrollable ? {
43
70
  tabIndex: 0,
44
71
  role: 'region'
45
72
  } : {};
46
- return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
73
+ return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
47
74
  className: contentClass
48
75
  }, hasScrollingContentProps, rest, {
49
- ref: ref
50
- }), children), hasScrollingContent && /*#__PURE__*/React__default["default"].createElement("div", {
51
- className: `${prefix}--modal-content--overflow-indicator`
52
- }));
76
+ ref: mergeRefs["default"](contentRef, ref)
77
+ }), children);
53
78
  });
54
79
  ModalBody.propTypes = {
55
80
  /**
@@ -52,7 +52,7 @@ function Copy(_ref) {
52
52
  handleFadeOut();
53
53
  }, [handleFadeOut]);
54
54
  const handleAnimationEnd = event => {
55
- if (event.animationName === 'hide-feedback') {
55
+ if (event.animationName === `${prefix}--hide-feedback`) {
56
56
  setAnimation('');
57
57
  }
58
58
  };
@@ -53,7 +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
+ slug?: React.ReactElement;
57
57
  }
58
58
  export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
59
59
  headers: Array<DataTableHeader>;
@@ -341,7 +341,7 @@ declare class DataTable<RowType, ColTypes extends any[]> extends React.Component
341
341
  sortDirection: DataTableSortState;
342
342
  isSortable: boolean | undefined;
343
343
  isSortHeader: boolean;
344
- slug: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
344
+ slug: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
345
345
  onClick: (event: any) => void;
346
346
  };
347
347
  /**
@@ -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;
@@ -58,7 +58,7 @@ const TableToolbarSearch = _ref => {
58
58
  const {
59
59
  current: controlled
60
60
  } = React.useRef(expandedProp !== undefined);
61
- const [expandedState, setExpandedState] = React.useState(defaultExpanded || defaultValue);
61
+ const [expandedState, setExpandedState] = React.useState(Boolean(defaultExpanded || defaultValue));
62
62
  const expanded = controlled ? expandedProp : expandedState;
63
63
  const [value, setValue] = React.useState(defaultValue || '');
64
64
  const uniqueId = React.useMemo(getInstanceId, []);
@@ -21,6 +21,8 @@ var ButtonSet = require('../ButtonSet/ButtonSet.js');
21
21
  var InlineLoading = require('../InlineLoading/InlineLoading.js');
22
22
  var requiredIfGivenPropIsTruthy = require('../../prop-types/requiredIfGivenPropIsTruthy.js');
23
23
  var wrapFocus = require('../../internal/wrapFocus.js');
24
+ var debounce = require('lodash.debounce');
25
+ var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
24
26
  var setupGetInstanceId = require('../../tools/setupGetInstanceId.js');
25
27
  var usePrefix = require('../../internal/usePrefix.js');
26
28
  var index = require('../IconButton/index.js');
@@ -35,6 +37,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
35
37
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
36
38
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
37
39
  var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
40
+ var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
38
41
 
39
42
  const getInstanceId = setupGetInstanceId["default"]();
40
43
  const ModalSizes = ['xs', 'sm', 'md', 'lg'];
@@ -76,9 +79,11 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
76
79
  const prefix = usePrefix.usePrefix();
77
80
  const button = React.useRef(null);
78
81
  const secondaryButton = React.useRef();
82
+ const contentRef = React.useRef(null);
79
83
  const innerModal = React.useRef(null);
80
84
  const startTrap = React.useRef(null);
81
85
  const endTrap = React.useRef(null);
86
+ const [isScrollable, setIsScrollable] = React.useState(false);
82
87
  const modalInstanceId = `modal-${getInstanceId()}`;
83
88
  const modalLabelId = `${prefix}--modal-header__label--${modalInstanceId}`;
84
89
  const modalHeadingId = `${prefix}--modal-header__heading--${modalInstanceId}`;
@@ -144,7 +149,7 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
144
149
  [`${prefix}--modal-container--full-width`]: isFullWidth
145
150
  });
146
151
  const contentClasses = cx__default["default"](`${prefix}--modal-content`, {
147
- [`${prefix}--modal-scroll-content`]: hasScrollingContent
152
+ [`${prefix}--modal-scroll-content`]: hasScrollingContent || isScrollable
148
153
  });
149
154
  const footerClasses = cx__default["default"](`${prefix}--modal-footer`, {
150
155
  [`${prefix}--modal-footer--three-button`]: Array.isArray(secondaryButtons) && secondaryButtons.length === 2
@@ -156,7 +161,7 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
156
161
  const modalHeadingStr = asStringOrUndefined(modalHeading);
157
162
  const ariaLabel = modalLabelStr || ariaLabelProp || modalAriaLabel || modalHeadingStr;
158
163
  const getAriaLabelledBy = modalLabel ? modalLabelId : modalHeadingId;
159
- const hasScrollingContentProps = hasScrollingContent ? {
164
+ const hasScrollingContentProps = hasScrollingContent || isScrollable ? {
160
165
  tabIndex: 0,
161
166
  role: 'region',
162
167
  'aria-label': ariaLabel,
@@ -204,6 +209,22 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
204
209
  focusButton(innerModal.current);
205
210
  }
206
211
  }, [open, selectorPrimaryFocus, danger, prefix]);
212
+ useIsomorphicEffect["default"](() => {
213
+ if (contentRef.current) {
214
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
215
+ }
216
+ function handler() {
217
+ if (contentRef.current) {
218
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
219
+ }
220
+ }
221
+ const debouncedHandler = debounce__default["default"](handler, 200);
222
+ window.addEventListener('resize', debouncedHandler);
223
+ return () => {
224
+ debouncedHandler.cancel();
225
+ window.removeEventListener('resize', debouncedHandler);
226
+ };
227
+ }, []);
207
228
 
208
229
  // Slug is always size `lg`
209
230
  let normalizedSlug;
@@ -247,11 +268,10 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
247
268
  id: modalHeadingId,
248
269
  className: `${prefix}--modal-header__heading`
249
270
  }, modalHeading), normalizedSlug, !passiveModal && modalButton), /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
271
+ ref: contentRef,
250
272
  id: modalBodyId,
251
273
  className: contentClasses
252
- }, hasScrollingContentProps), children), hasScrollingContent && /*#__PURE__*/React__default["default"].createElement("div", {
253
- className: `${prefix}--modal-content--overflow-indicator`
254
- }), !passiveModal && /*#__PURE__*/React__default["default"].createElement(ButtonSet["default"], {
274
+ }, hasScrollingContentProps), children), !passiveModal && /*#__PURE__*/React__default["default"].createElement(ButtonSet["default"], {
255
275
  className: footerClasses,
256
276
  "aria-busy": loadingActive
257
277
  }, Array.isArray(secondaryButtons) && secondaryButtons.length <= 2 ? secondaryButtons.map((_ref3, i) => {
@@ -51,6 +51,10 @@ interface MultiSelectSortingProps<ItemType> {
51
51
  }
52
52
  export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<ItemType>, InternationalProps<'close.menu' | 'open.menu' | 'clear.all' | 'clear.selection'> {
53
53
  className?: string;
54
+ /**
55
+ * Specify the text that should be read for screen readers that describes that all items are deleted
56
+ */
57
+ clearAnnouncement?: string;
54
58
  /**
55
59
  * Specify the text that should be read for screen readers that describes total items selected
56
60
  */