@telus-uds/components-base 3.26.0 → 3.28.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/CHANGELOG.md +35 -2
  2. package/lib/cjs/Card/Card.js +34 -13
  3. package/lib/cjs/Card/CardBase.js +90 -14
  4. package/lib/cjs/Card/PressableCardBase.js +147 -8
  5. package/lib/cjs/Carousel/Carousel.js +105 -50
  6. package/lib/cjs/Carousel/CarouselContext.js +10 -4
  7. package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +11 -7
  8. package/lib/cjs/Carousel/Constants.js +11 -2
  9. package/lib/cjs/Checkbox/Checkbox.js +43 -13
  10. package/lib/cjs/ExpandCollapse/Control.js +5 -1
  11. package/lib/cjs/ExpandCollapse/ExpandCollapse.js +17 -8
  12. package/lib/cjs/ExpandCollapse/Panel.js +7 -2
  13. package/lib/cjs/IconButton/IconButton.js +10 -5
  14. package/lib/cjs/List/List.js +24 -9
  15. package/lib/cjs/List/ListItem.js +18 -1
  16. package/lib/cjs/List/ListItemBase.js +27 -8
  17. package/lib/cjs/List/ListItemMark.js +33 -62
  18. package/lib/cjs/List/PressableListItemBase.js +1 -0
  19. package/lib/cjs/Modal/Modal.js +21 -11
  20. package/lib/cjs/Progress/Progress.js +19 -5
  21. package/lib/cjs/Progress/ProgressBar.js +22 -4
  22. package/lib/cjs/Progress/ProgressContext.js +11 -0
  23. package/lib/cjs/SideNav/Item.js +3 -3
  24. package/lib/cjs/SideNav/ItemsGroup.js +46 -19
  25. package/lib/cjs/SideNav/SideNav.js +29 -13
  26. package/lib/esm/Card/Card.js +34 -13
  27. package/lib/esm/Card/CardBase.js +90 -14
  28. package/lib/esm/Card/PressableCardBase.js +148 -9
  29. package/lib/esm/Carousel/Carousel.js +106 -51
  30. package/lib/esm/Carousel/CarouselContext.js +10 -4
  31. package/lib/esm/Carousel/CarouselItem/CarouselItem.js +11 -7
  32. package/lib/esm/Carousel/Constants.js +10 -1
  33. package/lib/esm/Checkbox/Checkbox.js +43 -13
  34. package/lib/esm/ExpandCollapse/Control.js +5 -1
  35. package/lib/esm/ExpandCollapse/ExpandCollapse.js +17 -8
  36. package/lib/esm/ExpandCollapse/Panel.js +7 -2
  37. package/lib/esm/IconButton/IconButton.js +10 -5
  38. package/lib/esm/List/List.js +24 -9
  39. package/lib/esm/List/ListItem.js +19 -2
  40. package/lib/esm/List/ListItemBase.js +27 -8
  41. package/lib/esm/List/ListItemMark.js +33 -62
  42. package/lib/esm/List/PressableListItemBase.js +1 -0
  43. package/lib/esm/Modal/Modal.js +21 -11
  44. package/lib/esm/Progress/Progress.js +19 -5
  45. package/lib/esm/Progress/ProgressBar.js +22 -4
  46. package/lib/esm/Progress/ProgressContext.js +5 -0
  47. package/lib/esm/SideNav/Item.js +3 -3
  48. package/lib/esm/SideNav/ItemsGroup.js +45 -20
  49. package/lib/esm/SideNav/SideNav.js +29 -13
  50. package/lib/package.json +2 -2
  51. package/package.json +2 -2
  52. package/src/Card/Card.jsx +29 -7
  53. package/src/Card/CardBase.jsx +97 -11
  54. package/src/Card/PressableCardBase.jsx +135 -9
  55. package/src/Carousel/Carousel.jsx +119 -64
  56. package/src/Carousel/CarouselContext.jsx +12 -4
  57. package/src/Carousel/CarouselItem/CarouselItem.jsx +10 -6
  58. package/src/Carousel/Constants.js +10 -0
  59. package/src/Checkbox/Checkbox.jsx +29 -7
  60. package/src/ExpandCollapse/Control.jsx +1 -1
  61. package/src/ExpandCollapse/ExpandCollapse.jsx +9 -8
  62. package/src/ExpandCollapse/Panel.jsx +10 -2
  63. package/src/IconButton/IconButton.jsx +40 -28
  64. package/src/List/List.jsx +33 -9
  65. package/src/List/ListItem.jsx +33 -11
  66. package/src/List/ListItemBase.jsx +33 -9
  67. package/src/List/ListItemMark.jsx +32 -53
  68. package/src/List/PressableListItemBase.jsx +1 -0
  69. package/src/Modal/Modal.jsx +23 -11
  70. package/src/Progress/Progress.jsx +18 -7
  71. package/src/Progress/ProgressBar.jsx +19 -14
  72. package/src/Progress/ProgressContext.js +5 -0
  73. package/src/SideNav/Item.jsx +3 -3
  74. package/src/SideNav/ItemsGroup.jsx +36 -16
  75. package/src/SideNav/SideNav.jsx +22 -8
