@hero-design/rn 8.30.3 → 8.30.4

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.
package/lib/index.js CHANGED
@@ -11588,12 +11588,18 @@ var Carousel = function Carousel(_ref) {
11588
11588
  clearTimeout(handle);
11589
11589
  };
11590
11590
  }, [currentSlideIndex, carouselRef]);
11591
- var visibleSlideChanged = React.useCallback(function (_ref2) {
11592
- var viewableItems = _ref2.viewableItems;
11593
- if (!viewableItems || viewableItems && !viewableItems.length) return;
11594
- var index = viewableItems[0].index;
11591
+ var handleMomentumScrollEnd = function handleMomentumScrollEnd(event) {
11592
+ // Calculate the current index based on the scroll position and container width
11593
+ var containerWidth = event.nativeEvent.layoutMeasurement.width;
11594
+ var scrollPosition = event.nativeEvent.contentOffset.x;
11595
+ /**
11596
+ * By rounding down, we ensure that any partial visibility of the next item does not affect the index value
11597
+ * This helps maintain consistent behavior and aligns with the desired functionality of considering the left-most visible item as the current item.
11598
+ */
11599
+ var index = Math.floor(scrollPosition / containerWidth);
11600
+ // Call the callback function with the current index
11595
11601
  internalOnItemIndexChange(index);
11596
- }, []);
11602
+ };
11597
11603
  var viewConfig = React.useRef({
11598
11604
  viewAreaCoveragePercentThreshold: 50
11599
11605
  }).current;
@@ -11610,7 +11616,7 @@ var Carousel = function Carousel(_ref) {
11610
11616
  pagingEnabled: true,
11611
11617
  bounces: false,
11612
11618
  data: items,
11613
- onViewableItemsChanged: visibleSlideChanged,
11619
+ onMomentumScrollEnd: handleMomentumScrollEnd,
11614
11620
  viewabilityConfig: viewConfig,
11615
11621
  scrollEventThrottle: 32,
11616
11622
  ref: carouselRef,
@@ -11623,8 +11629,8 @@ var Carousel = function Carousel(_ref) {
11623
11629
  }], {
11624
11630
  useNativeDriver: false
11625
11631
  }),
