@telus-uds/components-base 1.83.0 → 1.84.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.
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _react = _interopRequireDefault(require("react"));
7
+ var _react = _interopRequireWildcard(require("react"));
8
8
  var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
9
9
  var _Animated = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Animated"));
10
10
  var _PanResponder = _interopRequireDefault(require("react-native-web/dist/cjs/exports/PanResponder"));
@@ -28,6 +28,13 @@ var _CarouselTabsPanelItem = _interopRequireDefault(require("./CarouselTabs/Caro
28
28
  var _dictionary = _interopRequireDefault(require("./dictionary"));
29
29
  var _jsxRuntime = require("react/jsx-runtime");
30
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
32
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
+ const TRANSITION_MODES = {
34
+ MANUAL: 'manual',
35
+ AUTOMATIC: 'automatic',
36
+ SWIPE: 'swipe'
37
+ };
31
38
  const staticStyles = _StyleSheet.default.create({
32
39
  root: {
33
40
  backgroundColor: 'transparent',
@@ -36,6 +43,12 @@ const staticStyles = _StyleSheet.default.create({
36
43
  position: 'relative',
37
44
  top: 0,
38
45
  left: 0
46
+ },
47
+ animationControlButton: {
48
+ position: 'absolute',
49
+ zIndex: 1,
50
+ right: _Platform.default.OS === 'web' ? undefined : 40,
51
+ top: 40
39
52
  }
40
53
  });
41
54
  const selectContainerStyles = width => ({
@@ -48,12 +61,29 @@ const selectSwipeAreaStyles = (count, width) => ({
48
61
  justifyContent: 'space-between',
49
62
  flexDirection: 'row'
50
63
  });
64
+ const getDynamicPositionProperty = areStylesAppliedOnPreviousButton => areStylesAppliedOnPreviousButton ? 'left' : 'right';
65
+ const selectControlButtonPositionStyles = _ref => {
66
+ let {
67
+ positionVariant,
68
+ buttonWidth,
69
+ positionProperty = getDynamicPositionProperty(),
70
+ spaceBetweenSlideAndButton
71
+ } = _ref;
72
+ const styles = {};
73
+ if (positionVariant === 'edge') {
74
+ styles[positionProperty] = -1 * (buttonWidth / 2);
75
+ } else if (positionVariant === 'inside') {
76
+ styles[positionProperty] = 0;
77
+ } else if (positionVariant === 'outside') {
78
+ styles[positionProperty] = -1 * (spaceBetweenSlideAndButton + buttonWidth);
79
+ }
80
+ return styles;
81
+ };
51
82
  const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, areStylesAppliedOnPreviousButton) => {
52
83
  const styles = {
53
84
  zIndex: 1,
54
85
  position: 'absolute'
55
86
  };
56
- const dynamicPositionProperty = areStylesAppliedOnPreviousButton ? 'left' : 'right';
57
87
  if (isFirstSlide) {
58
88
  styles.visibility = areStylesAppliedOnPreviousButton ? 'hidden' : 'visible';
59
89
  } else if (isLastSlide) {
@@ -61,19 +91,20 @@ const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWi
61
91
  } else {
62
92
  styles.visibility = 'visible';
63
93
  }
64
- if (previousNextNavigationPosition === 'edge') {
65
- styles[dynamicPositionProperty] = -1 * (previousNextNavigationButtonWidth / 2);
66
- } else if (previousNextNavigationPosition === 'inside') {
67
- styles[dynamicPositionProperty] = 0;
68
- } else if (previousNextNavigationPosition === 'outside') {
69
- styles[dynamicPositionProperty] = -1 * (spaceBetweenSlideAndPreviousNextNavigation + previousNextNavigationButtonWidth);
70
- }
71
- return styles;
94
+ return {
95
+ ...styles,
96
+ ...selectControlButtonPositionStyles({
97
+ positionVariant: previousNextNavigationPosition,
98
+ buttonWidth: previousNextNavigationButtonWidth,
99
+ positionProperty: getDynamicPositionProperty(areStylesAppliedOnPreviousButton),
100
+ spaceBetweenSlideAndButton: spaceBetweenSlideAndPreviousNextNavigation
101
+ })
102
+ };
72
103
  };
73
- const selectIconStyles = _ref => {
104
+ const selectIconStyles = _ref2 => {
74
105
  let {
75
106
  iconBackgroundColor
76
- } = _ref;
107
+ } = _ref2;
77
108
  return {
78
109
  backgroundColor: iconBackgroundColor
79
110
  };
@@ -134,7 +165,7 @@ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_u
134
165
  - `spaceBetweenSlideAndPreviousNextNavigation` - Horizontal space between slide and previous/next navigational buttons
135
166
  - `spaceBetweenSlideAndPanelNavigation` - Vertical space between slide area and panel navigation area
136
167
  */
137
- const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
168
+ const Carousel = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
138
169
  let {
139
170
  tokens,
140
171
  variant,
@@ -164,8 +195,21 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
164
195
  accessibilityLabel,
165
196
  accessibilityLiveRegion = 'polite',
166
197
  copy,
198
+ slideDuration = 0,
199
+ transitionDuration = 0,
200
+ autoPlay = false,
167
201
  ...rest
168
- } = _ref2;
202
+ } = _ref3;
203
+ let childrenArray = (0, _utils.unpackFragment)(children);
204
+ const autoPlayFeatureEnabled = autoPlay && slideDuration > 0 && transitionDuration > 0 && childrenArray.length > 1;
205
+ // if `Carousel` only has one `Carousel.Item`, convert this to a single-item array
206
+ if (!Array.isArray(childrenArray)) {
207
+ childrenArray = [childrenArray];
208
+ }
209
+ const getCopy = (0, _utils.useCopy)({
210
+ dictionary: _dictionary.default,
211
+ copy
212
+ });
169
213
  const viewport = (0, _ViewportProvider.useViewport)();
170
214
  const themeTokens = (0, _ThemeProvider.useThemeTokens)('Carousel', tokens, variant, {
171
215
  viewport
@@ -173,84 +217,53 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
173
217
  const {
174
218
  previousIcon,
175
219
  nextIcon,
220
+ playIcon,
221
+ pauseIcon,
176
222
  showPreviousNextNavigation,
177
223
  showPanelNavigation,
178
224
  showPanelTabs,
179
225
  spaceBetweenSlideAndPreviousNextNavigation
180
226
  } = themeTokens;
181
- const [activeIndex, setActiveIndex] = _react.default.useState(0);
182
- const [isAnimating, setIsAnimating] = _react.default.useState(false);
183
- const handleAnimationStart = _react.default.useCallback(function () {
184
- if (typeof onAnimationStart === 'function') onAnimationStart(...arguments);
185
- setIsAnimating(true);
186
- }, [onAnimationStart]);
187
- const handleAnimationEnd = _react.default.useCallback(function () {
188
- if (typeof onAnimationEnd === 'function') onAnimationEnd(...arguments);
189
- setIsAnimating(false);
190
- }, [onAnimationEnd]);
191
- const getCopy = (0, _utils.useCopy)({
192
- dictionary: _dictionary.default,
193
- copy
194
- });
195
- let childrenArray = (0, _utils.unpackFragment)(children);
196
- // if `Carousel` only has one `Carousel.Item`, convert this to a single-item array
197
- if (!Array.isArray(childrenArray)) {
198
- childrenArray = [childrenArray];
199
- }
200
- const systemProps = selectProps({
201
- ...rest,
202
- accessibilityRole,
203
- accessibilityLabel,
204
- accessibilityValue: {
205
- min: 1,
206
- max: childrenArray.length,
207
- now: activeIndex + 1
208
- }
209
- });
227
+ const [activeIndex, setActiveIndex] = (0, _react.useState)(0);
228
+ const activeIndexRef = (0, _react.useRef)(activeIndex);
210
229
  const {
211
230
  reduceMotionEnabled
212
231
  } = (0, _A11yInfoProvider.useA11yInfo)();
232
+ const reduceMotionRef = (0, _react.useRef)(reduceMotionEnabled);
213
233
  const [containerLayout, setContainerLayout] = _react.default.useState({
214
234
  x: 0,
215
235
  y: 0,
216
236
  width: 0
217
237
  });
218
- const [previousNextNavigationButtonWidth, setPreviousNextNavigationButtonWidth] = _react.default.useState(0);
219
- const firstFocusRef = _react.default.useRef(null);
220
- const pan = _react.default.useRef(new _Animated.default.ValueXY()).current;
221
- const animatedX = _react.default.useRef(0);
222
- const animatedY = _react.default.useRef(0);
238
+ const containerLayoutRef = (0, _react.useRef)(containerLayout);
239
+ const [previousNextNavigationButtonWidth, setPreviousNextNavigationButtonWidth] = (0, _react.useState)(0);
240
+ const firstFocusRef = (0, _react.useRef)(null);
241
+ const pan = (0, _react.useRef)(new _Animated.default.ValueXY()).current;
242
+ const animatedX = (0, _react.useRef)(0);
243
+ const animatedY = (0, _react.useRef)(0);
244
+ const [isAnimating, setIsAnimating] = (0, _react.useState)(false);
245
+ /**
246
+ * While having the same starting point, `isAutoPlayEnabled` and `isCarouselPlaying` are different states
247
+ *
248
+ * `isAutoPlayEnabled` is a state to determine if the autoplay feature is enabled or disabled
249
+ * `isCarouselPlaying` is a state to determine if the carousel is currently playing or paused
250
+ */
251
+ const [isAutoPlayEnabled, setIsAutoPlayEnabled] = (0, _react.useState)(autoPlayFeatureEnabled);
252
+ const [isCarouselPlaying, setisCarouselPlaying] = (0, _react.useState)(autoPlayFeatureEnabled);
253
+ const isSwiping = (0, _react.useRef)(false);
254
+ const autoPlayRef = (0, _react.useRef)(null);
223
255
  const isFirstSlide = !activeIndex;
224
- const isLastSlide = activeIndex + 1 >= children.length;
225
- const onContainerLayout = _ref3 => {
226
- let {
227
- nativeEvent: {
228
- layout: {
229
- x,
230
- y,
231
- width
232
- }
233
- }
234
- } = _ref3;
235
- return setContainerLayout(prevState => ({
236
- ...prevState,
237
- x,
238
- y,
239
- width
240
- }));
241
- };
242
- const onPreviousNextNavigationButtonLayout = _ref4 => {
243
- let {
244
- nativeEvent: {
245
- layout: {
246
- width
247
- }
248
- }
249
- } = _ref4;
250
- return setPreviousNextNavigationButtonWidth(width);
251
- };
252
- const updateOffset = _react.default.useCallback(() => {
253
- animatedX.current = containerLayout.width * activeIndex * -1;
256
+ const isLastSlide = activeIndex + 1 >= childrenArray.length;
257
+ const handleAnimationStart = (0, _react.useCallback)(function () {
258
+ if (typeof onAnimationStart === 'function') onAnimationStart(...arguments);
259
+ setIsAnimating(true);
260
+ }, [onAnimationStart]);
261
+ const handleAnimationEnd = (0, _react.useCallback)(function () {
262
+ if (typeof onAnimationEnd === 'function') onAnimationEnd(...arguments);
263
+ setIsAnimating(false);
264
+ }, [onAnimationEnd]);
265
+ const updateOffset = (0, _react.useCallback)(() => {
266
+ animatedX.current = containerLayoutRef.current.width * activeIndexRef.current * -1;
254
267
  animatedY.current = 0;
255
268
  pan.setOffset({
256
269
  x: animatedX.current,
@@ -260,20 +273,27 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
260
273
  x: 0,
261
274
  y: 0
262
275
  });
263
- }, [activeIndex, containerLayout.width, pan, animatedX]);
264
- const animate = _react.default.useCallback((toValue, toIndex) => {
276
+ }, [pan, animatedX]);
277
+ const animate = (0, _react.useCallback)((toValue, toIndex) => {
265
278
  const handleAnimationEndToIndex = function () {
266
279
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
267
280
  args[_key] = arguments[_key];
268
281
  }
269
282
  return handleAnimationEnd(toIndex, ...args);
270
283
  };
271
- if (reduceMotionEnabled) {
284
+ if (reduceMotionRef.current || isSwiping.current) {
272
285
  _Animated.default.timing(pan, {
273
286
  toValue,
274
287
  duration: 1,
275
288
  useNativeDriver: false
276
289
  }).start(handleAnimationEndToIndex);
290
+ } else if (isAutoPlayEnabled) {
291
+ _Animated.default.timing(pan, {
292
+ ...springConfig,
293
+ toValue,
294
+ useNativeDriver: false,
295
+ duration: transitionDuration * 1000
296
+ }).start(handleAnimationEndToIndex);
277
297
  } else {
278
298
  _Animated.default.spring(pan, {
279
299
  ...springConfig,
@@ -281,45 +301,157 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
281
301
  useNativeDriver: false
282
302
  }).start(handleAnimationEndToIndex);
283
303
  }
284
- }, [pan, springConfig, reduceMotionEnabled, handleAnimationEnd]);
285
- const updateIndex = _react.default.useCallback(function () {
304
+ }, [pan, springConfig, handleAnimationEnd, transitionDuration, isAutoPlayEnabled]);
305
+ const stopAutoplay = (0, _react.useCallback)(() => {
306
+ if (autoPlayRef !== null && autoPlayRef !== void 0 && autoPlayRef.current) {
307
+ clearTimeout(autoPlayRef === null || autoPlayRef === void 0 ? void 0 : autoPlayRef.current);
308
+ }
309
+ }, []);
310
+ const updateIndex = (0, _react.useCallback)(function () {
286
311
  let delta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
312
+ let transitionMode = arguments.length > 1 ? arguments[1] : undefined;
287
313
  const toValue = {
288
314
  x: 0,
289
315
  y: 0
290
316
  };
291
317
  let skipChanges = !delta;
292
318
  let calcDelta = delta;
293
- if (activeIndex <= 0 && delta < 0) {
294
- skipChanges = true;
295
- calcDelta = children.length + delta;
296
- } else if (activeIndex + 1 >= children.length && delta > 0) {
297
- skipChanges = true;
298
- calcDelta = -1 * activeIndex + delta - 1;
319
+ if (activeIndexRef.current <= 0 && delta < 0) {
320
+ skipChanges = transitionMode !== TRANSITION_MODES.AUTOMATIC;
321
+ calcDelta = childrenArray.length + delta;
322
+ } else if (activeIndexRef.current + 1 >= childrenArray.length && delta > 0) {
323
+ skipChanges = transitionMode !== TRANSITION_MODES.AUTOMATIC;
324
+ calcDelta = -1 * activeIndexRef.current + delta - 1;
299
325
  }
300
- const index = activeIndex + calcDelta;
326
+ const index = activeIndexRef.current + calcDelta;
301
327
  if (skipChanges) {
302
328
  animate(toValue, index);
303
329
  return calcDelta;
304
330
  }
331
+ stopAutoplay();
305
332
  setActiveIndex(index);
306
- toValue.x = containerLayout.width * -1 * calcDelta;
333
+ toValue.x = containerLayoutRef.current.width * -1 * calcDelta;
307
334
  animate(toValue, index);
335
+ if (isCarouselPlaying) {
336
+ stopAutoplay();
337
+ if (index === 0 && activeIndexRef.current + 1 === childrenArray.length && transitionMode === TRANSITION_MODES.AUTOMATIC) {
338
+ setisCarouselPlaying(false);
339
+ } else if (isAutoPlayEnabled) {
340
+ autoPlayRef.current = setTimeout(() => {
341
+ var _firstFocusRef$curren;
342
+ updateOffset();
343
+ handleAnimationStart(activeIndexRef.current);
344
+ updateIndex(slideDuration < 0 ? -1 : 1, TRANSITION_MODES.AUTOMATIC);
345
+ if (refocus) (_firstFocusRef$curren = firstFocusRef.current) === null || _firstFocusRef$curren === void 0 ? void 0 : _firstFocusRef$curren.focus();
346
+ }, Math.abs(slideDuration) * 1000);
347
+ }
348
+ }
308
349
  if (onIndexChanged) onIndexChanged(calcDelta, index);
309
350
  return calcDelta;
310
- }, [containerLayout.width, activeIndex, animate, children.length, onIndexChanged]);
311
- const fixOffsetAndGo = _react.default.useCallback(delta => {
312
- var _firstFocusRef$curren;
351
+ }, [handleAnimationStart, refocus, slideDuration, updateOffset, animate, childrenArray.length, onIndexChanged, isCarouselPlaying, stopAutoplay, isAutoPlayEnabled]);
352
+ const startAutoplay = (0, _react.useCallback)(() => {
353
+ stopAutoplay();
354
+ if (isAutoPlayEnabled) {
355
+ autoPlayRef.current = setTimeout(() => {
356
+ var _firstFocusRef$curren2;
357
+ updateOffset();
358
+ handleAnimationStart(activeIndexRef.current);
359
+ updateIndex(slideDuration < 0 ? -1 : 1, TRANSITION_MODES.AUTOMATIC);
360
+ if (refocus && _Platform.default.OS === 'web') (_firstFocusRef$curren2 = firstFocusRef.current) === null || _firstFocusRef$curren2 === void 0 ? void 0 : _firstFocusRef$curren2.focus();
361
+ }, Math.abs(slideDuration) * 1000);
362
+ }
363
+ }, [handleAnimationStart, refocus, updateIndex, updateOffset, slideDuration, stopAutoplay, isAutoPlayEnabled]);
364
+ const fixOffsetAndGo = (0, _react.useCallback)((delta, transitionMode) => {
365
+ var _firstFocusRef$curren3;
313
366
  updateOffset();
314
- handleAnimationStart(activeIndex);
315
- updateIndex(delta);
316
- if (refocus) (_firstFocusRef$curren = firstFocusRef.current) === null || _firstFocusRef$curren === void 0 ? void 0 : _firstFocusRef$curren.focus();
317
- }, [updateIndex, updateOffset, activeIndex, handleAnimationStart, refocus]);
318
- const goToNeighboring = _react.default.useCallback(function () {
367
+ handleAnimationStart(activeIndexRef.current);
368
+ updateIndex(delta, transitionMode);
369
+ if (refocus && _Platform.default.OS === 'web') (_firstFocusRef$curren3 = firstFocusRef.current) === null || _firstFocusRef$curren3 === void 0 ? void 0 : _firstFocusRef$curren3.focus();
370
+ }, [updateIndex, updateOffset, handleAnimationStart, refocus]);
371
+ const goToNeighboring = (0, _react.useCallback)(function () {
319
372
  let toPrev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
320
- fixOffsetAndGo(toPrev ? -1 : 1);
373
+ let transitionMode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : TRANSITION_MODES.MANUAL;
374
+ fixOffsetAndGo(toPrev ? -1 : 1, transitionMode);
321
375
  }, [fixOffsetAndGo]);
322
- const isSwipeAllowed = _react.default.useCallback(() => {
376
+ (0, _react.useEffect)(() => {
377
+ activeIndexRef.current = activeIndex;
378
+ }, [activeIndex]);
379
+ (0, _react.useEffect)(() => {
380
+ reduceMotionRef.current = reduceMotionEnabled;
381
+ }, [reduceMotionEnabled]);
382
+ (0, _react.useEffect)(() => {
383
+ containerLayoutRef.current = containerLayout;
384
+ }, [containerLayout]);
385
+ (0, _react.useEffect)(() => {
386
+ pan.x.addListener(_ref4 => {
387
+ let {
388
+ value
389
+ } = _ref4;
390
+ animatedX.current = value;
391
+ });
392
+ pan.y.addListener(_ref5 => {
393
+ let {
394
+ value
395
+ } = _ref5;
396
+ animatedY.current = value;
397
+ });
398
+ if (isCarouselPlaying) {
399
+ startAutoplay();
400
+ }
401
+ return () => {
402
+ stopAutoplay();
403
+ pan.x.removeAllListeners();
404
+ pan.y.removeAllListeners();
405
+ };
406
+ }, [pan.x, pan.y, startAutoplay, stopAutoplay, isCarouselPlaying]);
407
+ (0, _react.useEffect)(() => {
408
+ const subscription = _Dimensions.default.addEventListener('change', () => {
409
+ updateOffset();
410
+ });
411
+ return () => {
412
+ if (subscription.remove) {
413
+ subscription.remove();
414
+ } else {
415
+ _Dimensions.default.removeEventListener('change', updateOffset);
416
+ }
417
+ };
418
+ }, [updateOffset]);
419
+ (0, _react.useEffect)(() => {
420
+ setIsAutoPlayEnabled(autoPlay && slideDuration > 0 && transitionDuration > 0 && childrenArray.length > 1);
421
+ }, [autoPlay, slideDuration, transitionDuration, childrenArray.length]);
422
+ (0, _react.useEffect)(() => {
423
+ return () => {
424
+ stopAutoplay();
425
+ };
426
+ }, [stopAutoplay]);
427
+ const onContainerLayout = _ref6 => {
428
+ let {
429
+ nativeEvent: {
430
+ layout: {
431
+ x,
432
+ y,
433
+ width
434
+ }
435
+ }
436
+ } = _ref6;
437
+ return setContainerLayout(prevState => ({
438
+ ...prevState,
439
+ x,
440
+ y,
441
+ width
442
+ }));
443
+ };
444
+ const onPreviousNextNavigationButtonLayout = _ref7 => {
445
+ let {
446
+ nativeEvent: {
447
+ layout: {
448
+ width
449
+ }
450
+ }
451
+ } = _ref7;
452
+ return setPreviousNextNavigationButtonWidth(width);
453
+ };
454
+ const isSwipeAllowed = (0, _react.useCallback)(() => {
323
455
  if (childrenArray.length === 1) {
324
456
  return false;
325
457
  }
@@ -328,72 +460,59 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
328
460
  }
329
461
  return true;
330
462
  }, [viewport, childrenArray.length]);
331
- const panResponder = _react.default.useMemo(() => _PanResponder.default.create({
463
+ const panResponder = (0, _react.useMemo)(() => _PanResponder.default.create({
332
464
  onPanResponderTerminationRequest: () => false,
333
465
  onMoveShouldSetResponderCapture: () => true,
334
466
  onMoveShouldSetPanResponderCapture: (_, gestureState) => {
335
467
  if (!isSwipeAllowed()) {
336
468
  return false;
337
469
  }
338
- handleAnimationStart(activeIndex);
339
- return Math.abs(gestureState.dx) > minDistanceToCapture;
470
+ handleAnimationStart(activeIndexRef.current);
471
+ const allow = Math.abs(gestureState.dx) > minDistanceToCapture;
472
+ if (allow) {
473
+ isSwiping.current = true;
474
+ stopAutoplay();
475
+ }
476
+ return allow;
477
+ },
478
+ onPanResponderGrant: () => {
479
+ updateOffset();
340
480
  },
341
- onPanResponderGrant: () => updateOffset(),
342
481
  onPanResponderMove: _Animated.default.event([null, {
343
482
  dx: pan.x
344
483
  }], {
345
484
  useNativeDriver: false
346
485
  }),
347
486
  onPanResponderRelease: (_, gesture) => {
487
+ if (isCarouselPlaying) {
488
+ startAutoplay();
489
+ }
348
490
  const correction = gesture.moveX - gesture.x0;
349
- if (Math.abs(correction) < containerLayout.width * minDistanceForAction) {
491
+ if (Math.abs(correction) < containerLayoutRef.current.width * minDistanceForAction) {
350
492
  animate({
351
493
  x: 0,
352
494
  y: 0
353
495
  }, 0);
354
496
  } else {
355
497
  const delta = correction > 0 ? -1 : 1;
356
- updateIndex(delta);
498
+ updateIndex(delta, TRANSITION_MODES.SWIPE);
357
499
  }
500
+ isSwiping.current = false;
358
501
  }
359
- }), [containerLayout.width, updateIndex, updateOffset, animate, isSwipeAllowed, activeIndex, minDistanceForAction, handleAnimationStart, minDistanceToCapture, pan.x]);
360
- _react.default.useEffect(() => {
361
- pan.x.addListener(_ref5 => {
362
- let {
363
- value
364
- } = _ref5;
365
- animatedX.current = value;
366
- });
367
- pan.y.addListener(_ref6 => {
368
- let {
369
- value
370
- } = _ref6;
371
- animatedY.current = value;
372
- });
373
- return () => {
374
- pan.x.removeAllListeners();
375
- pan.y.removeAllListeners();
376
- };
377
- }, [pan.x, pan.y]);
378
- _react.default.useEffect(() => {
379
- const subscription = _Dimensions.default.addEventListener('change', () => {
380
- updateOffset();
381
- });
382
- return () => subscription === null || subscription === void 0 ? void 0 : subscription.remove();
383
- });
384
- const goToNext = _react.default.useCallback(() => {
502
+ }), [updateIndex, updateOffset, animate, isSwipeAllowed, minDistanceForAction, handleAnimationStart, minDistanceToCapture, pan.x, startAutoplay, stopAutoplay, isCarouselPlaying]);
503
+ const goToNext = (0, _react.useCallback)(() => {
385
504
  goToNeighboring();
386
505
  }, [goToNeighboring]);
387
- const goToPrev = _react.default.useCallback(() => {
506
+ const goToPrev = (0, _react.useCallback)(() => {
388
507
  goToNeighboring(true);
389
508
  }, [goToNeighboring]);
390
- const goTo = _react.default.useCallback(function () {
509
+ const goTo = (0, _react.useCallback)(function () {
391
510
  let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
392
- const delta = index - activeIndex;
511
+ const delta = index - activeIndexRef.current;
393
512
  if (delta) {
394
- fixOffsetAndGo(delta);
513
+ fixOffsetAndGo(delta, TRANSITION_MODES.MANUAL);
395
514
  }
396
- }, [fixOffsetAndGo, activeIndex]);
515
+ }, [fixOffsetAndGo]);
397
516
 
398
517
  // @TODO: - these are Allium-theme variants and won't have any effect in themes that don't implement them.
399
518
  // Normally we avoid setting variants of subcomponents, however this could be re-considered.
@@ -403,7 +522,7 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
403
522
  raised: !(variant !== null && variant !== void 0 && variant.inverse) && true,
404
523
  inverse: variant === null || variant === void 0 ? void 0 : variant.inverse
405
524
  };
406
- const getCopyWithPlaceholders = _react.default.useCallback(copyKey => {
525
+ const getCopyWithPlaceholders = (0, _react.useCallback)(copyKey => {
407
526
  const copyText = getCopy(copyKey).replace(/%\{title\}/g, title).replace(/%\{itemLabel\}/g, itemLabel).replace(/%\{stepNumber\}/g, activeIndex + 1).replace(/%\{stepCount\}/g, childrenArray.length);
408
527
 
409
528
  // First word might be a lowercase placeholder: capitalize the first letter
@@ -426,6 +545,17 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
426
545
  }
427
546
  }
428
547
  };
548
+ const systemProps = selectProps({
549
+ ...rest,
550
+ accessibilityRole,
551
+ accessibilityLabel,
552
+ accessibilityValue: {
553
+ min: 1,
554
+ max: childrenArray.length,
555
+ now: activeIndex + 1
556
+ }
557
+ });
558
+
429
559
  // If container isn't used for focus, give it a label of title if none is passed in,
430
560
  // otherwise read the current position on focus
431
561
  const containerAccessibilityLabel = systemProps.accessibilityLabel ?? isFirstFocusContainer ? `${title ? `${title} ` : ''}${getCopyWithPlaceholders('stepTrackerLabel')}` : title;
@@ -437,6 +567,14 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
437
567
  focusable: true
438
568
  })
439
569
  };
570
+ const onAnimationControlButtonPress = (0, _react.useCallback)(() => {
571
+ if (isCarouselPlaying) {
572
+ stopAutoplay();
573
+ } else {
574
+ startAutoplay();
575
+ }
576
+ setisCarouselPlaying(prevState => !prevState);
577
+ }, [isCarouselPlaying, stopAutoplay, startAutoplay]);
440
578
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CarouselContext.CarouselProvider, {
441
579
  activeIndex: activeIndex,
442
580
  goTo: goTo,
@@ -453,7 +591,19 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
453
591
  ref: ref,
454
592
  ...systemProps,
455
593
  ...containerProps,
456
- children: [showPreviousNextNavigation && childrenArray.length > 1 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
594
+ children: [isAutoPlayEnabled ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
595
+ style: [staticStyles.animationControlButton, selectControlButtonPositionStyles({
596
+ positionVariant: previousNextNavigationPosition,
597
+ buttonWidth: previousNextNavigationButtonWidth,
598
+ positionProperty: getDynamicPositionProperty(),
599
+ spaceBetweenSlideAndButton: spaceBetweenSlideAndPreviousNextNavigation
600
+ })],
601
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
602
+ icon: isCarouselPlaying ? pauseIcon : playIcon,
603
+ variant: previousNextIconButtonVariants,
604
+ onPress: onAnimationControlButtonPress
605
+ })
606
+ }) : null, showPreviousNextNavigation && childrenArray.length > 1 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
457
607
  style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, true),
458
608
  testID: "previous-button-container",
459
609
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
@@ -477,7 +627,7 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
477
627
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
478
628
  style: selectContainerStyles(containerLayout.width),
479
629
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Animated.default.View, {
480
- style: _StyleSheet.default.flatten([selectSwipeAreaStyles(children.length, containerLayout.width), {
630
+ style: _StyleSheet.default.flatten([selectSwipeAreaStyles(childrenArray.length, containerLayout.width), {
481
631
  transform: [{
482
632
  translateX: pan.x
483
633
  }, {
@@ -570,7 +720,7 @@ Carousel.propTypes = {
570
720
  * This function is also provided with a parameter indicating changed index (either 1, or -1)
571
721
  * Use it as follows:
572
722
  * ```js
573
- * const onIndexChangedCallback = React.useCallback((changedIndex, currentActiveIndex) => {
723
+ * const onIndexChangedCallback = useCallback((changedIndex, currentActiveIndex) => {
574
724
  * console.log(changedIndex)
575
725
  * }, []) // pass local dependencies as per your component
576
726
  * <Carousel
@@ -621,7 +771,7 @@ Carousel.propTypes = {
621
771
  * This function is also provided with a parameter indicating the current slide index before animation starts
622
772
  * Use it as follows:
623
773
  * ```js
624
- * const onAnimationStartCallback = React.useCallback((currentIndex) => {
774
+ * const onAnimationStartCallback = useCallback((currentIndex) => {
625
775
  * console.log(currentIndex)
626
776
  * }, []) // pass local dependencies as per your component
627
777
  * <Carousel
@@ -638,7 +788,7 @@ Carousel.propTypes = {
638
788
  * This function is also provided with a parameter indicating the updated slide index after animation ends
639
789
  * Use it as follows:
640
790
  * ```js
641
- * const onAnimationEndCallback = React.useCallback((changedIndex) => {
791
+ * const onAnimationEndCallback = useCallback((changedIndex) => {
642
792
  * console.log(changedIndex)
643
793
  * }, []) // pass local dependencies as per your component
644
794
  * <Carousel
@@ -676,7 +826,26 @@ Carousel.propTypes = {
676
826
  * Note that if the immediate Carousel children do not all render as `'li'` elements,
677
827
  * this should be changed (e.g. pass tag="div") because only 'li' is a valid child of 'ul'.
678
828
  */
679
- tag: _propTypes.default.oneOf(_utils.layoutTags)
829
+ tag: _propTypes.default.oneOf(_utils.layoutTags),
830
+ /**
831
+ * If set to `true`, the Carousel will automatically transition between slides
832
+ * and show the play/pause button
833
+ * - Default value is `false`
834
+ * - `slideDuration` and `transitionDuration` are required to be set for this to work
835
+ */
836
+ autoPlay: _propTypes.default.bool,
837
+ /**
838
+ * Duration of the time in seconds spent on each slide
839
+ * - Default value is `0`
840
+ * - `autoPlay` and `transitionDuration` are required to be set for this to work
841
+ */
842
+ slideDuration: _propTypes.default.number,
843
+ /**
844
+ * Duration of the time in seconds between each slide transition
845
+ * - Default value is `0`
846
+ * - `autoPlay` and `slideDuration` are required to be set for this to work
847
+ */
848
+ transitionDuration: _propTypes.default.number
680
849
  };
681
850
  Carousel.Item = _CarouselItem.default;
682
851
  Carousel.displayName = 'Carousel';