@@ -22,7 +22,7 @@ import CarouselTabsPanel from './CarouselTabs/CarouselTabsPanel';
22
22
  import CarouselTabsPanelItem from './CarouselTabs/CarouselTabsPanelItem';
23
23
  import dictionary from './dictionary';
24
24
  import Box from '../Box';
25
- import { ITEMS_PER_VIEWPORT_XS_SM, ITEMS_PER_VIEWPORT_MD, ITEMS_PER_VIEWPORT_LG_XL, DEFAULT_POSITION_OFFSET, LARGE_VIEWPORT_MARGIN, DEFAULT_VIEWPORT_MARGIN, PEEKING_MULTIPLIER, ACTIVE_INDEX_OFFSET_MULTIPLIER, NEGATIVE_MULTIPLIER, TRANSITION_MODES, SWIPE_RELEASE_STYLES, INSTANT_ANIMATION_DURATION, DEFAULT_SWIPE_RELEASE_DURATION } from './Constants';
25
+ import { ITEMS_PER_VIEWPORT_XS_SM, ITEMS_PER_VIEWPORT_MD, ITEMS_PER_VIEWPORT_LG_XL, DEFAULT_POSITION_OFFSET, LARGE_VIEWPORT_MARGIN, DEFAULT_VIEWPORT_MARGIN, PEEKING_MULTIPLIER, NEGATIVE_MULTIPLIER, TRANSITION_MODES, SWIPE_RELEASE_STYLES, INSTANT_ANIMATION_DURATION, DEFAULT_SWIPE_RELEASE_DURATION, POSITION_VARIANTS, POSITION_PROPERTIES } from './Constants';
26
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
27
27
  const staticStyles = StyleSheet.create({
28
28
  root: {
@@ -72,7 +72,7 @@ const selectHeroContainerStyles = (width, hidden) => ({
72
72
  width,
73
73
  visibility: hidden ? 'hidden' : 'visible'
74
74
  });
75
- const getDynamicPositionProperty = areStylesAppliedOnPreviousButton => areStylesAppliedOnPreviousButton ? 'left' : 'right';
75
+ const getDynamicPositionProperty = areStylesAppliedOnPreviousButton => areStylesAppliedOnPreviousButton ? POSITION_PROPERTIES.LEFT : POSITION_PROPERTIES.RIGHT;
76
76
  const selectControlButtonPositionStyles = _ref => {
77
77
  let {
78
78
  positionVariant,
@@ -82,23 +82,36 @@ const selectControlButtonPositionStyles = _ref => {
82
82
  enablePeeking,
83
83
  enableDisplayMultipleItemsPerSlide,
84
84
  isAutoPlayEnabled,
85
- viewport
85
+ viewport,
86
+ maxWidth,
87
+ viewportWidth
86
88
  } = _ref;
87
89
  const styles = {};
88
- if (positionVariant === 'edge') {
89
- styles[positionProperty] = -1 * (buttonWidth / 2);
90
- } else if (positionVariant === 'inside') {
91
- styles[positionProperty] = DEFAULT_POSITION_OFFSET;
92
- } else if (positionVariant === 'outside') {
90
+ let positionOffset = 0;
91
+ if (positionVariant === POSITION_VARIANTS.EDGE) {
92
+ positionOffset = -1 * (buttonWidth / 2);
93
+ } else if (positionVariant === POSITION_VARIANTS.INSIDE) {
94
+ positionOffset = DEFAULT_POSITION_OFFSET;
95
+ } else if (positionVariant === POSITION_VARIANTS.OUTSIDE) {
93
96
  if (enablePeeking || enableDisplayMultipleItemsPerSlide || isAutoPlayEnabled && viewport === 'xs') {
94
- styles[positionProperty] = 0;
97
+ positionOffset = 0;
95
98
  } else {
96
- styles[positionProperty] = -1 * (spaceBetweenSlideAndButton + buttonWidth);
99
+ positionOffset = -1 * (spaceBetweenSlideAndButton + buttonWidth);
100
+ }
101
+ }
102
+ if (enablePeeking) {
103
+ if (positionProperty === POSITION_PROPERTIES.RIGHT) {
104
+ const rightMargin = (viewportWidth - maxWidth) / 2;
105
+ positionOffset += rightMargin;
106
+ } else if (positionProperty === POSITION_PROPERTIES.LEFT) {
107
+ const leftMargin = (viewportWidth - maxWidth) / 2;
108
+ positionOffset += leftMargin;
97
109
  }
98
110
  }
111
+ styles[positionProperty] = positionOffset;
99
112
  return styles;
100
113
  };
101
- const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, areStylesAppliedOnPreviousButton, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport) => {
114
+ const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, areStylesAppliedOnPreviousButton, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport, maxWidth, viewportWidth) => {
102
115
  const styles = {
103
116
  zIndex: 1,
104
117
  position: 'absolute'
@@ -120,7 +133,9 @@ const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWi
120
133
  enablePeeking,
121
134
  enableDisplayMultipleItemsPerSlide,
122
135
  isAutoPlayEnabled,
123
- viewport
136
+ viewport,
137
+ maxWidth,
138
+ viewportWidth
124
139
  })
125
140
  };
126
141
  };
@@ -186,7 +201,7 @@ const getMaximumItemsForSlide = (enableDisplayMultipleItemsPerSlide, viewport) =
186
201
  }
187
202
  return ITEMS_PER_VIEWPORT_XS_SM;
188
203
  };