11626
- renderItem: function renderItem(_ref3) {
11627
- var item = _ref3.item;
11632
+ renderItem: function renderItem(_ref2) {
11633
+ var item = _ref2.item;
11628
11634
  if (!item) return null;
11629
11635
  var image = item.image,
11630
11636
  heading = item.heading,
@@ -13004,9 +13010,11 @@ var AnimatedFABIcon = function AnimatedFABIcon(_ref) {
13004
13010
  iconProps = _objectWithoutProperties(_ref, _excluded$c);
13005
13011
  var rotateAnimation = React.useRef(new reactNative.Animated.Value(active ? 1 : 0));
13006
13012
  React.useEffect(function () {
13007
- var animation = reactNative.Animated.spring(rotateAnimation.current, {
13013
+ var animation = reactNative.Animated.timing(rotateAnimation.current, {
13008
13014
  toValue: active ? 1 : 0,
13009
- useNativeDriver: reactNative.Platform.OS === 'ios' || reactNative.Platform.OS === 'android'
13015
+ useNativeDriver: reactNative.Platform.OS === 'ios' || reactNative.Platform.OS === 'android',
13016
+ easing: reactNative.Easing.inOut(reactNative.Easing.ease),
13017
+ duration: 300
13010
13018
  });
13011
13019
  animation.start();
13012
13020
  return function () {
@@ -13028,11 +13036,6 @@ var AnimatedFABIcon = function AnimatedFABIcon(_ref) {
13028
13036
  }, iconProps)));
13029
13037
  };
13030
13038
 
13031
- if (reactNative.Platform.OS === 'android') {
13032
- if (reactNative.UIManager.setLayoutAnimationEnabledExperimental) {
13033
- reactNative.UIManager.setLayoutAnimationEnabledExperimental(true);
13034
- }
13035
- }
13036
13039
  var IconOnlyContent = function IconOnlyContent(_ref) {
13037
13040
  var icon = _ref.icon,
13038
13041
  animated = _ref.animated,
@@ -13058,19 +13061,7 @@ var IconWithTextContent = function IconWithTextContent(_ref2) {
13058
13061
  testID: "styled-fab-icon"
13059
13062
  })), /*#__PURE__*/React__default["default"].createElement(StyledFABText, null, title));
13060
13063
  };
13061
- var defaultAnimation = {
13062
- create: {
13063
- type: 'easeInEaseOut',
13064
- property: 'opacity'
13065
- },
13066
- update: {
13067
- type: 'spring',
13068
- springDamping: 1
13069
- },
13070
- duration: 400
13071
- };
13072
- var FAB = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
13073
- var _StyleSheet$flatten, _StyleSheet$flatten2;
13064
+ var FAB = function FAB(_ref3) {
13074
13065
  var onPress = _ref3.onPress,
13075
13066
  title = _ref3.title,
13076
13067
  icon = _ref3.icon,
@@ -13078,75 +13069,22 @@ var FAB = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
13078
13069
  testID = _ref3.testID,
13079
13070
  active = _ref3.active,
13080
13071
  style = _ref3.style;
13072
+ var isIconOnly = !title;
13081
13073
  var theme = useTheme();
13082
- var _React$useState = React__default["default"].useState({
13083
- hideTitle: false,
13084
- hideButton: false
13085
- }),
13086
- _React$useState2 = _slicedToArray(_React$useState, 2),
13087
- displayState = _React$useState2[0],
13088
- setDisplayState = _React$useState2[1];
13089
- var _React$useState3 = React__default["default"].useState(false),
13090
- _React$useState4 = _slicedToArray(_React$useState3, 2),
13091
- canAnimate = _React$useState4[0],
13092
- setCanAnimate = _React$useState4[1];
13093
- var isIconOnly = displayState.hideTitle || active || !title;
13094
- React.useImperativeHandle(ref, function () {
13095
- return {
13096
- show: function show() {
13097
- setDisplayState({
13098
- hideButton: false,
13099
- hideTitle: false
13100
- });
13101
- },
13102
- collapse: function collapse() {
13103
- setDisplayState({
13104
- hideButton: false,
13105
- hideTitle: true
13106
- });
13107
- },
13108
- hide: function hide() {
13109
- setDisplayState(function (previousState) {
13110
- return _objectSpread2(_objectSpread2({}, previousState), {}, {
13111
- hideButton: true
13112
- });
13113
- });
13114
- }
13115
- };
13116
- }, [displayState]);
13117
- React.useEffect(function () {
13118
- if (canAnimate) {
13119
- reactNative.LayoutAnimation.configureNext(defaultAnimation);
13120
- }
13121
- }, [isIconOnly]);
13122
- React.useEffect(function () {
13123
- if (canAnimate) {
13124
- reactNative.LayoutAnimation.configureNext(defaultAnimation);
13125
- }
13126
- }, [displayState.hideButton]);
13127
- var marginBottom = Number((_StyleSheet$flatten = reactNative.StyleSheet.flatten(style)) === null || _StyleSheet$flatten === void 0 ? void 0 : _StyleSheet$flatten.marginBottom) || 0;
13128
- return /*#__PURE__*/React__default["default"].createElement(StyledFAB$1
13129
- /** Add a small timeout before executing animation to prevent flakiness on android */, {
13130
- onLayout: function onLayout() {
13131
- return setTimeout(function () {
13132
- return setCanAnimate(true);
13133
- }, 200);
13134
- },
13074
+ return /*#__PURE__*/React__default["default"].createElement(StyledFAB$1, {
13135
13075
  underlayColor: theme.__hd__.fab.colors.buttonPressedBackground,
13136
13076
  onPress: onPress,
13137
- style: [style, {
13138
- bottom: displayState.hideButton ? -(marginBottom + theme.__hd__.fab.sizes.height * 2) : (_StyleSheet$flatten2 = reactNative.StyleSheet.flatten(style)) === null || _StyleSheet$flatten2 === void 0 ? void 0 : _StyleSheet$flatten2.bottom
13139
- }],
13077
+ style: style,
13140
13078
  testID: testID
13141
13079
  }, isIconOnly ? /*#__PURE__*/React__default["default"].createElement(IconOnlyContent, {
13142
13080
  animated: animated,
13143
13081
  active: active,
13144
- icon: active ? 'add' : icon
13082
+ icon: icon
13145
13083
  }) : /*#__PURE__*/React__default["default"].createElement(IconWithTextContent, {
13146
13084
  icon: icon,
13147
13085
  title: title
13148
13086
  }));
13149
- });
13087
+ };
13150
13088
 
13151
13089
  var StyledActionItem = index$a(reactNative.TouchableHighlight)(function (_ref) {
13152
13090
  var theme = _ref.theme;
@@ -13243,55 +13181,40 @@ var StyledHeaderText = index$a(Typography.Text)(function (_ref3) {
13243
13181
  };
13244
13182
  });
13245
13183
 
13246
- var ActionGroup = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
13247
- var headerTitle = _ref.headerTitle,
13248
- onPress = _ref.onPress,
13249
- active = _ref.active,
13250
- style = _ref.style,
13251
- items = _ref.items,
13252
- testID = _ref.testID,
13253
- fabTitle = _ref.fabTitle,
13254
- _ref$fabIcon = _ref.fabIcon,
13255
- fabIcon = _ref$fabIcon === void 0 ? 'add' : _ref$fabIcon;
13256
- var fabRef = React.useRef(null);
13184
+ var ActionItemsListComponent = function ActionItemsListComponent(_ref) {
13185
+ var style = _ref.style,
13186
+ items = _ref.items;
13187
+ return /*#__PURE__*/React__default["default"].createElement(reactNative.View, {
13188
+ style: style
13189
+ }, items === null || items === void 0 ? void 0 : items.map(function (itemProp) {
13190
+ return /*#__PURE__*/React__default["default"].createElement(ActionItem, _extends$1({
13191
+ key: itemProp.key || "".concat(itemProp.icon, "_").concat(itemProp.title)
13192
+ }, itemProp));
13193
+ }));
13194
+ };
13195
+ var ActionGroup = function ActionGroup(_ref2) {
13196
+ var headerTitle = _ref2.headerTitle,
13197
+ onPress = _ref2.onPress,
13198
+ active = _ref2.active,
13199
+ style = _ref2.style,
13200
+ items = _ref2.items,
13201
+ testID = _ref2.testID,
13202
+ fabTitle = _ref2.fabTitle,
13203
+ _ref2$fabIcon = _ref2.fabIcon,
13204
+ fabIcon = _ref2$fabIcon === void 0 ? 'add' : _ref2$fabIcon;
13257
13205
  var tranlateXAnimation = React.useRef(new reactNative.Animated.Value(active ? 1 : 0));
13258
- var animatedValues = React.useRef((items === null || items === void 0 ? void 0 : items.map(function () {
13259
- return new reactNative.Animated.Value(0);
13260
- })) || []).current;
13261
- var translateYAnimations = animatedValues === null || animatedValues === void 0 ? void 0 : animatedValues.map(function (value) {
13262
- return value.interpolate({
13263
- inputRange: [0, 1],
13264
- outputRange: active ? [100, 0] : [40, 0]
13265
- });
13266
- });
13267
- React.useImperativeHandle(ref, function () {
13268
- return {
13269
- showFAB: function showFAB() {
13270
- var _fabRef$current;
13271
- return (_fabRef$current = fabRef.current) === null || _fabRef$current === void 0 ? void 0 : _fabRef$current.show();
13272
- },
13273
- collapseFAB: function collapseFAB() {
13274
- var _fabRef$current2;
13275
- return (_fabRef$current2 = fabRef.current) === null || _fabRef$current2 === void 0 ? void 0 : _fabRef$current2.collapse();
13276
- },
13277
- hideFAB: function hideFAB() {
13278
- var _fabRef$current3;
13279
- return (_fabRef$current3 = fabRef.current) === null || _fabRef$current3 === void 0 ? void 0 : _fabRef$current3.hide();
13280
- }
13281
- };
13282
- }, [fabRef]);
13283
13206
  React.useEffect(function () {
13284
- reactNative.Animated.spring(tranlateXAnimation.current, {
13207
+ var animation = reactNative.Animated.timing(tranlateXAnimation.current, {
13285
13208
  toValue: active ? 1 : 0,
13286
- useNativeDriver: reactNative.Platform.OS !== 'web'
13287
- }).start();
13288
- reactNative.Animated.stagger(20, animatedValues.map(function (value) {
13289
- return reactNative.Animated.spring(value, {
13290
- toValue: active ? 1 : 0,
13291
- useNativeDriver: reactNative.Platform.OS !== 'web'
13292
- });
13293
- }).reverse()).start();
13294
- }, [active, animatedValues]);
13209
+ useNativeDriver: reactNative.Platform.OS === 'ios' || reactNative.Platform.OS === 'android',
13210
+ easing: reactNative.Easing.inOut(reactNative.Easing.cubic)
13211
+ });
13212
+ animation.start();
13213
+ }, [active]);
13214
+ var interpolatedTranlateXAnimation = tranlateXAnimation.current.interpolate({
13215
+ inputRange: [0, 1],
13216
+ outputRange: [400, 0]
13217
+ });
13295
13218
  var interpolatedBackdropOpacityAnimation = tranlateXAnimation.current.interpolate({
13296
13219
  inputRange: [0, 1],
13297
13220
  outputRange: [0, 0.4]
@@ -13314,39 +13237,24 @@ var ActionGroup = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
13314
13237
  pointerEvents: active ? 'auto' : 'none',
13315
13238
  testID: "action-group",
13316
13239
  style: {
13317
- opacity: interpolatedActionGroupOpacityAnimation
13318
- }
13319
- }, !!headerTitle && /*#__PURE__*/React__default["default"].createElement(reactNative.Animated.View, {
13320
- style: {
13240
+ opacity: interpolatedActionGroupOpacityAnimation,
13321
13241
  transform: [{
13322
- translateY: translateYAnimations[0]
13242
+ translateX: interpolatedTranlateXAnimation
13323
13243
  }]
13324
13244
  }
13325
- }, /*#__PURE__*/React__default["default"].createElement(StyledHeaderText, {
13245
+ }, !!headerTitle && /*#__PURE__*/React__default["default"].createElement(StyledHeaderText, {
13326
13246
  testID: "header-text"
13327
- }, headerTitle)), /*#__PURE__*/React__default["default"].createElement(Box, {
13328
- style: [style, {
13329
- paddingBottom: 0
13330
- }]
13331
- }, items === null || items === void 0 ? void 0 : items.map(function (itemProp, index) {
13332
- return /*#__PURE__*/React__default["default"].createElement(reactNative.Animated.View, {
13333
- key: itemProp.key || "".concat(itemProp.icon, "_").concat(itemProp.title),
13334
- style: {
13335
- transform: [{
13336
- translateY: translateYAnimations[index]
13337
- }]
13338
- }
13339
- }, /*#__PURE__*/React__default["default"].createElement(ActionItem, itemProp));
13340
- }))), /*#__PURE__*/React__default["default"].createElement(StyledFAB, {
13247
+ }, headerTitle), /*#__PURE__*/React__default["default"].createElement(ActionItemsListComponent, {
13248
+ items: items
13249
+ })), /*#__PURE__*/React__default["default"].createElement(StyledFAB, {
13341
13250
  testID: "fab",
13342
13251
  icon: fabIcon,
13343
13252
  onPress: onPress,
13344
13253
  animated: true,
13345
13254
  active: active,
13346
- title: fabTitle,
13347
- ref: fabRef
13255
+ title: fabTitle
13348
13256
  }));
