@carbon/ibm-products 2.67.0-rc.0 → 2.68.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 (75) hide show
  1. package/css/index-full-carbon.css +252 -261
  2. package/css/index-full-carbon.css.map +1 -1
  3. package/css/index-full-carbon.min.css +1 -1
  4. package/css/index-full-carbon.min.css.map +1 -1
  5. package/css/index-without-carbon-released-only.css +13 -31
  6. package/css/index-without-carbon-released-only.css.map +1 -1
  7. package/css/index-without-carbon-released-only.min.css +1 -1
  8. package/css/index-without-carbon-released-only.min.css.map +1 -1
  9. package/css/index-without-carbon.css +252 -261
  10. package/css/index-without-carbon.css.map +1 -1
  11. package/css/index-without-carbon.min.css +1 -1
  12. package/css/index-without-carbon.min.css.map +1 -1
  13. package/css/index.css +26 -35
  14. package/css/index.css.map +1 -1
  15. package/css/index.min.css +1 -1
  16. package/css/index.min.css.map +1 -1
  17. package/es/components/Carousel/Carousel.d.ts +6 -0
  18. package/es/components/Carousel/Carousel.js +45 -0
  19. package/es/components/CreateFullPage/CreateFullPage.d.ts +3 -2
  20. package/es/components/Datagrid/Datagrid/DraggableElement.d.ts +3 -0
  21. package/es/components/Datagrid/Datagrid/DraggableElement.js +23 -15
  22. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.d.ts +16 -20
  23. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.js +3 -5
  24. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/Columns.js +1 -3
  25. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.d.ts +2 -1
  26. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js +2 -0
  27. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/DraggableItemsList.js +4 -11
  28. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.d.ts +2 -1
  29. package/es/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.js +3 -1
  30. package/es/components/Datagrid/useCustomizeColumns.js +29 -22
  31. package/es/components/Guidebanner/Guidebanner.js +2 -1
  32. package/es/components/InterstitialScreen/InterstitialScreen.d.ts +4 -0
  33. package/es/components/InterstitialScreen/InterstitialScreen.js +16 -4
  34. package/es/components/InterstitialScreen/InterstitialScreenBody.js +7 -7
  35. package/es/components/InterstitialScreen/InterstitialScreenFooter.js +8 -1
  36. package/es/components/InterstitialScreen/InterstitialScreenHeader.js +10 -4
  37. package/es/components/PageHeader/PageHeaderUtils.js +2 -1
  38. package/es/components/Tearsheet/TearsheetShell.js +0 -1
  39. package/es/global/js/hooks/useResizeObserver.d.ts +8 -1
  40. package/es/global/js/hooks/useResizeObserver.js +12 -13
  41. package/lib/components/Carousel/Carousel.d.ts +6 -0
  42. package/lib/components/Carousel/Carousel.js +45 -0
  43. package/lib/components/CreateFullPage/CreateFullPage.d.ts +3 -2
  44. package/lib/components/Datagrid/Datagrid/DraggableElement.d.ts +3 -0
  45. package/lib/components/Datagrid/Datagrid/DraggableElement.js +23 -15
  46. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.d.ts +16 -20
  47. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/ButtonWrapper.js +3 -5
  48. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/Columns.js +1 -3
  49. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.d.ts +2 -1
  50. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/CustomizeColumnsTearsheet.js +2 -0
  51. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/DraggableItemsList.js +4 -11
  52. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.d.ts +2 -1
  53. package/lib/components/Datagrid/Datagrid/addons/CustomizeColumns/TearsheetWrapper.js +3 -1
  54. package/lib/components/Datagrid/useCustomizeColumns.js +29 -22
  55. package/lib/components/Guidebanner/Guidebanner.js +2 -1
  56. package/lib/components/InterstitialScreen/InterstitialScreen.d.ts +4 -0
  57. package/lib/components/InterstitialScreen/InterstitialScreen.js +15 -3
  58. package/lib/components/InterstitialScreen/InterstitialScreenBody.js +7 -7
  59. package/lib/components/InterstitialScreen/InterstitialScreenFooter.js +7 -0
  60. package/lib/components/InterstitialScreen/InterstitialScreenHeader.js +9 -3
  61. package/lib/components/PageHeader/PageHeaderUtils.js +2 -1
  62. package/lib/components/Tearsheet/TearsheetShell.js +0 -1
  63. package/lib/global/js/hooks/useResizeObserver.d.ts +8 -1
  64. package/lib/global/js/hooks/useResizeObserver.js +12 -13
  65. package/package.json +5 -5
  66. package/scss/components/AboutModal/_about-modal.scss +3 -1
  67. package/scss/components/BreadcrumbWithOverflow/_breadcrumb-with-overflow.scss +0 -1
  68. package/scss/components/Carousel/_carousel.scss +5 -0
  69. package/scss/components/Datagrid/styles/_draggableElement.scss +14 -8
  70. package/scss/components/Datagrid/styles/addons/_CustomizeColumnsTearsheet.scss +0 -7
  71. package/scss/components/FilterSummary/_filter-summary.scss +0 -5
  72. package/scss/components/InterstitialScreen/_interstitial-screen.scss +2 -2
  73. package/scss/global/styles/_display-box.scss +1 -3
  74. package/telemetry.yml +1 -0
  75. package/scss/components/FilterSummary/_animations.scss +0 -20
