@carbon/ibm-products 2.54.0-canary.70 → 2.54.0-canary.73

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.
@@ -46,6 +46,18 @@ export interface CoachmarkOverlayElementsProps {
46
46
  * The label for the Close button.
47
47
  */
48
48
  closeButtonLabel?: string;
49
+ /**
50
+ * Callback called when clicking on the Next button.
51
+ */
52
+ onNext?: () => void;
53
+ /**
54
+ * Callback called when clicking on the Previous button.
55
+ */
56
+ onBack?: () => void;
57
+ /**
58
+ * Current step of the coachmarks.
59
+ */
60
+ currentStep?: number;
49
61
  }
50
62
  /**
51
63
  * Composable container to allow for the displaying of CoachmarkOverlayElement
@@ -20,7 +20,7 @@ import { pkg } from '../../settings.js';
20
20
  import '../Coachmark/Coachmark.js';
21
21
  import { useCoachmark } from '../Coachmark/utils/context.js';
22
22
 
23
- var _excluded = ["className", "children", "isVisible", "media", "renderMedia", "nextButtonText", "previousButtonLabel", "closeButtonLabel"];
23
+ var _excluded = ["className", "children", "isVisible", "media", "renderMedia", "currentStep", "nextButtonText", "previousButtonLabel", "closeButtonLabel", "onNext", "onBack"];
24
24
 
25
25
  // The block part of our conventional BEM class names (blockClass__E--M).
26
26
  var blockClass = "".concat(pkg.prefix, "--coachmark-overlay-elements");
@@ -41,7 +41,10 @@ var defaults = {
41
41
  isVisible: false,
42
42
  nextButtonText: 'Next',
43
43
  previousButtonLabel: 'Back',
44
- closeButtonLabel: 'Got it'
44
+ closeButtonLabel: 'Got it',
45
+ onNext: undefined,
46
+ onBack: undefined,
47
+ currentStep: 0
45
48
  };
46
49
  /**
47
50
  * Composable container to allow for the displaying of CoachmarkOverlayElement
@@ -54,12 +57,18 @@ var CoachmarkOverlayElements = /*#__PURE__*/React__default.forwardRef(function (
54
57
  isVisible = _ref$isVisible === void 0 ? defaults.isVisible : _ref$isVisible,
55
58
  media = _ref.media,
56
59
  renderMedia = _ref.renderMedia,
60
+ _ref$currentStep = _ref.currentStep,
61
+ currentStep = _ref$currentStep === void 0 ? defaults.currentStep : _ref$currentStep,
57
62
  _ref$nextButtonText = _ref.nextButtonText,
58
63
  nextButtonText = _ref$nextButtonText === void 0 ? defaults.nextButtonText : _ref$nextButtonText,
59
64
  _ref$previousButtonLa = _ref.previousButtonLabel,
60
65
  previousButtonLabel = _ref$previousButtonLa === void 0 ? defaults.previousButtonLabel : _ref$previousButtonLa,
61
66
  _ref$closeButtonLabel = _ref.closeButtonLabel,
62
67
  closeButtonLabel = _ref$closeButtonLabel === void 0 ? defaults.closeButtonLabel : _ref$closeButtonLabel,
68
+ _ref$onNext = _ref.onNext,
69
+ onNext = _ref$onNext === void 0 ? defaults.onNext : _ref$onNext,
70
+ _ref$onBack = _ref.onBack,
71
+ onBack = _ref$onBack === void 0 ? defaults.onBack : _ref$onBack,
63
72
  rest = _objectWithoutProperties(_ref, _excluded);
64
73
  var buttonFocusRef = useRef(undefined);
65
74
  var scrollRef = useRef(undefined);
@@ -67,7 +76,7 @@ var CoachmarkOverlayElements = /*#__PURE__*/React__default.forwardRef(function (
67
76
  _useState2 = _slicedToArray(_useState, 2),
68
77
  scrollPosition = _useState2[0],
69
78
  setScrollPosition = _useState2[1];
70
- var _useState3 = useState(0),
79
+ var _useState3 = useState(currentStep),
71
80
  _useState4 = _slicedToArray(_useState3, 2),
72
81
  currentProgStep = _useState4[0],
73
82
  _setCurrentProgStep = _useState4[1];
@@ -90,6 +99,15 @@ var CoachmarkOverlayElements = /*#__PURE__*/React__default.forwardRef(function (
90
99
  playStep: currentProgStep
91
100
  });
92
101
  }, [currentProgStep, renderMedia]);
102
+ useEffect(function () {
103
+ var _scrollRef$current, _scrollRef$current$sc;
104
+ // When current step is set by props
105
+ // scroll to the appropriate view on the carrousel
106
+ var targetStep = clamp(currentStep, progStepFloor, progStepCeil);
107
+ scrollRef === null || scrollRef === void 0 || (_scrollRef$current = scrollRef.current) === null || _scrollRef$current === void 0 || (_scrollRef$current$sc = _scrollRef$current.scrollToView) === null || _scrollRef$current$sc === void 0 || _scrollRef$current$sc.call(_scrollRef$current, targetStep);
108
+ // Avoid circular call to this hook
109
+ // eslint-disable-next-line react-hooks/exhaustive-deps
110
+ }, [currentStep]);
93
111
  useEffect(function () {
94
112
  // On mount, one of the two primary buttons ("next" or "close")
95
113
  // will be rendered and must have focus. (a11y)
@@ -131,7 +149,6 @@ var CoachmarkOverlayElements = /*#__PURE__*/React__default.forwardRef(function (
131
149
  }, coachmark.closeButtonProps, {
132
150
  ref: buttonFocusRef
133
151
  }), closeButtonLabel))) : /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Carousel, {
134
- disableArrowScroll: true,
135
152
  ref: scrollRef,
136
153
  onScroll: function onScroll(scrollPercent) {
137
154
  setScrollPosition(scrollPercent);
@@ -146,10 +163,11 @@ var CoachmarkOverlayElements = /*#__PURE__*/React__default.forwardRef(function (
146
163
  title: previousButtonLabel,
147
164
  disabled: scrollPosition === 0,
148
165
  onClick: function onClick() {
149
- var _scrollRef$current, _scrollRef$current$sc;
166
+ var _scrollRef$current2, _scrollRef$current2$s;
150
167
  var targetStep = clamp(currentProgStep - 1, progStepFloor, progStepCeil);
151
- scrollRef === null || scrollRef === void 0 || (_scrollRef$current = scrollRef.current) === null || _scrollRef$current === void 0 || (_scrollRef$current$sc = _scrollRef$current.scrollToView) === null || _scrollRef$current$sc === void 0 || _scrollRef$current$sc.call(_scrollRef$current, targetStep);
168
+ scrollRef === null || scrollRef === void 0 || (_scrollRef$current2 = scrollRef.current) === null || _scrollRef$current2 === void 0 || (_scrollRef$current2$s = _scrollRef$current2.scrollToView) === null || _scrollRef$current2$s === void 0 || _scrollRef$current2$s.call(_scrollRef$current2, targetStep);
152
169
  setCurrentProgStep(targetStep);
170
+ onBack === null || onBack === void 0 || onBack();
153
171
  }
154
172
  }, previousButtonLabel), currentProgStep < progStepCeil ? /*#__PURE__*/React__default.createElement(Button, {
155
173
  size: "sm",
@@ -157,10 +175,11 @@ var CoachmarkOverlayElements = /*#__PURE__*/React__default.forwardRef(function (
157
175
  title: nextButtonText,
158
176
  disabled: scrollPosition === 1,
159
177
  onClick: function onClick() {
160
- var _scrollRef$current2, _scrollRef$current2$s;
178
+ var _scrollRef$current3, _scrollRef$current3$s;
161
179
  var targetStep = clamp(currentProgStep + 1, progStepFloor, progStepCeil);
162
- scrollRef === null || scrollRef === void 0 || (_scrollRef$current2 = scrollRef.current) === null || _scrollRef$current2 === void 0 || (_scrollRef$current2$s = _scrollRef$current2.scrollToView) === null || _scrollRef$current2$s === void 0 || _scrollRef$current2$s.call(_scrollRef$current2, targetStep);
180
+ scrollRef === null || scrollRef === void 0 || (_scrollRef$current3 = scrollRef.current) === null || _scrollRef$current3 === void 0 || (_scrollRef$current3$s = _scrollRef$current3.scrollToView) === null || _scrollRef$current3$s === void 0 || _scrollRef$current3$s.call(_scrollRef$current3, targetStep);
163
181
  setCurrentProgStep(targetStep);
182
+ onNext === null || onNext === void 0 || onNext();
164
183
  }
165
184
  }, nextButtonText) : closeButtonLabel && /*#__PURE__*/React__default.createElement(Button, _extends({
166
185
  size: "sm",
@@ -194,6 +213,10 @@ CoachmarkOverlayElements.propTypes = {
194
213
  * The label for the Close button.
195
214
  */
196
215
  closeButtonLabel: PropTypes.string,
216
+ /**
217
+ * Current step of the coachmarks
218
+ */
219
+ currentStep: PropTypes.number,
197
220
  /**
198
221
  * The visibility of CoachmarkOverlayElements is
199
222
  * managed in the parent component.
@@ -215,6 +238,14 @@ CoachmarkOverlayElements.propTypes = {
215
238
  * The label for the Next button.
216
239
  */
217
240
  nextButtonText: PropTypes.string,
241
+ /**
242
+ * Optional callback called when clicking on the Previous button.
243
+ */
244
+ onBack: PropTypes.func,
245
+ /**
246
+ * Optional callback called when clicking on the Next button.
247
+ */
248
+ onNext: PropTypes.func,
218
249
  /**
219
250
  * The label for the Previous button.
220
251
  */
@@ -196,7 +196,8 @@ var CreateTearsheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
196
196
  slug: slug,
197
197
  title: title,
198
198
  verticalPosition: verticalPosition,
199
- closeIconDescription: ''
199
+ closeIconDescription: '',
200
+ currentStep: currentStep
200
201
  }), /*#__PURE__*/React__default.createElement("div", {
201
202
  className: "".concat(blockClass, "__content"),
202
203
  ref: contentRef
@@ -19,6 +19,10 @@ interface TearsheetShellProps extends PropsWithChildren {
19
19
  * An optional class or classes to be added to the outermost element.
20
20
  */
21
21
  className?: string;
22
+ /**
23
+ * Used to track the current step on components which use `StepsContext` and `TearsheetShell`
24
+ */
25
+ currentStep?: number;
22
26
  /**
23
27
  * A description of the flow, displayed in the header area of the tearsheet.
24
28
  */
@@ -21,7 +21,7 @@ import { usePortalTarget } from '../../global/js/hooks/usePortalTarget.js';
21
21
  import { useFocus, claimFocus } from '../../global/js/hooks/useFocus.js';
22
22
  import { usePreviousValue } from '../../global/js/hooks/usePreviousValue.js';
23
23
 
24
- var _excluded = ["actions", "aiLabel", "ariaLabel", "children", "className", "closeIconDescription", "description", "hasCloseIcon", "headerActions", "influencer", "influencerPosition", "influencerWidth", "label", "navigation", "onClose", "open", "portalTarget", "selectorPrimaryFocus", "selectorsFloatingMenus", "size", "slug", "title", "verticalPosition", "launcherButtonRef"];
24
+ var _excluded = ["actions", "aiLabel", "ariaLabel", "children", "className", "closeIconDescription", "currentStep", "description", "hasCloseIcon", "headerActions", "influencer", "influencerPosition", "influencerWidth", "label", "navigation", "onClose", "open", "portalTarget", "selectorPrimaryFocus", "selectorsFloatingMenus", "size", "slug", "title", "verticalPosition", "launcherButtonRef"];
25
25
  // The block part of our conventional BEM class names (bc__E--M).
26
26
  var bc = "".concat(pkg.prefix, "--tearsheet");
27
27
  var componentName = 'TearsheetShell';
@@ -68,6 +68,7 @@ var TearsheetShell = /*#__PURE__*/React__default.forwardRef(function (_ref, ref)
68
68
  children = _ref.children,
69
69
  className = _ref.className,
70
70
  closeIconDescription = _ref.closeIconDescription,
71
+ currentStep = _ref.currentStep,
71
72
  description = _ref.description,
72
73
  hasCloseIcon = _ref.hasCloseIcon,
73
74
  headerActions = _ref.headerActions,
@@ -100,8 +101,7 @@ var TearsheetShell = /*#__PURE__*/React__default.forwardRef(function (_ref, ref)
100
101
  var prevOpen = usePreviousValue(open);
101
102
  var _useFocus = useFocus(modalRef, selectorPrimaryFocus),
102
103
  firstElement = _useFocus.firstElement,
103
- keyDownListener = _useFocus.keyDownListener,
104
- specifiedElement = _useFocus.specifiedElement;
104
+ keyDownListener = _useFocus.keyDownListener;
105
105
  var modalRefValue = modalRef.current;
106
106
 
107
107
  // Function to strip html tags out of a string.
@@ -137,23 +137,12 @@ var TearsheetShell = /*#__PURE__*/React__default.forwardRef(function (_ref, ref)
137
137
  setDepth(newDepth);
138
138
  setPosition(newPosition);
139
139
  }
140
- handleStackChange.checkFocus = function () {
141
- // if we are now the topmost tearsheet, ensure we have focus
142
- if (open && position === depth && modalRefValue && !modalRefValue.contains(document.activeElement)) {
143
- handleStackChange.claimFocus();
144
- }
145
- };
146
-
147
- // Callback to give the tearsheet the opportunity to claim focus
148
- handleStackChange.claimFocus = function () {
149
- claimFocus(firstElement, modalRef, selectorPrimaryFocus);
150
- };
151
140
  useEffect(function () {
152
- if (open) {
141
+ if (open && position === depth) {
153
142
  // Focusing the first element or selectorPrimaryFocus element
154
143
  claimFocus(firstElement, modalRef, selectorPrimaryFocus);
155
144
  }
156
- }, [firstElement, modalRef, open, selectorPrimaryFocus]);
145
+ }, [currentStep, depth, firstElement, modalRef, modalRefValue, open, position, selectorPrimaryFocus]);
157
146
  useEffect(function () {
158
147
  if (prevOpen && !open && launcherButtonRef) {
159
148
  setTimeout(function () {
@@ -161,22 +150,10 @@ var TearsheetShell = /*#__PURE__*/React__default.forwardRef(function (_ref, ref)
161
150
  }, 0);
162
151
  }
163
152
  }, [launcherButtonRef, open, prevOpen]);
164
- useEffect(function () {
165
- if (open && position !== depth) {
166
- setTimeout(function () {
167
- if (selectorPrimaryFocus) {
168
- return specifiedElement === null || specifiedElement === void 0 ? void 0 : specifiedElement.focus();
169
- }
170
- firstElement === null || firstElement === void 0 || firstElement.focus();
171
- }, 0);
172
- }
173
- }, [position, depth, firstElement, open, specifiedElement, selectorPrimaryFocus]);
174
153
  useEffect(function () {
175
154
  var notify = function notify() {
176
155
  return stack.all.forEach(function (handler) {
177
- var _handler$checkFocus;
178
156
  handler(Math.min(stack.open.length, maxDepth), stack.open.indexOf(handler) + 1);
179
- (_handler$checkFocus = handler.checkFocus) === null || _handler$checkFocus === void 0 || _handler$checkFocus.call(handler);
180
157
  });
181
158
  };
182
159
 
@@ -211,14 +188,6 @@ var TearsheetShell = /*#__PURE__*/React__default.forwardRef(function (_ref, ref)
211
188
  }
212
189
  };
213
190
  }, [open, size]);
214
- function handleFocus() {
215
- // If something within us is receiving focus but we are not the topmost
216
- // stacked tearsheet, transfer focus to the topmost tearsheet instead
217
- if (position < depth) {
218
- var _stack$open$claimFocu, _stack$open;
219
- (_stack$open$claimFocu = (_stack$open = stack.open[stack.open.length - 1]).claimFocus) === null || _stack$open$claimFocu === void 0 || _stack$open$claimFocu.call(_stack$open);
220
- }
221
- }
222
191
  if (position <= depth) {
223
192
  var _prevDepth$current;
224
193
  // Include a modal header if and only if one or more of these is given.
@@ -250,7 +219,6 @@ var TearsheetShell = /*#__PURE__*/React__default.forwardRef(function (_ref, ref)
250
219
  onClose: onClose,
251
220
  open: open,
252
221
  selectorPrimaryFocus: selectorPrimaryFocus,
253
- onFocus: handleFocus,
254
222
  onKeyDown: keyDownListener,
255
223
  preventCloseOnClickOutside: !isPassive,
256
224
  ref: modalRef,
@@ -12,4 +12,4 @@ export function useFocus(modalRef: any, selectorPrimaryFocus: any): {
12
12
  specified: any;
13
13
  };
14
14
  };
15
- export function claimFocus(firstElement: any, modalRef: any, selectorPrimaryFocus?: string | undefined): any;
15
+ export function claimFocus(firstElement: any, modalRef: any, selectorPrimaryFocus?: string | undefined): void;
@@ -116,12 +116,15 @@ var claimFocus = function claimFocus(firstElement, modalRef) {
116
116
  var _window2;
117
117
  var specifiedEl = getSpecificElement(modalRef === null || modalRef === void 0 ? void 0 : modalRef.current, selectorPrimaryFocus);
118
118
  if (specifiedEl && ((_window2 = window) === null || _window2 === void 0 || (_window2 = _window2.getComputedStyle(specifiedEl)) === null || _window2 === void 0 ? void 0 : _window2.display) !== 'none') {
119
- return specifiedEl.focus();
119
+ setTimeout(function () {
120
+ return specifiedEl.focus();
121
+ }, 0);
120
122
  }
123
+ } else {
124
+ setTimeout(function () {
125
+ return firstElement === null || firstElement === void 0 ? void 0 : firstElement.focus();
126
+ }, 0);
121
127
  }
122
- setTimeout(function () {
123
- return firstElement === null || firstElement === void 0 ? void 0 : firstElement.focus();
124
- }, 0);
125
128
  };
126
129
 
127
130
  export { claimFocus, getSpecificElement, useFocus };
@@ -46,6 +46,18 @@ export interface CoachmarkOverlayElementsProps {
46
46
  * The label for the Close button.
47
47
  */
48
48
  closeButtonLabel?: string;
49
+ /**
50
+ * Callback called when clicking on the Next button.
51
+ */
52
+ onNext?: () => void;
53
+ /**
54
+ * Callback called when clicking on the Previous button.
55
+ */
56
+ onBack?: () => void;
57
+ /**
58
+ * Current step of the coachmarks.
59
+ */
60
+ currentStep?: number;
49
61
  }
50
62
  /**
51
63
  * Composable container to allow for the displaying of CoachmarkOverlayElement
@@ -22,7 +22,7 @@ var settings = require('../../settings.js');
22
22
  require('../Coachmark/Coachmark.js');
23
23
  var context = require('../Coachmark/utils/context.js');
24
24
 
25
- var _excluded = ["className", "children", "isVisible", "media", "renderMedia", "nextButtonText", "previousButtonLabel", "closeButtonLabel"];
25
+ var _excluded = ["className", "children", "isVisible", "media", "renderMedia", "currentStep", "nextButtonText", "previousButtonLabel", "closeButtonLabel", "onNext", "onBack"];
26
26
 
27
27
  // The block part of our conventional BEM class names (blockClass__E--M).
28
28
  var blockClass = "".concat(settings.pkg.prefix, "--coachmark-overlay-elements");
@@ -43,7 +43,10 @@ var defaults = {
43
43
  isVisible: false,
44
44
  nextButtonText: 'Next',
45
45
  previousButtonLabel: 'Back',
46
- closeButtonLabel: 'Got it'
46
+ closeButtonLabel: 'Got it',
47
+ onNext: undefined,
48
+ onBack: undefined,
49
+ currentStep: 0
47
50
  };
48
51
  /**
49
52
  * Composable container to allow for the displaying of CoachmarkOverlayElement
@@ -56,12 +59,18 @@ exports.CoachmarkOverlayElements = /*#__PURE__*/React.forwardRef(function (_ref,
56
59
  isVisible = _ref$isVisible === void 0 ? defaults.isVisible : _ref$isVisible,
57
60
  media = _ref.media,
58
61
  renderMedia = _ref.renderMedia,
62
+ _ref$currentStep = _ref.currentStep,
63
+ currentStep = _ref$currentStep === void 0 ? defaults.currentStep : _ref$currentStep,
59
64
  _ref$nextButtonText = _ref.nextButtonText,
60
65
  nextButtonText = _ref$nextButtonText === void 0 ? defaults.nextButtonText : _ref$nextButtonText,
61
66
  _ref$previousButtonLa = _ref.previousButtonLabel,
62
67
  previousButtonLabel = _ref$previousButtonLa === void 0 ? defaults.previousButtonLabel : _ref$previousButtonLa,
63
68
  _ref$closeButtonLabel = _ref.closeButtonLabel,
64
69
  closeButtonLabel = _ref$closeButtonLabel === void 0 ? defaults.closeButtonLabel : _ref$closeButtonLabel,
70
+ _ref$onNext = _ref.onNext,
71
+ onNext = _ref$onNext === void 0 ? defaults.onNext : _ref$onNext,
72
+ _ref$onBack = _ref.onBack,
73
+ onBack = _ref$onBack === void 0 ? defaults.onBack : _ref$onBack,
65
74
  rest = _rollupPluginBabelHelpers.objectWithoutProperties(_ref, _excluded);
66
75
  var buttonFocusRef = React.useRef(undefined);
67
76
  var scrollRef = React.useRef(undefined);
@@ -69,7 +78,7 @@ exports.CoachmarkOverlayElements = /*#__PURE__*/React.forwardRef(function (_ref,
69
78
  _useState2 = _rollupPluginBabelHelpers.slicedToArray(_useState, 2),
70
79
  scrollPosition = _useState2[0],
71
80
  setScrollPosition = _useState2[1];
72
- var _useState3 = React.useState(0),
81
+ var _useState3 = React.useState(currentStep),
73
82
  _useState4 = _rollupPluginBabelHelpers.slicedToArray(_useState3, 2),
74
83
  currentProgStep = _useState4[0],
75
84
  _setCurrentProgStep = _useState4[1];
@@ -92,6 +101,15 @@ exports.CoachmarkOverlayElements = /*#__PURE__*/React.forwardRef(function (_ref,
92
101
  playStep: currentProgStep
93
102
  });
94
103
  }, [currentProgStep, renderMedia]);
104
+ React.useEffect(function () {
105
+ var _scrollRef$current, _scrollRef$current$sc;
106
+ // When current step is set by props
107
+ // scroll to the appropriate view on the carrousel
108
+ var targetStep = lodash.clamp(currentStep, progStepFloor, progStepCeil);
109
+ scrollRef === null || scrollRef === void 0 || (_scrollRef$current = scrollRef.current) === null || _scrollRef$current === void 0 || (_scrollRef$current$sc = _scrollRef$current.scrollToView) === null || _scrollRef$current$sc === void 0 || _scrollRef$current$sc.call(_scrollRef$current, targetStep);
110
+ // Avoid circular call to this hook
111
+ // eslint-disable-next-line react-hooks/exhaustive-deps
112
+ }, [currentStep]);
95
113
  React.useEffect(function () {
96
114
  // On mount, one of the two primary buttons ("next" or "close")
97
115
  // will be rendered and must have focus. (a11y)
@@ -133,7 +151,6 @@ exports.CoachmarkOverlayElements = /*#__PURE__*/React.forwardRef(function (_ref,
133
151
  }, coachmark.closeButtonProps, {
134
152
  ref: buttonFocusRef
135
153
  }), closeButtonLabel))) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Carousel.Carousel, {
136
- disableArrowScroll: true,
137
154
  ref: scrollRef,
138
155
  onScroll: function onScroll(scrollPercent) {
139
156
  setScrollPosition(scrollPercent);
@@ -148,10 +165,11 @@ exports.CoachmarkOverlayElements = /*#__PURE__*/React.forwardRef(function (_ref,
148
165
  title: previousButtonLabel,
149
166
  disabled: scrollPosition === 0,
150
167
  onClick: function onClick() {
151
- var _scrollRef$current, _scrollRef$current$sc;
168
+ var _scrollRef$current2, _scrollRef$current2$s;
152
169
  var targetStep = lodash.clamp(currentProgStep - 1, progStepFloor, progStepCeil);
153
- scrollRef === null || scrollRef === void 0 || (_scrollRef$current = scrollRef.current) === null || _scrollRef$current === void 0 || (_scrollRef$current$sc = _scrollRef$current.scrollToView) === null || _scrollRef$current$sc === void 0 || _scrollRef$current$sc.call(_scrollRef$current, targetStep);
170
+ scrollRef === null || scrollRef === void 0 || (_scrollRef$current2 = scrollRef.current) === null || _scrollRef$current2 === void 0 || (_scrollRef$current2$s = _scrollRef$current2.scrollToView) === null || _scrollRef$current2$s === void 0 || _scrollRef$current2$s.call(_scrollRef$current2, targetStep);
154
171
  setCurrentProgStep(targetStep);
172
+ onBack === null || onBack === void 0 || onBack();
155
173
  }
156
174
  }, previousButtonLabel), currentProgStep < progStepCeil ? /*#__PURE__*/React.createElement(react.Button, {
157
175
  size: "sm",
@@ -159,10 +177,11 @@ exports.CoachmarkOverlayElements = /*#__PURE__*/React.forwardRef(function (_ref,
159
177
  title: nextButtonText,
160
178
  disabled: scrollPosition === 1,
161
179
  onClick: function onClick() {
162
- var _scrollRef$current2, _scrollRef$current2$s;
180
+ var _scrollRef$current3, _scrollRef$current3$s;
163
181
  var targetStep = lodash.clamp(currentProgStep + 1, progStepFloor, progStepCeil);
164
- scrollRef === null || scrollRef === void 0 || (_scrollRef$current2 = scrollRef.current) === null || _scrollRef$current2 === void 0 || (_scrollRef$current2$s = _scrollRef$current2.scrollToView) === null || _scrollRef$current2$s === void 0 || _scrollRef$current2$s.call(_scrollRef$current2, targetStep);
182
+ scrollRef === null || scrollRef === void 0 || (_scrollRef$current3 = scrollRef.current) === null || _scrollRef$current3 === void 0 || (_scrollRef$current3$s = _scrollRef$current3.scrollToView) === null || _scrollRef$current3$s === void 0 || _scrollRef$current3$s.call(_scrollRef$current3, targetStep);
165
183
  setCurrentProgStep(targetStep);
184
+ onNext === null || onNext === void 0 || onNext();
166
185
  }
167
186
  }, nextButtonText) : closeButtonLabel && /*#__PURE__*/React.createElement(react.Button, _rollupPluginBabelHelpers.extends({
168
187
  size: "sm",
@@ -196,6 +215,10 @@ exports.CoachmarkOverlayElements.propTypes = {
196
215
  * The label for the Close button.
197
216
  */
198
217
  closeButtonLabel: index.default.string,
218
+ /**
219
+ * Current step of the coachmarks
220
+ */
221
+ currentStep: index.default.number,
199
222
  /**
200
223
  * The visibility of CoachmarkOverlayElements is
201
224
  * managed in the parent component.
@@ -217,6 +240,14 @@ exports.CoachmarkOverlayElements.propTypes = {
217
240
  * The label for the Next button.
218
241
  */
219
242
  nextButtonText: index.default.string,
243
+ /**
244
+ * Optional callback called when clicking on the Previous button.
245
+ */
246
+ onBack: index.default.func,
247
+ /**
248
+ * Optional callback called when clicking on the Next button.
249
+ */
250
+ onNext: index.default.func,
220
251
  /**
221
252
  * The label for the Previous button.
222
253
  */
@@ -198,7 +198,8 @@ exports.CreateTearsheet = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
198
198
  slug: slug,
199
199
  title: title,
200
200
  verticalPosition: verticalPosition,
201
- closeIconDescription: ''
201
+ closeIconDescription: '',
202
+ currentStep: currentStep
202
203
  }), /*#__PURE__*/React.createElement("div", {
203
204
  className: "".concat(blockClass, "__content"),
204
205
  ref: contentRef
@@ -19,6 +19,10 @@ interface TearsheetShellProps extends PropsWithChildren {
19
19
  * An optional class or classes to be added to the outermost element.
20
20
  */
21
21
  className?: string;
22
+ /**
23
+ * Used to track the current step on components which use `StepsContext` and `TearsheetShell`
24
+ */
25
+ currentStep?: number;
22
26
  /**
23
27
  * A description of the flow, displayed in the header area of the tearsheet.
24
28
  */
@@ -23,7 +23,7 @@ var usePortalTarget = require('../../global/js/hooks/usePortalTarget.js');
23
23
  var useFocus = require('../../global/js/hooks/useFocus.js');
24
24
  var usePreviousValue = require('../../global/js/hooks/usePreviousValue.js');
25
25
 
26
- var _excluded = ["actions", "aiLabel", "ariaLabel", "children", "className", "closeIconDescription", "description", "hasCloseIcon", "headerActions", "influencer", "influencerPosition", "influencerWidth", "label", "navigation", "onClose", "open", "portalTarget", "selectorPrimaryFocus", "selectorsFloatingMenus", "size", "slug", "title", "verticalPosition", "launcherButtonRef"];
26
+ var _excluded = ["actions", "aiLabel", "ariaLabel", "children", "className", "closeIconDescription", "currentStep", "description", "hasCloseIcon", "headerActions", "influencer", "influencerPosition", "influencerWidth", "label", "navigation", "onClose", "open", "portalTarget", "selectorPrimaryFocus", "selectorsFloatingMenus", "size", "slug", "title", "verticalPosition", "launcherButtonRef"];
27
27
  // The block part of our conventional BEM class names (bc__E--M).
28
28
  var bc = "".concat(settings.pkg.prefix, "--tearsheet");
29
29
  var componentName = 'TearsheetShell';
@@ -70,6 +70,7 @@ var TearsheetShell = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
70
70
  children = _ref.children,
71
71
  className = _ref.className,
72
72
  closeIconDescription = _ref.closeIconDescription,
73
+ currentStep = _ref.currentStep,
73
74
  description = _ref.description,
74
75
  hasCloseIcon = _ref.hasCloseIcon,
75
76
  headerActions = _ref.headerActions,
@@ -102,8 +103,7 @@ var TearsheetShell = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
102
103
  var prevOpen = usePreviousValue.usePreviousValue(open);
103
104
  var _useFocus = useFocus.useFocus(modalRef, selectorPrimaryFocus),
104
105
  firstElement = _useFocus.firstElement,
105
- keyDownListener = _useFocus.keyDownListener,
106
- specifiedElement = _useFocus.specifiedElement;
106
+ keyDownListener = _useFocus.keyDownListener;
107
107
  var modalRefValue = modalRef.current;
108
108
 
109
109
  // Function to strip html tags out of a string.
@@ -139,23 +139,12 @@ var TearsheetShell = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
139
139
  setDepth(newDepth);
140
140
  setPosition(newPosition);
141
141
  }
142
- handleStackChange.checkFocus = function () {
143
- // if we are now the topmost tearsheet, ensure we have focus
144
- if (open && position === depth && modalRefValue && !modalRefValue.contains(document.activeElement)) {
145
- handleStackChange.claimFocus();
146
- }
147
- };
148
-
149
- // Callback to give the tearsheet the opportunity to claim focus
150
- handleStackChange.claimFocus = function () {
151
- useFocus.claimFocus(firstElement, modalRef, selectorPrimaryFocus);
152
- };
153
142
  React.useEffect(function () {
154
- if (open) {
143
+ if (open && position === depth) {
155
144
  // Focusing the first element or selectorPrimaryFocus element
156
145
  useFocus.claimFocus(firstElement, modalRef, selectorPrimaryFocus);
157
146
  }
158
- }, [firstElement, modalRef, open, selectorPrimaryFocus]);
147
+ }, [currentStep, depth, firstElement, modalRef, modalRefValue, open, position, selectorPrimaryFocus]);
159
148
  React.useEffect(function () {
160
149
  if (prevOpen && !open && launcherButtonRef) {
161
150
  setTimeout(function () {
@@ -163,22 +152,10 @@ var TearsheetShell = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
163
152
  }, 0);
164
153
  }
165
154
  }, [launcherButtonRef, open, prevOpen]);
166
- React.useEffect(function () {
167
- if (open && position !== depth) {
168
- setTimeout(function () {
169
- if (selectorPrimaryFocus) {
170
- return specifiedElement === null || specifiedElement === void 0 ? void 0 : specifiedElement.focus();
171
- }
172
- firstElement === null || firstElement === void 0 || firstElement.focus();
173
- }, 0);
174
- }
175
- }, [position, depth, firstElement, open, specifiedElement, selectorPrimaryFocus]);
176
155
  React.useEffect(function () {
177
156
  var notify = function notify() {
178
157
  return stack.all.forEach(function (handler) {
179
- var _handler$checkFocus;
180
158
  handler(Math.min(stack.open.length, maxDepth), stack.open.indexOf(handler) + 1);
181
- (_handler$checkFocus = handler.checkFocus) === null || _handler$checkFocus === void 0 || _handler$checkFocus.call(handler);
182
159
  });
183
160
  };
184
161
 
@@ -213,14 +190,6 @@ var TearsheetShell = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
213
190
  }
214
191
  };
215
192
  }, [open, size]);
216
- function handleFocus() {
217
- // If something within us is receiving focus but we are not the topmost
218
- // stacked tearsheet, transfer focus to the topmost tearsheet instead
219
- if (position < depth) {
220
- var _stack$open$claimFocu, _stack$open;
221
- (_stack$open$claimFocu = (_stack$open = stack.open[stack.open.length - 1]).claimFocus) === null || _stack$open$claimFocu === void 0 || _stack$open$claimFocu.call(_stack$open);
222
- }
223
- }
224
193
  if (position <= depth) {
225
194
  var _prevDepth$current;
226
195
  // Include a modal header if and only if one or more of these is given.
@@ -252,7 +221,6 @@ var TearsheetShell = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
252
221
  onClose: onClose,
253
222
  open: open,
254
223
  selectorPrimaryFocus: selectorPrimaryFocus,
255
- onFocus: handleFocus,
256
224
  onKeyDown: keyDownListener,
257
225
  preventCloseOnClickOutside: !isPassive,
258
226
  ref: modalRef,
@@ -12,4 +12,4 @@ export function useFocus(modalRef: any, selectorPrimaryFocus: any): {
12
12
  specified: any;
13
13
  };
14
14
  };
15
- export function claimFocus(firstElement: any, modalRef: any, selectorPrimaryFocus?: string | undefined): any;
15
+ export function claimFocus(firstElement: any, modalRef: any, selectorPrimaryFocus?: string | undefined): void;
@@ -118,12 +118,15 @@ var claimFocus = function claimFocus(firstElement, modalRef) {
118
118
  var _window2;
119
119
  var specifiedEl = getSpecificElement(modalRef === null || modalRef === void 0 ? void 0 : modalRef.current, selectorPrimaryFocus);
120
120
  if (specifiedEl && ((_window2 = window) === null || _window2 === void 0 || (_window2 = _window2.getComputedStyle(specifiedEl)) === null || _window2 === void 0 ? void 0 : _window2.display) !== 'none') {
121
- return specifiedEl.focus();
121
+ setTimeout(function () {
122
+ return specifiedEl.focus();
123
+ }, 0);
122
124
  }
125
+ } else {
126
+ setTimeout(function () {
127
+ return firstElement === null || firstElement === void 0 ? void 0 : firstElement.focus();
128
+ }, 0);
123
129
  }
124
- setTimeout(function () {
125
- return firstElement === null || firstElement === void 0 ? void 0 : firstElement.focus();
126
- }, 0);
127
130
  };
128
131
 
129
132
  exports.claimFocus = claimFocus;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/ibm-products",
3
3
  "description": "Carbon for IBM Products",
4
- "version": "2.54.0-canary.70+13e845c84",
4
+ "version": "2.54.0-canary.73+36bd4f96c",
5
5
  "license": "Apache-2.0",
6
6
  "main": "lib/index.js",
7
7
  "module": "es/index.js",
@@ -120,5 +120,5 @@
120
120
  "react": "^16.8.6 || ^17.0.1 || ^18.2.0",
121
121
  "react-dom": "^16.8.6 || ^17.0.1 || ^18.2.0"
122
122
  },
123
- "gitHead": "13e845c84e1583e4cdc5d037f31a8c3b826fabfc"
123
+ "gitHead": "36bd4f96c4d5ab6f3fd5ef1a732e9efbf6ec5212"
124
124
  }