13349
- });
13257
+ };
13350
13258
 
13351
13259
  var index$6 = Object.assign(FAB, {
13352
13260
  ActionGroup: ActionGroup
@@ -15029,7 +14937,7 @@ var getGradientColors = function getGradientColors(theme, intent) {
15029
14937
  }
15030
14938
  };
15031
14939
  var Skeleton = function Skeleton(_ref) {
15032
- var _StyleSheet$flatten, _StyleSheet$flatten2;
14940
+ var _StyleSheet$flatten;
15033
14941
  var _ref$intent = _ref.intent,
15034
14942
  intent = _ref$intent === void 0 ? 'light' : _ref$intent,
15035
14943
  _ref$variant = _ref.variant,
@@ -15045,14 +14953,10 @@ var Skeleton = function Skeleton(_ref) {
15045
14953
  _useState2 = _slicedToArray(_useState, 2),
15046
14954
  containerWidth = _useState2[0],
15047
14955
  setContainerWidth = _useState2[1];
15048
- var _useState3 = React.useState(Number((_StyleSheet$flatten2 = reactNative.StyleSheet.flatten(style)) === null || _StyleSheet$flatten2 === void 0 ? void 0 : _StyleSheet$flatten2.height) || 0),
14956
+ var _useState3 = React.useState(false),
15049
14957
  _useState4 = _slicedToArray(_useState3, 2),
15050
- containerHeight = _useState4[0],
15051
- setContainerHeight = _useState4[1];
15052
- var _useState5 = React.useState(false),
15053
- _useState6 = _slicedToArray(_useState5, 2),
15054
- shouldStartAnimation = _useState6[0],
15055
- setShouldStartAnimation = _useState6[1];
14958
+ shouldStartAnimation = _useState4[0],
14959
+ setShouldStartAnimation = _useState4[1];
15056
14960
  var animatedValue = React.useRef(new reactNative.Animated.Value(0)).current;
15057
14961
  React.useEffect(function () {
15058
14962
  if (shouldStartAnimation) {
@@ -15069,10 +14973,7 @@ var Skeleton = function Skeleton(_ref) {
15069
14973
  outputRange: [-containerWidth, containerWidth]
15070
14974
  });
15071
14975
  var onContainerLayout = React.useCallback(function (e) {
15072
- var _e$nativeEvent$layout = e.nativeEvent.layout,
15073
- width = _e$nativeEvent$layout.width,
15074
- height = _e$nativeEvent$layout.height;
15075
- setContainerHeight(height);
14976
+ var width = e.nativeEvent.layout.width;
15076
14977
  setContainerWidth(width);
15077
14978
  if (!shouldStartAnimation) {
15078
14979
  setShouldStartAnimation(true);
@@ -15090,8 +14991,8 @@ var Skeleton = function Skeleton(_ref) {
15090
14991
  start: gradientPositions.start,
15091
14992
  end: gradientPositions.end,
15092
14993
  style: {
15093
- width: containerWidth,
15094
- height: containerHeight,
14994
+ width: '100%',
14995
+ height: '100%',
15095
14996
  transform: [{
15096
14997
  translateX: translateX
15097
14998
  }]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.30.3",
3
+ "version": "8.30.4",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -21,7 +21,7 @@
21
21
  "dependencies": {
22
22
  "@emotion/native": "^11.9.3",
23
23
  "@emotion/react": "^11.9.3",
24
- "@hero-design/colors": "8.30.3",
24
+ "@hero-design/colors": "8.30.4",
25
25
  "date-fns": "^2.16.1",
26
26
  "events": "^3.2.0",
27
27
  "hero-editor": "^1.9.21"
@@ -45,7 +45,7 @@
45
45
  "@babel/preset-typescript": "^7.17.12",
46
46
  "@babel/runtime": "^7.18.9",
47
47
  "@emotion/jest": "^11.9.3",
48
- "@hero-design/eslint-plugin": "8.30.3",
48
+ "@hero-design/eslint-plugin": "8.30.4",
49
49
  "@react-native-community/datetimepicker": "^3.5.2",
50
50
  "@react-native-community/slider": "4.1.12",
51
51
  "@rollup/plugin-babel": "^5.3.1",
@@ -61,10 +61,10 @@
61
61
  "@types/react-native": "^0.67.7",
62
62
  "@types/react-native-vector-icons": "^6.4.10",
63
63
  "babel-plugin-inline-import": "^3.0.0",
64
- "eslint-config-hd": "8.30.3",
64
+ "eslint-config-hd": "8.30.4",
65
65
  "eslint-plugin-import": "^2.27.5",
66
66
  "jest": "^27.3.1",
67
- "prettier-config-hd": "8.30.3",
67
+ "prettier-config-hd": "8.30.4",
68
68
  "react": "18.0.0",
69
69
  "react-native": "0.69.7",
70
70
  "react-native-gesture-handler": "~2.1.0",
@@ -99,7 +99,6 @@ exports[`Carousel renders correctly with pageControlPosition bottom 1`] = `
99
99
  onScroll={[Function]}
100
100
  onScrollBeginDrag={[Function]}
101
101
  onScrollEndDrag={[Function]}
102
- onViewableItemsChanged={[Function]}
103
102
  pagingEnabled={true}
104
103
  removeClippedSubviews={false}
105
104
  renderItem={[Function]}
@@ -111,16 +110,7 @@ exports[`Carousel renders correctly with pageControlPosition bottom 1`] = `
111
110
  "viewAreaCoveragePercentThreshold": 50,
112
111
  }
113
112
  }
114
- viewabilityConfigCallbackPairs={
115
- Array [
116
- Object {
117
- "onViewableItemsChanged": [Function],
118
- "viewabilityConfig": Object {
119
- "viewAreaCoveragePercentThreshold": 50,
120
- },
121
- },
122
- ]
123
- }
113
+ viewabilityConfigCallbackPairs={Array []}
124
114
  >
125
115
  <View>
126
116
  <View
@@ -933,7 +923,6 @@ exports[`Carousel renders correctly with pageControlPosition top 1`] = `
933
923
  onScroll={[Function]}
934
924
  onScrollBeginDrag={[Function]}
935
925
  onScrollEndDrag={[Function]}
936
- onViewableItemsChanged={[Function]}
937
926
  pagingEnabled={true}
938
927
  removeClippedSubviews={false}
939
928
  renderItem={[Function]}
@@ -945,16 +934,7 @@ exports[`Carousel renders correctly with pageControlPosition top 1`] = `
945
934
  "viewAreaCoveragePercentThreshold": 50,
946
935
  }
947
936
  }
948
- viewabilityConfigCallbackPairs={
949
- Array [
950
- Object {
951
- "onViewableItemsChanged": [Function],
952
- "viewabilityConfig": Object {
953
- "viewAreaCoveragePercentThreshold": 50,
954
- },
955
- },
956
- ]
957
- }
937
+ viewabilityConfigCallbackPairs={Array []}
958
938
  >
959
939
  <View>
960
940
  <View
@@ -1620,7 +1600,6 @@ exports[`Carousel should call skip call back when press skip 1`] = `
1620
1600
  onScroll={[Function]}
1621
1601
  onScrollBeginDrag={[Function]}
1622
1602
  onScrollEndDrag={[Function]}
1623
- onViewableItemsChanged={[Function]}
1624
1603
  pagingEnabled={true}
1625
1604
  removeClippedSubviews={false}
1626
1605
  renderItem={[Function]}
@@ -1632,16 +1611,7 @@ exports[`Carousel should call skip call back when press skip 1`] = `
1632
1611
  "viewAreaCoveragePercentThreshold": 50,
1633
1612
  }
1634
1613
  }
1635
- viewabilityConfigCallbackPairs={
1636
- Array [
1637
- Object {
1638
- "onViewableItemsChanged": [Function],
1639
- "viewabilityConfig": Object {
1640
- "viewAreaCoveragePercentThreshold": 50,
1641
- },
1642
- },
1643
- ]
1644
- }
1614
+ viewabilityConfigCallbackPairs={Array []}
1645
1615
  >
1646
1616
  <View>
1647
1617
  <View
@@ -9,6 +9,8 @@ import React, {
9
9
  import {
10
10
  Animated,
11
11
  FlatList,
12
+ NativeScrollEvent,
13
+ NativeSyntheticEvent,
12
14
  StyleProp,
13
15
  useWindowDimensions,
14
16
  View,
@@ -127,11 +129,22 @@ const Carousel = ({
127
129
  };
128
130
  }, [currentSlideIndex, carouselRef]);
129
131
 
130
- const visibleSlideChanged = useCallback(({ viewableItems }) => {
131
- if (!viewableItems || (viewableItems && !viewableItems.length)) return;
132
- const { index } = viewableItems[0];
132
+ const handleMomentumScrollEnd = (
133
+ event: NativeSyntheticEvent<NativeScrollEvent>
134
+ ) => {
135
+ // Calculate the current index based on the scroll position and container width
136
+ const containerWidth = event.nativeEvent.layoutMeasurement.width;
137
+ const scrollPosition = event.nativeEvent.contentOffset.x;
138
+
139
+ /**
140
+ * By rounding down, we ensure that any partial visibility of the next item does not affect the index value
141
+ * This helps maintain consistent behavior and aligns with the desired functionality of considering the left-most visible item as the current item.
142
+ */
143
+ const index = Math.floor(scrollPosition / containerWidth);
144
+
145
+ // Call the callback function with the current index
133
146
  internalOnItemIndexChange(index);
134
- }, []);
147
+ };
135
148
 
136
149
  const viewConfig = useRef({ viewAreaCoveragePercentThreshold: 50 }).current;
137
150
 
@@ -158,7 +171,7 @@ const Carousel = ({
158
171
  pagingEnabled
159
172
  bounces={false}
160
173
  data={items}
161
- onViewableItemsChanged={visibleSlideChanged}
174
+ onMomentumScrollEnd={handleMomentumScrollEnd}
162
175
  viewabilityConfig={viewConfig}
163
176
  scrollEventThrottle={32}
164
177
  ref={carouselRef}