@@ -7,24 +7,23 @@
7
7
 
8
8
  import { useState, useRef, useEffect, useLayoutEffect } from 'react';
9
9
 
10
- const useResizeObserver = function (ref, callback) {
11
- let deps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
10
+ const useResizeObserver = (ref, onResize) => {
12
11
  const [width, setWidth] = useState(-1);
13
12
  const [height, setHeight] = useState(-1);
14
13
  const entriesToHandle = useRef(null);
15
- const cb = useRef(callback);
14
+ const cb = useRef(onResize);
16
15
  useEffect(() => {
17
- // ref for callback removes it as dependency from useLayoutEffect
16
+ // ref for onResize removes it as dependency from useLayoutEffect
18
17
  // This significantly reduces repeated calls if a function is redefined on every
19
18
  // render
20
- cb.current = callback;
21
- }, [callback]);
19
+ cb.current = onResize;
20
+ }, [onResize]);
22
21
  useEffect(() => {
23
22
  const getInitialSize = () => {
24
23
  if (ref.current) {
25
24
  const refComputedStyle = window.getComputedStyle(ref.current);
26
- const initialWidth = (ref.current?.offsetWidth || 0) - (parseFloat(refComputedStyle?.paddingLeft || 0), parseFloat(refComputedStyle?.paddingRight || 0));
27
- const initialHeight = (ref.current?.offsetHeight || 0) - (parseFloat(refComputedStyle?.paddingTop || 0), parseFloat(refComputedStyle?.paddingLeft || 0));
25
+ const initialWidth = (ref.current?.offsetWidth ?? 0) - (typeof refComputedStyle?.paddingLeft === 'string' && refComputedStyle?.paddingLeft.length ? parseFloat(refComputedStyle?.paddingLeft) : 0) - (typeof refComputedStyle?.paddingRight === 'string' && refComputedStyle?.paddingRight.length ? parseFloat(refComputedStyle?.paddingRight) : 0);
26
+ const initialHeight = (ref.current?.offsetHeight ?? 0) - (typeof refComputedStyle?.paddingTop === 'string' && refComputedStyle?.paddingTop.length ? parseFloat(refComputedStyle?.paddingTop) : 0) - (typeof refComputedStyle?.paddingBottom === 'string' && refComputedStyle?.paddingBottom.length ? parseFloat(refComputedStyle?.paddingBottom) : 0);
28
27
  setWidth(initialWidth);
29
28
  setHeight(initialHeight);
30
29
  }
@@ -33,8 +32,9 @@ const useResizeObserver = function (ref, callback) {
33
32
  return;
34
33
  }
35
34
  getInitialSize();
35
+ // Ignoring exhaustive-deps as we do NOT want to include the ref in dep array
36
36
  // eslint-disable-next-line react-hooks/exhaustive-deps
37
- }, [width, height, ref.current, ...deps]);
37
+ }, [width, height]);
38
38
  useLayoutEffect(() => {
39
39
  if (!ref?.current) {
40
40
  return;
@@ -48,7 +48,7 @@ const useResizeObserver = function (ref, callback) {
48
48
  setHeight(entry.contentRect.height);
49
49
  cb.current && cb.current(entry.contentRect);
50
50
  };
51
- let observer = new ResizeObserver(entries => {
51
+ const observer = new ResizeObserver(entries => {
52
52
  // always update entriesToHandle
53
53
  entriesToHandle.current = entries;
54
54
  window.requestAnimationFrame(() => {
@@ -60,11 +60,10 @@ const useResizeObserver = function (ref, callback) {
60
60
  // observe all refs passed
61
61
  observer.observe(ref.current);
62
62
  return () => {
63
- observer?.disconnect();
64
- observer = null;
63
+ observer.disconnect();
65
64
  };
66
65
  // eslint-disable-next-line react-hooks/exhaustive-deps
67
- }, [ref.current, ...deps]);
66
+ }, [ref.current]);
68
67
  return {
69
68
  width,
70
69
  height
@@ -45,6 +45,12 @@ export interface CarouselProps {
45
45
  * Additional props passed to the component.
46
46
  */
47
47
  [key: string]: any;
48
+ /**
49
+ * enable scroll mode when only scroll functionality is required, more than one items will be visible at a time
50
+ * when isScrollMode is false, component behaves like a carousal and on item will be active at a time
51
+ * and other items will be hidden and inactive.
52
+ */
53
+ isScrollMode?: boolean;
48
54
  }
49
55
  /**
50
56
  * The Carousel acts as a scaffold for other Onboarding content.
@@ -14,6 +14,7 @@ var CarouselItem = require('./CarouselItem.js');
14
14
  var cx = require('classnames');
15
15
  var devtools = require('../../global/js/utils/devtools.js');
16
16
  var settings = require('../../settings.js');
17
+ var react = require('@carbon/react');
17
18
  var useIsomorphicEffect = require('../../global/js/hooks/useIsomorphicEffect.js');
18
19
 
19
20
  // The block part of our conventional BEM class names (blockClass__E--M).
@@ -51,6 +52,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
51
52
  fadedEdgeColor,
52
53
  onChangeIsScrollable = defaults.onChangeIsScrollable,
53
54
  onScroll = defaults.onScroll,
55
+ isScrollMode = false,
54
56
  ...rest
55
57
  } = props;
56
58
  const carouselRef = React.useRef(null);
@@ -61,6 +63,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
61
63
  const childElementsRef = React.useRef(Array(React.Children.count(children)).fill(React.useRef(null)));
62
64
  const leftFadedEdgeColor = typeof fadedEdgeColor === 'object' ? fadedEdgeColor?.left : fadedEdgeColor;
63
65
  const rightFadedEdgeColor = typeof fadedEdgeColor === 'object' ? fadedEdgeColor?.right : fadedEdgeColor;
66
+ const carbonPrefix = react.usePrefix();
64
67
 
65
68
  // Trigger callbacks to report state of the carousel
66
69
  const handleOnScroll = React.useCallback(() => {
@@ -158,8 +161,42 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
158
161
  handleOnScroll();
159
162
  }, [handleOnScroll]);
160
163
  const handleScrollToView = React.useCallback(itemNumber => {
164
+ updateAriaHiddenTabIndex(itemNumber);
161
165
  childElementsRef.current[itemNumber].scrollIntoView();
166
+ // eslint-disable-next-line react-hooks/exhaustive-deps
162
167
  }, []);
168
+ const getFocusableElements = container => {
169
+ const notQuery = `:not(.${carbonPrefix}--visually-hidden,.${carbonPrefix}--btn--disabled,[aria-hidden="true"],[disabled])`;
170
+ // Queries to include element types button, input, select, textarea
171
+ const queryButton = `button${notQuery}`;
172
+ const queryInput = `input${notQuery}`;
173
+ const querySelect = `select${notQuery}`;
174
+ const queryTextarea = `textarea${notQuery}`;
175
+ const queryLink = `[href]${notQuery}`;
176
+ const queryAnchor = `a${notQuery}`;
177
+ const queryTabIndex = `[tabindex="0"]${notQuery}`;
178
+ // Final query
179
+ const query = `${queryButton},${queryLink},${queryAnchor},${queryInput},${querySelect},${queryTextarea},${queryTabIndex}`;
180
+ return container?.querySelectorAll(`${query}`) ?? [];
181
+ };
182
+ const updateAriaHiddenTabIndex = itemNumber => {
183
+ //aria-hidden need to updated based on the active item, otherwise screen reader will reset to first item while
184
+ //interact with element via Control + Option + Down Arrow
185
+ // aria-hidden is set to true to inactive carousal items
186
+ // tab-index is set to -1 for all inputs in in active elements
187
+
188
+ !isScrollMode && childElementsRef.current?.forEach((item, idx) => {
189
+ const isActive = idx === itemNumber;
190
+ // Set aria-hidden based on active state
191
+ item?.setAttribute('aria-hidden', String(!isActive));
192
+
193
+ // Update tabIndex for all focusable elements within the item
194
+ const focusableElements = getFocusableElements(item);
195
+ focusableElements.forEach(el => {
196
+ el.tabIndex = isActive ? 0 : -1;
197
+ });
198
+ });
199
+ };
163
200
 
164
201
  // Trigger a callback after first render (and applied CSS).
165
202
  React.useEffect(() => {
@@ -170,6 +207,8 @@ const Carousel = /*#__PURE__*/React.forwardRef((props, ref) => {
170
207
  setTimeout(() => {
171
208
  // But, because we are making calculations based on the final,
172
209
  // applied CSS, we must wait for one more "tick".
210
+
211
+ updateAriaHiddenTabIndex(0);
173
212
  handleOnScroll();
174
213
  }, 0);
175
214
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -318,6 +357,12 @@ Carousel.propTypes = {
318
357
  left: index.default.string,
319
358
  right: index.default.string
320
359
  })]),
360
+ /**
361
+ * enable scroll mode when only scroll functionality is required, more than one items will be visible at a time
362
+ * when isScrollMode is false, component behaves like a carousal and on item will be active at a time
363
+ * and other items will be hidden and inactive.
364
+ */
365
+ isScrollMode: index.default.bool,
321
366
  /**
322
367
  * An optional callback function that returns `true`
323
368
  * when the carousel has enough content to be scrollable,
@@ -20,6 +20,7 @@ interface HeaderBreadcrumb {
20
20
  /** Provide if this breadcrumb item represents the current page */
21
21
  isCurrentPage?: boolean;
22
22
  }
23
+ type MaybePromise<T> = Promise<T> | T;
23
24
  type CreateFullPageBreadcrumbsProps = {
24
25
  /** The header breadcrumbs */
25
26
  breadcrumbs?: null | undefined;
@@ -107,9 +108,9 @@ type CreateFullPageBaseProps = {
107
108
  *
108
109
  * @returns Object - if you want to prevent the modal from closing, return an object with the property preventClose set to true
109
110
  */
110
- onRequestSubmit: () => {
111
+ onRequestSubmit: () => MaybePromise<{
111
112
  preventClose?: boolean;
112
- } | void;
113
+ } | void>;
113
114
  /**
114
115
  * A secondary title of the full page, displayed in the influencer area
115
116
  */
@@ -15,6 +15,9 @@ interface DraggableElementProps extends PropsWithChildren {
15
15
  isSticky?: boolean;
16
16
  selected?: boolean;
17
17
  }
18
+ /**
19
+ * Single row in the DraggableItemsList used by CustomizeColumnsTearsheet.
20
+ */
18
21
  declare const DraggableElement: {
19
22
  ({ id, elementId, children, classList, disabled, ariaLabel, isSticky, selected, }: DraggableElementProps): React.JSX.Element;
20
23
  propTypes: {
@@ -20,6 +20,9 @@ var sortable = require('@dnd-kit/sortable');
20
20
 
21
21
  var _Locked, _DraggableIcon;
22
22
  const blockClass = `${settings.pkg.prefix}--datagrid`;
23
+ /**
24
+ * Single row in the DraggableItemsList used by CustomizeColumnsTearsheet.
25
+ */
23
26
  const DraggableElement = _ref => {
24
27
  let {
25
28
  id,
@@ -42,20 +45,33 @@ const DraggableElement = _ref => {
42
45
  disabled,
43
46
  id
44
47
  });
45
- const content = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
48
+
49
+ // Most of the attributes (ex: role, tabIndex, aria-disabled) are unnecessary for a <button>, so just get the ones we need.
50
+ const {
51
+ 'aria-pressed': ariaPressed,
52
+ 'aria-describedby': ariaDescribedby
53
+ } = attributes;
54
+ const dragHandle = isSticky ? /*#__PURE__*/React.createElement("div", {
46
55
  className: cx({
47
56
  disabled
48
57
  }, `${blockClass}__draggable-handleStyle`)
49
- }, isSticky ? _Locked || (_Locked = /*#__PURE__*/React.createElement(icons.Locked, {
58
+ }, _Locked || (_Locked = /*#__PURE__*/React.createElement(icons.Locked, {
50
59
  size: 16
51
- })) : _DraggableIcon || (_DraggableIcon = /*#__PURE__*/React.createElement(icons.Draggable, {
60
+ })), ' ') : /*#__PURE__*/React.createElement("button", _rollupPluginBabelHelpers.extends({
61
+ className: `${blockClass}__draggable-handleStyle`,
62
+ type: "button",
63
+ "aria-label": ariaLabel,
64
+ "aria-describedby": ariaDescribedby,
65
+ "aria-pressed": ariaPressed
66
+ }, listeners), _DraggableIcon || (_DraggableIcon = /*#__PURE__*/React.createElement(icons.Draggable, {
52
67
  size: 16
53
- }))), children);
68
+ })));
69
+ const content = /*#__PURE__*/React.createElement(React.Fragment, null, dragHandle, children);
54
70
  const style = {
55
71
  transform: !disabled ? utilities.CSS.Transform.toString(transform) : undefined,
56
72
  transition
57
73
  };
58
- return /*#__PURE__*/React.createElement("li", _rollupPluginBabelHelpers.extends({
74
+ return /*#__PURE__*/React.createElement("li", {
59
75
  className: cx(classList, `${blockClass}__draggable-handleHolder`, {
60
76
  [`${blockClass}__draggable-handleHolder--selected`]: selected,
61
77
  [`${blockClass}__draggable-handleHolder--sticky`]: isSticky,
@@ -64,16 +80,8 @@ const DraggableElement = _ref => {
64
80
  id: elementId ? elementId : id,
65
81
  ref: setNodeRef,
66
82
  style: style
67
- }, attributes, listeners, {
68
- "aria-disabled": undefined,
69
- "aria-selected": selected,
70
- role: "option"
71
- }), /*#__PURE__*/React.createElement("span", {
72
- className: `${blockClass}__shared-ui--assistive-text`
73
- }, ariaLabel), /*#__PURE__*/React.createElement("div", {
74
- className: cx({
75
- [`${blockClass}__draggable-handleStyle`]: !disabled
76
- }, [`${blockClass}__draggable-handleHolder-droppable`])
83
+ }, /*#__PURE__*/React.createElement("div", {
84
+ className: cx([`${blockClass}__draggable-handleHolder-droppable`])
77
85
  }, content));
78
86
  };
79
87
  DraggableElement.propTypes = {
@@ -1,21 +1,17 @@
1
- export default ButtonWrapper;
2
- declare function ButtonWrapper({ onClick, setIsTearsheetOpen, isTearsheetOpen, iconTooltipLabel, ...rest }: {
3
- [x: string]: any;
4
- onClick: any;
5
- setIsTearsheetOpen: any;
6
- isTearsheetOpen: any;
7
- iconTooltipLabel?: string | undefined;
8
- }): React.JSX.Element;
9
- declare namespace ButtonWrapper {
10
- namespace defaultProps {
11
- function onClick(): void;
12
- }
13
- namespace propTypes {
14
- export let iconTooltipLabel: any;
15
- export let isTearsheetOpen: any;
16
- let onClick_1: any;
17
- export { onClick_1 as onClick };
18
- export let setIsTearsheetOpen: any;
19
- }
20
- }
1
+ /**
2
+ * Copyright IBM Corp. 2022, 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
+ */
21
7
  import * as React from 'react';
8
+ import { Button } from '@carbon/react';
9
+ import { ComponentProps } from 'react';
10
+ interface ButtonWrapperProps extends ComponentProps<typeof Button> {
11
+ isTearsheetOpen: boolean;
12
+ iconTooltipLabel?: string;
13
+ onClick?: () => void;
14
+ setIsTearsheetOpen: (open: boolean) => void;
15
+ }
16
+ declare const ButtonWrapper: React.ForwardRefExoticComponent<ButtonWrapperProps & React.RefAttributes<HTMLButtonElement>>;
17
+ export default ButtonWrapper;
@@ -36,7 +36,7 @@ function _interopNamespaceDefault(e) {
36
36
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
37
37
 
38
38
  const blockClass = `${settings.pkg.prefix}--datagrid`;
39
- const ButtonWrapper = _ref => {
39
+ const ButtonWrapper = /*#__PURE__*/React__namespace.forwardRef((_ref, ref) => {
40
40
  let {
41
41
  onClick,
42
42
  setIsTearsheetOpen,
@@ -53,6 +53,7 @@ const ButtonWrapper = _ref => {
53
53
  kind: "ghost",
54
54
  hasIconOnly: true,
55
55
  "test-id": `${blockClass}__customize-columns-trigger`,
56
+ ref: ref,
56
57
  onClick: () => {
57
58
  setIsTearsheetOpen(!isTearsheetOpen);
58
59
  if (typeof onClick === 'function') {
@@ -60,10 +61,7 @@ const ButtonWrapper = _ref => {
60
61
  }
61
62
  }
62
63
  }));
63
- };
64
- ButtonWrapper.defaultProps = {
65
- onClick: () => {}
66
- };
64
+ });
67
65
  ButtonWrapper.propTypes = {
68
66
  iconTooltipLabel: index.default.string,
69
67
  isTearsheetOpen: index.default.bool.isRequired,
@@ -49,10 +49,8 @@ const Columns = _ref => {
49
49
  ref: listRef
50
50
  }, /*#__PURE__*/React.createElement("ol", {
51
51
  className: `${blockClass}__customize-columns-column-list--focus`,
52
- role: "listbox",
53
52
  "aria-label": customizeTearsheetHeadingLabel,
54
- "aria-describedby": `${blockClass}__customize-columns--instructions`,
55
- tabIndex: 0
53
+ "aria-describedby": `${blockClass}__customize-columns--instructions`
56
54
  }, /*#__PURE__*/React.createElement("span", {
57
55
  "aria-live": "assertive",
58
56
  className: `${blockClass}__shared-ui--assistive-text`
@@ -1,7 +1,8 @@
1
1
  export default CustomizeColumnsTearsheet;
2
- declare function CustomizeColumnsTearsheet({ isOpen, setIsTearsheetOpen, onSaveColumnPrefs, columnDefinitions, originalColumnDefinitions, customizeTearsheetHeadingLabel, primaryButtonTextLabel, secondaryButtonTextLabel, instructionsLabel, findColumnPlaceholderLabel, resetToDefaultLabel, assistiveTextInstructionsLabel, assistiveTextDisabledInstructionsLabel, selectAllLabel, }: {
2
+ declare function CustomizeColumnsTearsheet({ isOpen, setIsTearsheetOpen, launcherButtonRef, onSaveColumnPrefs, columnDefinitions, originalColumnDefinitions, customizeTearsheetHeadingLabel, primaryButtonTextLabel, secondaryButtonTextLabel, instructionsLabel, findColumnPlaceholderLabel, resetToDefaultLabel, assistiveTextInstructionsLabel, assistiveTextDisabledInstructionsLabel, selectAllLabel, }: {
3
3
  isOpen: any;
4
4
  setIsTearsheetOpen: any;
5
+ launcherButtonRef: any;
5
6
  onSaveColumnPrefs: any;
6
7
  columnDefinitions: any;
7
8
  originalColumnDefinitions: any;
@@ -22,6 +22,7 @@ const CustomizeColumnsTearsheet = _ref => {
22
22
  let {
23
23
  isOpen,
24
24
  setIsTearsheetOpen,
25
+ launcherButtonRef,
25
26
  onSaveColumnPrefs,
26
27
  columnDefinitions,
27
28
  originalColumnDefinitions,
@@ -110,6 +111,7 @@ const CustomizeColumnsTearsheet = _ref => {
110
111
  open: isOpen,
111
112
  title: `${customizeTearsheetHeadingLabel} (${visibleColumnsCount}/${totalColumns})`,
112
113
  description: instructionsLabel,
114
+ launcherButtonRef: launcherButtonRef,
113
115
  actions: [{
114
116
  kind: 'secondary',
115
117
  label: secondaryButtonTextLabel,
@@ -150,10 +150,10 @@ const DraggableItemsList = _ref => {
150
150
  }, visibleCols.map(colDef => {
151
151
  const colHeaderTitle = getNodeTextContent.getNodeTextContent(colDef.Header);
152
152
  const parts = colHeaderTitle.split(new RegExp(`(${filterString})`, 'gi'));
153
- const highlightedText = parts.map(part => part.toLowerCase() === filterString.toLowerCase() ? `<strong>${part}</strong>` : part).join('');
153
+ const highlightedText = parts.map(part => part.toLowerCase() === filterString.toLowerCase() ? /*#__PURE__*/React.createElement("strong", null, part) : part);
154
154
  const isFrozenColumn = !!colDef.sticky;
155
155
  const isDisabled = colDef.disabled;
156
- const listContents = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(react.Checkbox, {
156
+ const listContents = /*#__PURE__*/React.createElement(react.Checkbox, {
157
157
  checked: common.isColumnVisible(colDef),
158
158
  disabled: isDisabled || isFrozenColumn,
159
159
  onChange: (_, _ref2) => {
@@ -163,17 +163,10 @@ const DraggableItemsList = _ref => {
163
163
  return onSelectColumn(colDef, checked);
164
164
  },
165
165
  id: `${blockClass}__customization-column-${colDef.id}`,
166
- labelText: colHeaderTitle,
167
- title: colHeaderTitle,
166
+ labelText: highlightedText,
168
167
  className: `${blockClass}__customize-columns-checkbox`,
169
- hideLabel: true,
170
168
  onKeyDown: event => handleCheckboxKeydown(event, colDef)
171
- }), /*#__PURE__*/React.createElement("div", {
172
- dangerouslySetInnerHTML: {
173
- __html: highlightedText
174
- },
175
- className: `${blockClass}__customize-columns-checkbox-visible-label`
176
- }));
169
+ });
177
170
  return /*#__PURE__*/React.createElement(DraggableElement.default, {
178
171
  classList: draggableClass,
179
172
  key: colDef.id,
@@ -1,6 +1,7 @@
1
1
  export default TearsheetWrapper;
2
- declare function TearsheetWrapper({ instance }: {
2
+ declare function TearsheetWrapper({ instance, launcherButtonRef }: {
3
3
  instance: any;
4
+ launcherButtonRef: any;
4
5
  }): React.JSX.Element;
5
6
  declare namespace TearsheetWrapper {
6
7
  namespace propTypes {
@@ -18,7 +18,8 @@ var InlineEditContext = require('../InlineEdit/InlineEditContext/InlineEditConte
18
18
 
19
19
  const TearsheetWrapper = _ref => {
20
20
  let {
21
- instance
21
+ instance,
22
+ launcherButtonRef
22
23
  } = _ref;
23
24
  const {
24
25
  onSaveColumnPrefs,
@@ -41,6 +42,7 @@ const TearsheetWrapper = _ref => {
41
42
  return /*#__PURE__*/React.createElement(CustomizeColumnsTearsheet.default, _rollupPluginBabelHelpers.extends({}, rest, labels, {
42
43
  isOpen: isTearsheetOpen,
43
44
  setIsTearsheetOpen: setIsTearsheetOpen,
45
+ launcherButtonRef: launcherButtonRef,
44
46
  columnDefinitions: instance.allColumns,
45
47
  originalColumnDefinitions: instance.columns,
46
48
  onSaveColumnPrefs: updatedColDefs => {
@@ -11,8 +11,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
11
11
 
12
12
  var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
13
13
  var React = require('react');
14
- var TearsheetWrapper = require('./Datagrid/addons/CustomizeColumns/TearsheetWrapper.js');
15
14
  var ButtonWrapper = require('./Datagrid/addons/CustomizeColumns/ButtonWrapper.js');
15
+ var TearsheetWrapper = require('./Datagrid/addons/CustomizeColumns/TearsheetWrapper.js');
16
16
 
17
17
  function _interopNamespaceDefault(e) {
18
18
  var n = Object.create(null);
@@ -33,29 +33,36 @@ function _interopNamespaceDefault(e) {
33
33
 
34
34
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
35
35
 
36
- const useCustomizeColumns = hooks => {
36
+ const useInstance = instance => {
37
+ const {
38
+ customizeColumnsProps
39
+ } = instance;
40
+ const {
41
+ labels
42
+ } = customizeColumnsProps || {};
37
43
  const [isTearsheetOpen, setIsTearsheetOpen] = React__namespace.useState(false);
38
- hooks.useInstance.push(instance => {
39
- const {
40
- customizeColumnsProps
41
- } = instance;
42
- const {
43
- labels
44
- } = customizeColumnsProps || {};
45
- Object.assign(instance, {
46
- customizeColumnsProps: {
47
- ...customizeColumnsProps,
48
- isTearsheetOpen,
49
- setIsTearsheetOpen
50
- },
51
- CustomizeColumnsButton: props => /*#__PURE__*/React__namespace.createElement(ButtonWrapper.default, _rollupPluginBabelHelpers.extends({
52
- iconTooltipLabel: labels?.iconTooltipLabel,
53
- isTearsheetOpen: isTearsheetOpen,
54
- setIsTearsheetOpen: setIsTearsheetOpen
55
- }, props)),
56
- CustomizeColumnsTearsheet: TearsheetWrapper.default
57
- });
44
+ const launcherButtonRef = React__namespace.useRef(null);
45
+ const CustomizeColumnsButton = React__namespace.useCallback(props => /*#__PURE__*/React__namespace.createElement(ButtonWrapper.default, _rollupPluginBabelHelpers.extends({}, props, {
46
+ iconTooltipLabel: labels?.iconTooltipLabel,
47
+ isTearsheetOpen: isTearsheetOpen,
48
+ setIsTearsheetOpen: setIsTearsheetOpen,
49
+ ref: launcherButtonRef
50
+ })), [isTearsheetOpen, labels?.iconTooltipLabel]);
51
+ const CustomizeColumnsTearsheet = React__namespace.useCallback(props => /*#__PURE__*/React__namespace.createElement(TearsheetWrapper.default, _rollupPluginBabelHelpers.extends({}, props, {
52
+ launcherButtonRef: launcherButtonRef
53
+ })), [launcherButtonRef]);
54
+ Object.assign(instance, {
55
+ customizeColumnsProps: {
56
+ ...customizeColumnsProps,
57
+ isTearsheetOpen,
58
+ setIsTearsheetOpen
59
+ },
60
+ CustomizeColumnsButton,
61
+ CustomizeColumnsTearsheet
58
62
  });
59
63
  };
64
+ const useCustomizeColumns = hooks => {
65
+ hooks.useInstance.push(useInstance);
66
+ };
60
67
 
61
68
  exports.default = useCustomizeColumns;
@@ -90,7 +90,8 @@ exports.Guidebanner = /*#__PURE__*/React.forwardRef((_ref, ref) => {
90
90
  },
91
91
  onScroll: scrollPercent => {
92
92
  setScrollPosition(scrollPercent);
93
- }
93
+ },
94
+ isScrollMode: true
94
95
  }, children), /*#__PURE__*/React.createElement("div", {
95
96
  className: cx([collapsible || showNavigation ? `${blockClass}__navigation` : null])
96
97
  }, collapsible && /*#__PURE__*/React.createElement(react.Button, {
@@ -35,6 +35,10 @@ export interface InterstitialScreenProps {
35
35
  * Function to call when the close button is clicked.
36
36
  */
37
37
  onClose?: (value: ActionType) => void;
38
+ /**
39
+ * Provide a ref to return focus to once the interstitial is closed.
40
+ */
41
+ launcherButtonRef?: RefObject<HTMLElement>;
38
42
  }
39
43
  type InterstitialScreenComponent = React.ForwardRefExoticComponent<InterstitialScreenProps & React.RefAttributes<HTMLDivElement>> & {
40
44
  Header: React.FC<InterstitialScreenHeaderProps>;
@@ -52,6 +52,7 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
52
52
  interstitialAriaLabel = 'Interstitial screen',
53
53
  isFullScreen = false,
54
54
  isOpen = false,
55
+ launcherButtonRef,
55
56
  onClose,
56
57
  ...rest
57
58
  } = props;
@@ -86,7 +87,12 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
86
87
  // for modal only, "is-visible" triggers animation
87
88
  setIsVisibleClass(!isFullScreen && isOpen ? 'is-visible' : null);
88
89
  nextButtonRef?.current?.focus();
89
- }, [isFullScreen, isOpen]);
90
+ if (!isOpen && launcherButtonRef) {
91
+ setTimeout(() => {
92
+ launcherButtonRef.current.focus();
93
+ }, 0);
94
+ }
95
+ }, [launcherButtonRef, isFullScreen, isOpen]);
90
96
 
91
97
  // hitting escape key also closes this component
92
98
  React.useEffect(() => {
@@ -105,7 +111,9 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
105
111
  return null;
106
112
  }
107
113
  const renderModal = () => {
108
- return /*#__PURE__*/React.createElement(react.ComposedModal, _rollupPluginBabelHelpers.extends({}, rest, {
114
+ return /*#__PURE__*/React.createElement(react.unstable_FeatureFlags, {
115
+ enableExperimentalFocusWrapWithoutSentinels: true
116
+ }, /*#__PURE__*/React.createElement(react.ComposedModal, _rollupPluginBabelHelpers.extends({}, rest, {
109
117
  preventCloseOnClickOutside: true,
110
118
  className: cx(blockClass,
111
119
  // Apply the block class to the main HTML element
@@ -116,7 +124,7 @@ exports.InterstitialScreen = /*#__PURE__*/React.forwardRef((props, ref) => {
116
124
  open: isOpen,
117
125
  ref: _forwardedRef,
118
126
  "aria-label": interstitialAriaLabel
119
- }, devtools.getDevtoolsProps(componentName)), children);
127
+ }, devtools.getDevtoolsProps(componentName)), children));
120
128
  };
121
129
  const renderFullScreen = () => {
122
130
  return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, rest, {
@@ -197,6 +205,10 @@ exports.InterstitialScreen.propTypes = {
197
205
  * Specifies whether the component is currently open.
198
206
  */
199
207
  isOpen: index.default.bool,
208
+ /**
209
+ * Provide a ref to return focus to once the interstitial is closed.
210
+ */
211
+ launcherButtonRef: index.default.any,
200
212
  /**
201
213
  * Function to call when the close button is clicked.
202
214
  */
@@ -26,7 +26,7 @@ const InterstitialScreenBody = /*#__PURE__*/React.forwardRef(props => {
26
26
  } = props;
27
27
  const blockClass = `${settings.pkg.prefix}--interstitial-screen`;
28
28
  const bodyBlockClass = `${blockClass}--internal-body`;
29
- const [isMultiStep, setIsMultiStep] = React.useState(false);
29
+ const [stepType, setStepType] = React.useState();
30
30
  const {
31
31
  setBodyChildrenData,
32
32
  bodyChildrenData,
@@ -52,12 +52,12 @@ const InterstitialScreenBody = /*#__PURE__*/React.forwardRef(props => {
52
52
 
53
53
  // Set body children data
54
54
  setBodyChildrenData?.(children);
55
-
56
55
  // If the children is an array, treat it as a multiStep
57
56
  if (isElement && Array.isArray(children)) {
58
- const stepLength = children.length;
59
- setIsMultiStep(!!stepLength);
60
- setStepCount?.(stepLength);
57
+ setStepType('multi');
58
+ setStepCount?.(children.length);
59
+ } else {
60
+ setStepType('single');
61
61
  }
62
62
 
63
63
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -82,13 +82,13 @@ const InterstitialScreenBody = /*#__PURE__*/React.forwardRef(props => {
82
82
  ref: bodyScrollRef
83
83
  }, rest), /*#__PURE__*/React.createElement("div", {
84
84
  className: `${blockClass}--content`
85
- }, isMultiStep ? /*#__PURE__*/React.createElement("div", {
85
+ }, stepType === 'multi' ? /*#__PURE__*/React.createElement("div", {
86
86
  className: `${blockClass}__carousel`
87
87
  }, /*#__PURE__*/React.createElement(Carousel.Carousel, {
88
88
  disableArrowScroll: true,
89
89
  ref: scrollRef,
90
90
  onScroll: onScrollHandler
91
- }, bodyChildrenData)) : bodyChildrenData));
91
+ }, bodyChildrenData)) : stepType === 'single' ? bodyChildrenData : ''));
92
92
  return isFullScreen ? renderBody() : /*#__PURE__*/React.createElement(react.ModalBody, {
93
93
  className: bodyBlockClass
94
94
  }, renderBody());
@@ -44,6 +44,13 @@ const InterstitialScreenFooter = /*#__PURE__*/React.forwardRef(props => {
44
44
  const isMultiStep = !!stepCount;
45
45
  const progStepFloor = 0;
46
46
  const progStepCeil = stepCount - 1;
47
+ //this will focus the start button on last step when next button is hidden and start button is shown
48
+ React.useEffect(() => {
49
+ if (progStep + 1 === stepCount && startButtonRef.current) {
50
+ startButtonRef.current.focus();
51
+ }
52
+ // eslint-disable-next-line react-hooks/exhaustive-deps
53
+ }, [progStep]);
47
54
  const handleAction = async actionType => {
48
55
  setLoadingAction(actionType);
49
56
  await onAction?.(actionType, {