189
- const selectRootContainerStyles = (enableHero, viewport) => {
204
+ const selectRootContainerStyles = (enableHero, viewport, enablePeeking) => {
190
205
  if (enableHero && viewport === 'xl' && Platform.OS === 'web') {
191
206
  return {
192
207
  alignItems: 'center'
@@ -197,15 +212,25 @@ const selectRootContainerStyles = (enableHero, viewport) => {
197
212
  paddingHorizontal: 16
198
213
  };
199
214
  }
215
+ if (enablePeeking) {
216
+ return {
217
+ width: '100%'
218
+ };
219
+ }
200
220
  return {};
201
221
  };
202
- const selectMainContainerStyles = (enableHero, viewport, maxWidth) => {
203
- if (enableHero && viewport === 'xl' && Platform.OS === 'web') {
222
+ const selectMainContainerStyles = (enableHero, viewport, maxWidth, enablePeeking) => {
223
+ if (enableHero && viewport === 'xl' && Platform.OS === 'web' && !enablePeeking) {
204
224
  return {
205
225
  width: '100%',
206
226
  maxWidth: maxWidth || 1200
207
227
  };
208
228
  }
229
+ if (enablePeeking) {
230
+ return {
231
+ width: '100%'
232
+ };
233
+ }
209
234
  if (maxWidth !== null && maxWidth !== undefined) {
210
235
  return {
211
236
  maxWidth,
@@ -215,14 +240,20 @@ const selectMainContainerStyles = (enableHero, viewport, maxWidth) => {
215
240
  }
216
241
  return {};
217
242
  };
218
- const selectNavigationStyles = (tabs, enableHero, viewport) => {
243
+ const selectNavigationStyles = (tabs, enableHero, viewport, enablePeeking, maxWidth) => {
219
244
  let marginHorizontal = 0;
220
245
  if (enableHero && tabs) {
221
246
  marginHorizontal = viewport === 'xl' ? LARGE_VIEWPORT_MARGIN : DEFAULT_VIEWPORT_MARGIN;
222
247
  }
223
- return {
248
+ const styles = {
224
249
  marginHorizontal
225
250
  };
251
+ if (enablePeeking && maxWidth) {
252
+ styles.maxWidth = maxWidth;
253
+ styles.alignSelf = 'center';
254
+ styles.width = '100%';
255
+ }
256
+ return styles;
226
257
  };
227
258
 
228
259
  /**
@@ -231,23 +262,18 @@ const selectNavigationStyles = (tabs, enableHero, viewport) => {
231
262
  * @param {number} containerWidth - The width of the carousel container.
232
263
  * @param {boolean} enablePeeking - Flag indicating whether peeking is enabled.
233
264
  * @param {Object} viewport - The viewport configuration object used to determine peeking properties.
234
- * @param {React.MutableRefObject<number>} activeIndexRef - A ref object holding the current active index of the carousel.
265
+ * @param {number} maxWidth - The maximum width constraint for the carousel content.
235
266
  * @returns {number} The calculated final width of the carousel container.
236
267
  */
237
- const calculateFinalWidth = (containerWidth, enablePeeking, viewport, activeIndexRef) => {
268
+ const calculateFinalWidth = (containerWidth, enablePeeking, viewport, maxWidth) => {
238
269
  let finalWidth = containerWidth;
239
270
  if (enablePeeking) {
240
271
  const {
241
272
  peekingGap,
242
- peekingMiddleSpace,
243
- peekingMarginLeft
273
+ peekingMiddleSpace
244
274
  } = getPeekingProps(viewport);
245
- const slideWide = containerWidth - (peekingMiddleSpace * PEEKING_MULTIPLIER + peekingGap * PEEKING_MULTIPLIER);
246
- if (activeIndexRef.current === 0) {
247
- finalWidth = slideWide + peekingMarginLeft - peekingMiddleSpace;
248
- } else {
249
- finalWidth = slideWide + peekingGap;
250
- }
275
+ const baseWidth = maxWidth || containerWidth;
276
+ finalWidth = baseWidth - peekingMiddleSpace * PEEKING_MULTIPLIER + peekingGap;
251
277
  }
252
278
  return finalWidth;
253
279
  };
@@ -370,7 +396,10 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
370
396
  } = useTheme();
371
397
  const contentMaxWidthValue = useResponsiveProp(contentMaxWidth);
372
398
  const responsiveWidth = useResponsiveProp(themeOptions?.contentMaxWidth);
373
- const maxWidth = resolveContentMaxWidth(contentMaxWidthValue, responsiveWidth);
399
+ let maxWidth = null;
400
+ if (enablePeeking || contentMaxWidth !== undefined) {
401
+ maxWidth = contentMaxWidthValue === undefined ? responsiveWidth : resolveContentMaxWidth(contentMaxWidthValue, responsiveWidth);
402
+ }
374
403
  const totalItems = getTotalItems(enableDisplayMultipleItemsPerSlide, childrenArray, viewport);
375
404
  const autoPlayFeatureEnabled = autoPlay && slideDuration > 0 && transitionDuration > 0 && totalItems > 1;
376
405
  // if `Carousel` only has one `Carousel.Item`, convert this to a single-item array
@@ -433,8 +462,16 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
433
462
  const [isCarouselPlaying, setisCarouselPlaying] = React.useState(autoPlayFeatureEnabled);
434
463
  const isSwiping = React.useRef(false);
435
464
  const autoPlayRef = React.useRef(null);
465
+ const [rootContainerLayout, setRootContainerLayout] = React.useState({
466
+ x: 0,
467
+ y: 0,
468
+ width: 0,
469
+ height: 0
470
+ });
471
+ const rootContainerLayoutRef = React.useRef(rootContainerLayout);
436
472
  const isFirstSlide = !activeIndex;
437
473
  const isLastSlide = activeIndex + 1 >= totalItems;
474
+ const currentViewportWidth = rootContainerLayout.width;
438
475
  const handleAnimationStart = React.useCallback(function () {
439
476
  if (typeof onAnimationStart === 'function') onAnimationStart(...arguments);
440
477
  setIsAnimating(true);
@@ -452,15 +489,15 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
452
489
  if (enablePeeking) {
453
490
  const {
454
491
  peekingGap,
455
- peekingMiddleSpace,
456
- peekingMarginLeft
492
+ peekingMiddleSpace
457
493
  } = getPeekingProps(viewport);
458
494
  let finalWidth;
459
- const slideWide = containerLayoutRef.current.width - (peekingMiddleSpace * PEEKING_MULTIPLIER + peekingGap * PEEKING_MULTIPLIER);
495
+ const baseWidth = maxWidth || containerLayoutRef.current.width;
496
+ const slideWide = baseWidth - peekingMiddleSpace * PEEKING_MULTIPLIER;
460
497
  if (activeIndexRef.current === 0) {
461
498
  finalWidth = 0;
462
499
  } else {
463
- finalWidth = slideWide + peekingMarginLeft - peekingMiddleSpace + (slideWide + peekingGap) * (activeIndexRef.current - ACTIVE_INDEX_OFFSET_MULTIPLIER);
500
+ finalWidth = (slideWide + peekingGap) * activeIndexRef.current;
464
501
  }
465
502
  animatedX.current = finalWidth * NEGATIVE_MULTIPLIER;
466
503
  } else {
@@ -487,7 +524,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
487
524
  y: 0
488
525
  });
489
526
  }
490
- }, [pan, animatedX, heroPan, heroAnimatedX, enableHero, viewport, enablePeeking]);
527
+ }, [pan, animatedX, heroPan, heroAnimatedX, enableHero, viewport, enablePeeking, maxWidth]);
491
528
  const animate = React.useCallback(function (panToAnimate, toValue, toIndex) {
492
529
  let isSwipeRelease = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
493
530
  const applicableTransitionDuration = isLastSlide && toIndex === 0 ? loopDuration : transitionDuration;
@@ -579,7 +616,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
579
616
  }
580
617
  stopAutoplay();
581
618
  setActiveIndex(index);
582
- const finalWidth = calculateFinalWidth(containerLayoutRef.current.width, enablePeeking, viewport, activeIndexRef);
619
+ const finalWidth = calculateFinalWidth(containerLayoutRef.current.width, enablePeeking, viewport, maxWidth);
583
620
  toValue.x = finalWidth * -1 * calcDelta;
584
621
  const heroToValue = {
585
622
  x: 0,
@@ -606,7 +643,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
606
643
  }
607
644
  if (onIndexChanged) onIndexChanged(calcDelta, index);
608
645
  return calcDelta;
609
- }, [handleAnimationStart, triggerRefocus, slideDuration, updateOffset, animate, totalItems, onIndexChanged, isCarouselPlaying, stopAutoplay, isAutoPlayEnabled, viewport, enablePeeking, pan, heroPan, enableHero]);
646
+ }, [handleAnimationStart, triggerRefocus, slideDuration, updateOffset, animate, totalItems, onIndexChanged, isCarouselPlaying, stopAutoplay, isAutoPlayEnabled, viewport, enablePeeking, pan, heroPan, enableHero, maxWidth]);
610
647
  const startAutoplay = React.useCallback(() => {
611
648
  stopAutoplay();
612
649
  if (isAutoPlayEnabled) {
@@ -641,6 +678,9 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
641
678
  React.useEffect(() => {
642
679
  heroContainerLayoutRef.current = heroContainerLayout;
643
680
  }, [heroContainerLayout]);
681
+ React.useEffect(() => {
682
+ rootContainerLayoutRef.current = rootContainerLayout;
683
+ }, [rootContainerLayout]);
644
684
  React.useEffect(() => {
645
685
  pan.x.addListener(_ref5 => {
646
686
  let {
@@ -749,6 +789,25 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
749
789
  } = _ref11;
750
790
  return setPreviousNextNavigationButtonWidth(width);
751
791
  };
792
+ const onRootContainerLayout = _ref12 => {
793
+ let {
794
+ nativeEvent: {
795
+ layout: {
796
+ x,
797
+ y,
798
+ width,
799
+ height
800
+ }
801
+ }
802
+ } = _ref12;
803
+ return setRootContainerLayout(prevState => ({
804
+ ...prevState,
805
+ x,
806
+ y,
807
+ width,
808
+ height
809
+ }));
810
+ };
752
811
  const isSwipeAllowed = React.useCallback(() => {
753
812
  if (totalItems === 1) {
754
813
  return false;
@@ -914,9 +973,10 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
914
973
  }
915
974
  }, [isTransitioningRef]);
916
975
  return /*#__PURE__*/_jsxs(View, {
917
- style: selectRootContainerStyles(enableHero, viewport),
976
+ style: selectRootContainerStyles(enableHero, viewport, enablePeeking),
977
+ onLayout: onRootContainerLayout,
918
978
  children: [/*#__PURE__*/_jsx(View, {
919
- style: selectMainContainerStyles(enableHero, viewport, maxWidth),
979
+ style: selectMainContainerStyles(enableHero, viewport, maxWidth, enablePeeking),
920
980
  children: /*#__PURE__*/_jsxs(CarouselProvider, {
921
981
  activeIndex: activeIndex,
922
982
  goTo: goTo,
@@ -928,6 +988,8 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
928
988
  refocus: refocus,
929
989
  width: containerLayout.width,
930
990
  maximumItemsForSlide: getMaximumItemsForSlide(enableDisplayMultipleItemsPerSlide, viewport),
991
+ maxWidth: maxWidth,
992
+ viewportWidth: currentViewportWidth,
931
993
  children: [/*#__PURE__*/_jsxs(View, {
932
994
  style: [staticStyles.root, {
933
995
  ...(Platform.OS === 'web' ? {
@@ -950,7 +1012,9 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
950
1012
  enablePeeking,
951
1013
  enableDisplayMultipleItemsPerSlide,
952
1014
  isAutoPlayEnabled,
953
- viewport
1015
+ viewport,
1016
+ maxWidth,
1017
+ viewportWidth: currentViewportWidth
954
1018
  })],
955
1019
  children: /*#__PURE__*/_jsx(IconButton, {
956
1020
  icon: isCarouselPlaying ? pauseIcon : playIcon,
@@ -959,7 +1023,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
959
1023
  onPress: onAnimationControlButtonPress
960
1024
  })
961
1025
  }) : null, showPreviousNextNavigation && totalItems > 1 ? /*#__PURE__*/_jsx(View, {
962
- style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, true, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport),
1026
+ style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, true, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport, maxWidth, currentViewportWidth),
963
1027
  testID: "previous-button-container",
964
1028
  children: /*#__PURE__*/_jsx(IconButton, {
965
1029
  onLayout: onPreviousNextNavigationButtonLayout,
@@ -997,16 +1061,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
997
1061
  children: childrenArray.map((element, index) => {
998
1062
  let hidden = !isAnimating && index !== activeIndex;
999
1063
  if (enablePeeking && !isAnimating) {
1000
- if (enableDisplayMultipleItemsPerSlide) {
1001
- const maxItemsForSlide = getMaximumItemsForSlide(enableDisplayMultipleItemsPerSlide, viewport);
1002
- if (index >= activeIndex * maxItemsForSlide - 1 && index < activeIndex * maxItemsForSlide + maxItemsForSlide + 1) {
1003
- hidden = false;
1004
- } else {
1005
- hidden = true;
1006
- }
1007
- } else if (index >= activeIndex - 1 && index <= activeIndex + 1) {
1008
- hidden = false;
1009
- }
1064
+ hidden = false;
1010
1065
  } else if (!enablePeeking && enableDisplayMultipleItemsPerSlide && !isAnimating) {
1011
1066
  const maxItemsForSlide = getMaximumItemsForSlide(enableDisplayMultipleItemsPerSlide, viewport);
1012
1067
  if (index >= activeIndex * maxItemsForSlide && index < activeIndex * maxItemsForSlide + maxItemsForSlide) {
@@ -1028,7 +1083,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
1028
1083
  })
1029
1084
  })
1030
1085
  }), showPreviousNextNavigation && totalItems > 1 ? /*#__PURE__*/_jsx(View, {
1031
- style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, false, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport),
1086
+ style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, false, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport, maxWidth, currentViewportWidth),
1032
1087
  testID: "next-button-container",
1033
1088
  children: /*#__PURE__*/_jsx(IconButton, {
1034
1089
  onLayout: onPreviousNextNavigationButtonLayout,
@@ -1040,7 +1095,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
1040
1095
  })
1041
1096
  }) : null]
1042
1097
  }), /*#__PURE__*/_jsx(View, {
1043
- style: selectNavigationStyles(tabs, enableHero, viewport),
1098
+ style: selectNavigationStyles(tabs, enableHero, viewport, enablePeeking, maxWidth),
1044
1099
  children: showPanelNavigation ? activePanelNavigation : null
1045
1100
  })]
1046
1101
  })
@@ -14,7 +14,9 @@ const CarouselProvider = _ref => {
14
14
  themeTokens,
15
15
  totalItems,
16
16
  width,
17
- maximumItemsForSlide
17
+ maximumItemsForSlide,
18
+ maxWidth,
19
+ viewportWidth
18
20
  } = _ref;
19
21
  const value = React.useMemo(() => ({
20
22
  activeIndex,
@@ -25,8 +27,10 @@ const CarouselProvider = _ref => {
25
27
  themeTokens,
26
28
  totalItems,
27
29
  width,
28
- maximumItemsForSlide
29
- }), [activeIndex, goTo, getCopyWithPlaceholders, itemLabel, refocus, totalItems, themeTokens, width, maximumItemsForSlide]);
30
+ maximumItemsForSlide,
31
+ maxWidth,
32
+ viewportWidth
33
+ }), [activeIndex, goTo, getCopyWithPlaceholders, itemLabel, refocus, totalItems, themeTokens, width, maximumItemsForSlide, maxWidth, viewportWidth]);
30
34
  return /*#__PURE__*/_jsx(CarouselContext.Provider, {
31
35
  value: value,
32
36
  children: children
@@ -49,6 +53,8 @@ CarouselProvider.propTypes = {
49
53
  themeTokens: getTokensPropType('Carousel'),
50
54
  totalItems: PropTypes.number.isRequired,
51
55
  width: PropTypes.number.isRequired,
52
- maximumItemsForSlide: PropTypes.number
56
+ maximumItemsForSlide: PropTypes.number,
57
+ maxWidth: PropTypes.number,
58
+ viewportWidth: PropTypes.number
53
59
  };
54
60
  export { CarouselProvider, useCarousel };
@@ -12,26 +12,26 @@ const selectContainerStyle = _ref => {
12
12
  width,
13
13
  elementIndex,
14
14
  enablePeeking,
15
- peekingMarginLeft,
16
15
  peekingGap,
17
16
  hidden,
18
17
  enableDisplayMultipleItemsPerSlide,
19
18
  viewport,
20
- peekingMiddleSpace
19
+ peekingMiddleSpace,
20
+ maxWidth,
21
+ viewportWidth
21
22
  } = _ref;
22
23
  let adjustedWidth = width;
23
24
  let marginLeft = 0;
24
25
  if (enablePeeking) {
25
26
  const isFirst = elementIndex === 0;
26
- adjustedWidth = width - (peekingMiddleSpace * 2 + peekingGap * 2);
27
+ const baseWidth = maxWidth || width;
28
+ adjustedWidth = baseWidth - peekingMiddleSpace * 2;
27
29
  if (isFirst) {
28
- marginLeft = peekingMarginLeft;
30
+ marginLeft = peekingMiddleSpace + (viewportWidth - maxWidth) / 2;
29
31
  } else {
30
32
  marginLeft = peekingGap;
31
33
  }
32
34
  }
33
-
34
- // Adjust width and margins for multiple items per slide.
35
35
  if (enableDisplayMultipleItemsPerSlide) {
36
36
  switch (viewport) {
37
37
  case 'xs':
@@ -89,7 +89,9 @@ const CarouselItem = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
89
89
  width,
90
90
  activeIndex,
91
91
  goTo,
92
- maximumItemsForSlide
92
+ maximumItemsForSlide,
93
+ maxWidth,
94
+ viewportWidth
93
95
  } = useCarousel();
94
96
  const selectedProps = selectProps({
95
97
  ...rest,
@@ -132,6 +134,8 @@ const CarouselItem = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
132
134
  enablePeeking,
133
135
  enableDisplayMultipleItemsPerSlide,
134
136
  viewport,
137
+ maxWidth,
138
+ viewportWidth,
135
139
  ...peekingProps
136
140
  }),
137
141
  ...selectedProps,
@@ -19,4 +19,13 @@ export const SWIPE_RELEASE_STYLES = {
19
19
  EASE_OUT: 'ease-out'
20
20
  };
21
21
  export const INSTANT_ANIMATION_DURATION = 1;
22
- export const DEFAULT_SWIPE_RELEASE_DURATION = 500;
22
+ export const DEFAULT_SWIPE_RELEASE_DURATION = 500;
23
+ export const POSITION_VARIANTS = {
24
+ EDGE: 'edge',
25
+ INSIDE: 'inside',
26
+ OUTSIDE: 'outside'
27
+ };
28
+ export const POSITION_PROPERTIES = {
29
+ LEFT: 'left',
30
+ RIGHT: 'right'
31
+ };
@@ -114,6 +114,32 @@ const selectFeedbackTokens = _ref5 => {
114
114
  feedbackMarginTop
115
115
  };
116
116
  };
117
+ const selectPressableStyles = _ref6 => {
118
+ let {
119
+ padding,
120
+ paddingLeft,
121
+ paddingRight,
122
+ paddingTop,
123
+ paddingBottom
124
+ } = _ref6;
125
+ return {
126
+ padding,
127
+ paddingLeft,
128
+ paddingRight,
129
+ paddingTop,
130
+ paddingBottom
131
+ };
132
+ };
133
+ const selectContainerStyles = _ref7 => {
134
+ let {
135
+ iconContainerHeight,
136
+ iconContainerWidth
137
+ } = _ref7;
138
+ return {
139
+ height: iconContainerHeight,
140
+ width: iconContainerWidth
141
+ };
142
+ };
117
143
 
118
144
  /**
119
145
  * Basic Checkbox component.
@@ -150,7 +176,7 @@ const selectFeedbackTokens = _ref5 => {
150
176
  * or the internal state in case of uncontrolled checkbox.
151
177
  *
152
178
  */
153
- const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
179
+ const Checkbox = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
154
180
  let {
155
181
  checked,
156
182
  defaultChecked,
@@ -165,8 +191,9 @@ const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
165
191
  tokens,
166
192
  value,
167
193
  variant,
194
+ testID,
168
195
  ...rest
169
- } = _ref6;
196
+ } = _ref8;
170
197
  const {
171
198
  currentValue: isChecked,
172
199
  setValue: setIsChecked,
@@ -223,17 +250,18 @@ const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
223
250
  direction: feedbackPosition === 'top' ? 'column-reverse' : 'column',
224
251
  space: 0,
225
252
  children: [/*#__PURE__*/_jsx(Pressable, {
253
+ testID: testID && `${testID}-pressable`,
226
254
  disabled: inactive,
227
255
  onKeyDown: handleKeyDown,
228
256
  onPress: handleChange,
229
257
  ...selectedProps,
230
- style: staticStyles.removeOutline,
231
- children: _ref7 => {
258
+ style: [staticStyles.removeOutline, selectPressableStyles(defaultTokens)],
259
+ children: _ref9 => {
232
260
  let {
233
261
  focused: focus,
234
262
  hovered: hover,
235
263
  pressed
236
- } = _ref7;
264
+ } = _ref9;
237
265
  const {
238
266
  icon: IconComponent,
239
267
  ...stateTokens
@@ -244,15 +272,12 @@ const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
244
272
  });
245
273
  const iconTokens = selectIconTokens(stateTokens);
246
274
  const labelStyles = selectLabelStyles(stateTokens, themeOptions);
247
- const alignWithLabel = label ? [staticStyles.alignWithLabel, {
248
- height: labelStyles.lineHeight
249
- }] : null;
250
275
  return /*#__PURE__*/_jsxs(StackView, {
251
276
  space: 0,
252
277
  children: [/*#__PURE__*/_jsxs(View, {
253
278
  style: staticStyles.container,
254
279
  children: [/*#__PURE__*/_jsx(View, {
255
- style: alignWithLabel,
280
+ style: [staticStyles.iconContainer, selectContainerStyles(stateTokens)],
256
281
  children: /*#__PURE__*/_jsxs(View, {
257
282
  style: [staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)],
258
283
  testID: "Checkbox-Input",
@@ -351,7 +376,11 @@ Checkbox.propTypes = {
351
376
  /**
352
377
  * An optional Checkbox description.
353
378
  */
354
- description: PropTypes.string
379
+ description: PropTypes.string,
380
+ /**
381
+ * A identifier for testing purposes.
382
+ */
383
+ testID: PropTypes.string
355
384
  };
356
385
  export default Checkbox;
357
386
  const staticStyles = StyleSheet.create({
@@ -366,9 +395,10 @@ const staticStyles = StyleSheet.create({
366
395
  alignItems: 'center',
367
396
  justifyContent: 'center'
368
397
  },
369
- alignWithLabel: {
370
- alignSelf: 'flex-start',
371
- justifyContent: 'center'
398
+ iconContainer: {
399
+ display: 'flex',
400
+ justifyContent: 'center',
401
+ alignItems: 'center'
372
402
  },
373
403
  removeOutline: {
374
404
  outlineStyle: 'none'
@@ -57,7 +57,11 @@ function selectIconContainerStyles(_ref2) {
57
57
  const paddingSide = iconPosition === 'right' ? 'paddingLeft' : 'paddingRight';
58
58
  return {
59
59
  [paddingSide]: iconGap,
60
- paddingTop: iconPaddingTop
60
+ ...(iconPaddingTop && {
61
+ transform: [{
62
+ translateY: iconPaddingTop
63
+ }]
64
+ })
61
65
  };
62
66
  }
63
67
  function selectTextContainerStyles(_ref3) {
@@ -6,13 +6,22 @@ import { useThemeTokens } from '../ThemeProvider';
6
6
  import { a11yProps, getTokensPropType, selectSystemProps, useMultipleInputValues, variantProp, viewProps, contentfulProps, useUniqueId } from '../utils';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
8
8
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps, contentfulProps]);
9
- function selectBorderStyles(tokens) {
9
+ const selectWrapperStyles = _ref => {
10
+ let {
11
+ borderWidth,
12
+ borderTopWidth,
13
+ borderStyle,
14
+ borderColor
15
+ } = _ref;
10
16
  return {
11
- borderBottomWidth: tokens.borderWidth,
12
- borderBottomStyle: tokens.borderStyle,
13
- borderBottomColor: tokens.borderColor
17
+ borderStyle,
18
+ borderColor,
19
+ borderTopWidth,
20
+ borderBottomWidth: borderWidth,
21
+ borderBottomStyle: borderStyle,
22
+ borderBottomColor: borderColor
14
23
  };
15
- }
24
+ };
16
25
 
17
26
  /**
18
27
  * Flexible base component for lists where some or all items are collapsible headers.
@@ -21,7 +30,7 @@ function selectBorderStyles(tokens) {
21
30
  * <ExpandCollapse.Panel> children, and assign the panels explicit `panelId` props. The panels may be
22
31
  * nested (they do not need to be direct children), and non-interactive items may be included too.
23
32
  */
24
- const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref, ref) => {
33
+ const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
25
34
  let {
26
35
  children,
27
36
  tokens,
@@ -32,7 +41,7 @@ const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref, ref) => {
32
41
  onChange,
33
42
  dataSet,
34
43
  ...rest
35
- } = _ref;
44
+ } = _ref2;
36
45
  const instanceId = useUniqueId('ExpandCollapse');
37
46
  const {
38
47
  currentValues: openIds,
@@ -53,7 +62,7 @@ const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref, ref) => {
53
62
  ...selectProps(rest),
54
63
  dataSet: dataSet,
55
64
  children: /*#__PURE__*/_jsx(View, {
56
- style: selectBorderStyles(themeTokens),
65
+ style: selectWrapperStyles(themeTokens),
57
66
  children: typeof children === 'function' ? children({
58
67
  openIds,
59
68
  onToggle,
@@ -103,6 +103,7 @@ const ExpandCollapsePanel = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
103
103
  controlRef,
104
104
  content,
105
105
  copy = 'en',
106
+ disableMobileScrollBuffer = false,
106
107
  ...rest
107
108
  } = _ref5;
108
109
  const [containerHeight, setContainerHeight] = React.useState(null);
@@ -124,7 +125,7 @@ const ExpandCollapsePanel = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
124
125
 
125
126
  // on mobile devices we require a scroll buffer equal to the font size
126
127
  // to avoid triggering scrolling unnecessarily
127
- const mobileScrollBuffer = Platform.OS === 'web' ? 0 : selectTextStyles(themeTokens)?.fontSize;
128
+ const mobileScrollBuffer = Platform.OS === 'web' || disableMobileScrollBuffer ? 0 : selectTextStyles(themeTokens)?.fontSize;
128
129
  const handleControlPress = event => {
129
130
  onToggle?.(panelId, event);
130
131
  if (onPress) onPress(panelId, event);
@@ -271,6 +272,10 @@ ExpandCollapsePanel.propTypes = {
271
272
  /**
272
273
  * A boolean prop to determine if the panel is a content panel or not. If true, the panel will not have a control
273
274
  */
274
- content: PropTypes.bool
275
+ content: PropTypes.bool,
276
+ /**
277
+ * A boolean prop to disable the extra scroll buffer on mobile devices (only applicable on iOS/Android, ignored on web)
278
+ */
279
+ disableMobileScrollBuffer: PropTypes.bool
275
280
  };
276
281
  export default ExpandCollapsePanel;