@hero-design/rn 8.131.1 → 8.131.3

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 (52) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/es/index.js +39 -86
  3. package/lib/index.js +38 -85
  4. package/package.json +1 -1
  5. package/src/components/Alert/index.tsx +1 -1
  6. package/src/components/AppCue/index.tsx +1 -1
  7. package/src/components/Attachment/index.tsx +1 -1
  8. package/src/components/BottomNavigation/index.tsx +1 -1
  9. package/src/components/Carousel/index.tsx +1 -1
  10. package/src/components/Chip/index.tsx +1 -1
  11. package/src/components/ContentNavigator/index.tsx +1 -1
  12. package/src/components/Divider/index.tsx +1 -1
  13. package/src/components/Drawer/index.tsx +1 -1
  14. package/src/components/FloatingIsland/index.tsx +1 -1
  15. package/src/components/HeroDesignProvider/index.tsx +1 -1
  16. package/src/components/Icon/index.tsx +0 -2
  17. package/src/components/LocaleProvider/index.tsx +1 -1
  18. package/src/components/PinInput/index.tsx +1 -1
  19. package/src/components/Rate/index.tsx +1 -1
  20. package/src/components/RefreshControl/index.tsx +1 -1
  21. package/src/components/SectionHeading/index.tsx +1 -1
  22. package/src/components/Skeleton/index.tsx +1 -1
  23. package/src/components/Spinner/index.tsx +1 -1
  24. package/src/components/Tabs/ScrollableTabsHeader/hooks/useIndicatorAnimation.ts +68 -62
  25. package/src/components/Tabs/StyledScrollableTabs.tsx +4 -4
  26. package/src/components/Tag/index.tsx +1 -1
  27. package/src/types.ts +99 -99
  28. package/types/components/Alert/index.d.ts +1 -1
  29. package/types/components/AppCue/index.d.ts +1 -1
  30. package/types/components/Attachment/index.d.ts +1 -1
  31. package/types/components/BottomNavigation/StyledBottomNavigation.d.ts +1 -1
  32. package/types/components/BottomNavigation/index.d.ts +1 -1
  33. package/types/components/Carousel/index.d.ts +1 -1
  34. package/types/components/Chip/index.d.ts +1 -1
  35. package/types/components/ContentNavigator/index.d.ts +1 -1
  36. package/types/components/Divider/index.d.ts +1 -1
  37. package/types/components/Drawer/index.d.ts +1 -1
  38. package/types/components/FloatingIsland/index.d.ts +1 -1
  39. package/types/components/HeroDesignProvider/index.d.ts +1 -1
  40. package/types/components/Icon/index.d.ts +0 -2
  41. package/types/components/LocaleProvider/index.d.ts +1 -1
  42. package/types/components/PinInput/index.d.ts +1 -1
  43. package/types/components/Rate/index.d.ts +1 -1
  44. package/types/components/RefreshControl/index.d.ts +1 -1
  45. package/types/components/SectionHeading/index.d.ts +1 -1
  46. package/types/components/Skeleton/index.d.ts +1 -1
  47. package/types/components/Spinner/index.d.ts +1 -1
  48. package/types/components/StatusScreens/Error/StyledError.d.ts +1 -1
  49. package/types/components/StatusScreens/Success/StyledSuccess.d.ts +1 -1
  50. package/types/components/Tabs/ScrollableTabsHeader/hooks/useIndicatorAnimation.d.ts +0 -38
  51. package/types/components/Tag/index.d.ts +1 -1
  52. package/types/types.d.ts +89 -43
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @hero-design/rn
2
2
 
3
+ ## 8.131.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#5158](https://github.com/Thinkei/hero-design/pull/5158) [`83dc767c00d8ba69eb03fbb50335b04e126ad4cd`](https://github.com/Thinkei/hero-design/commit/83dc767c00d8ba69eb03fbb50335b04e126ad4cd) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - Export all component Props types from the package root.
8
+
9
+ ## 8.131.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [#5161](https://github.com/Thinkei/hero-design/pull/5161) [`f9dd6c0a09ca33eac8455c8d03bbbf420f9b6d27`](https://github.com/Thinkei/hero-design/commit/f9dd6c0a09ca33eac8455c8d03bbbf420f9b6d27) Thanks [@ttkien](https://github.com/ttkien)! - [Tabs] Fix white space in Tab.Scroll header
14
+
3
15
  ## 8.131.1
4
16
 
5
17
  ### Patch Changes
package/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as reactNative from 'react-native';
2
- import { StyleSheet as StyleSheet$1, Platform, Dimensions, Keyboard, Animated, View, UIManager, LayoutAnimation, TouchableOpacity, Text as Text$1, Easing, useWindowDimensions, TouchableWithoutFeedback, Modal as Modal$1, Image as Image$1, Pressable, KeyboardAvoidingView, TouchableHighlight, ScrollView, FlatList, TextInput as TextInput$1, PanResponder, BackHandler, InteractionManager, SectionList, RefreshControl as RefreshControl$1 } from 'react-native';
2
+ import { StyleSheet as StyleSheet$1, Platform, Dimensions, Keyboard, Animated, View, UIManager, LayoutAnimation, TouchableOpacity, Text as Text$1, Easing, useWindowDimensions, TouchableWithoutFeedback, Modal as Modal$1, Image as Image$1, Pressable, KeyboardAvoidingView, TouchableHighlight, ScrollView, FlatList, TextInput as TextInput$1, PanResponder, BackHandler, InteractionManager, SectionList, PixelRatio, RefreshControl as RefreshControl$1 } from 'react-native';
3
3
  import * as React from 'react';
4
4
  import React__default, { useState, useEffect, useMemo, useCallback, useRef, useLayoutEffect, createContext, forwardRef, useContext, memo, useReducer, isValidElement, useImperativeHandle } from 'react';
5
5
  import MaskedView from '@react-native-masked-view/masked-view';
@@ -28157,7 +28157,7 @@ var HeaderTabPillBody = index$c(Animated.View)(function (_ref4) {
28157
28157
  top: 0,
28158
28158
  bottom: 0,
28159
28159
  left: 0,
28160
- width: 1,
28160
+ width: 1 / PixelRatio.get(),
28161
28161
  backgroundColor: theme.__hd__.tabs.colors.highlightedActiveBackground
28162
28162
  };
28163
28163
  });
@@ -28178,7 +28178,7 @@ var HeaderTabItemActiveBorder = index$c(Animated.View)(function (_ref6) {
28178
28178
  return {
28179
28179
  position: 'absolute',
28180
28180
  bottom: 0,
28181
- width: 1,
28181
+ width: 1 / PixelRatio.get(),
28182
28182
  height: theme.__hd__.tabs.borderWidths.highlightedActiveBorder,
28183
28183
  backgroundColor: theme.__hd__.tabs.colors.highlightedActiveBorder
28184
28184
  };
@@ -28196,7 +28196,7 @@ var HeaderTabItemWrapper = index$c(View)(function (_ref7) {
28196
28196
  var HeaderTabItemIndicator = index$c(Animated.View)(function (_ref8) {
28197
28197
  var theme = _ref8.theme;
28198
28198
  return {
28199
- width: 1,
28199
+ width: 1 / PixelRatio.get(),
28200
28200
  height: theme.__hd__.tabs.sizes.indicator,
28201
28201
  position: 'absolute',
28202
28202
  bottom: theme.__hd__.tabs.space.tabIndicatorBottom,
@@ -28277,44 +28277,17 @@ var TabWithBadge = function TabWithBadge(_ref) {
28277
28277
  return /*#__PURE__*/React__default.createElement(View, null, tabItem);
28278
28278
  };
28279
28279
 
28280
- /**
28281
- * Drives two visual layers that slide to the selected tab on every press:
28282
- *
28283
- * Layer 1 — bottom border / underline (indicatorStyle)
28284
- * ─────────────────────────────────────────────────────
28285
- * Uses the "width:1 + scaleX" trick: the element has a fixed stylesheet
28286
- * width of 1px and scaleX is set to the target pixel width, giving a visual
28287
- * width of 1 × scaleX pixels without touching any layout property.
28288
- * Both translateX and scaleX are transform properties → native driver.
28289
- * Caveat: scaleX also scales border-radius, so this layer has no border-radius.
28290
- *
28291
- * Layer 2 — pill background (pillLeftStyle / pillBodyStyle / pillRightStyle)
28292
- * ─────────────────────────────────────────────────────────────────────────────
28293
- * The pill is split into three absolutely-positioned children so that
28294
- * border-radius is never distorted by scale:
28295
- *
28296
- * ┌──────────────────────────────────────────────────────┐
28297
- * │ [cap-left 8px] [body width-1 + scaleX] [cap-right 8px] │
28298
- * └──────────────────────────────────────────────────────┘
28299
- *
28300
- * cap-left — fixed 8px wide, borderTopLeftRadius:8, translateX = pillX
28301
- * body — width:1 + scaleX trick (scaleX = tabWidth - 16),
28302
- * transformOrigin 'left center',
28303
- * translateX = pillX + 8 (via Animated.add)
28304
- * cap-right — fixed 8px wide, borderTopRightRadius:8,
28305
- * translateX = pillX + tabWidth - 8 (via Animated.add)
28306
- *
28307
- * All four animated values use the native driver (translateX and scaleX are
28308
- * transform properties). `width` is never animated, so no JS driver needed.
28309
- *
28310
- * Driver summary:
28311
- * indicatorX native translateX — slides the bottom border
28312
- * indicatorScaleX native scaleX — stretches the bottom border
28313
- * pillX native translateX — slides all three pill pieces
28314
- * pillBodyScaleX native scaleX — stretches the pill body
28315
- * pillRightOffsetX native translateX — positions the right cap
28316
- * (Animated.add: pillX + tabWidth - 8)
28317
- */
28280
+ /** Centralised calculation for all animated values given a tab layout. */
28281
+ var computeValues = function computeValues(layout, pillCapWidth) {
28282
+ var pr = PixelRatio.get();
28283
+ return {
28284
+ indicatorX: layout.x,
28285
+ indicatorScaleX: layout.width * pr,
28286
+ pillX: layout.x,
28287
+ pillBodyScaleX: Math.max(layout.width - pillCapWidth * 2, 0) * pr,
28288
+ pillRightOffset: Math.max(layout.width - pillCapWidth, 0)
28289
+ };
28290
+ };
28318
28291
  var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28319
28292
  var selectedIndex = _ref.selectedIndex,
28320
28293
  tabsLength = _ref.tabsLength,
@@ -28323,9 +28296,6 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28323
28296
  var indicatorX = React__default.useRef(new Animated.Value(0)).current;
28324
28297
  var indicatorScaleX = React__default.useRef(new Animated.Value(1)).current;
28325
28298
  // Layer 2 — native driver (pill background, three-piece split).
28326
- // pillX: left edge of the pill (shared by all three pieces as base).
28327
- // pillBodyScaleX: scaleX for the body piece (tabWidth - 2 * CAP_WIDTH).
28328
- // pillRightOffset: additional x offset for the right cap (tabWidth - CAP_WIDTH).
28329
28299
  var pillX = React__default.useRef(new Animated.Value(0)).current;
28330
28300
  var pillBodyScaleX = React__default.useRef(new Animated.Value(1)).current;
28331
28301
  var pillRightOffset = React__default.useRef(new Animated.Value(0)).current;
@@ -28348,44 +28318,30 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28348
28318
  if (!layout) return;
28349
28319
  (_runningAnimRef$curre = runningAnimRef.current) === null || _runningAnimRef$curre === void 0 || _runningAnimRef$curre.stop();
28350
28320
  runningAnimRef.current = null;
28351
- // Layer 1: bottom-border element has width:1, so scaleX = pixel width.
28352
- var indicatorScaleXValue = layout.width;
28353
- // Layer 2 body: width:1 element, scaleX fills space between the two caps.
28354
- var bodyScaleX = Math.max(layout.width - pillCapWidth * 2, 0);
28355
- // Layer 2 right cap: offset from pillX to reach the right edge.
28356
- // Clamped to 0 so the right cap never slides left of the pill's origin
28357
- // when the tab is narrower than one cap width.
28358
- var rightOffset = Math.max(layout.width - pillCapWidth, 0);
28321
+ var values = computeValues(layout, pillCapWidth);
28359
28322
  if (!animate || !initializedRef.current) {
28360
- // First render — snap all values immediately without animation.
28361
- indicatorX.setValue(layout.x);
28362
- indicatorScaleX.setValue(indicatorScaleXValue);
28363
- pillX.setValue(layout.x);
28364
- pillBodyScaleX.setValue(bodyScaleX);
28365
- pillRightOffset.setValue(rightOffset);
28323
+ indicatorX.setValue(values.indicatorX);
28324
+ indicatorScaleX.setValue(values.indicatorScaleX);
28325
+ pillX.setValue(values.pillX);
28326
+ pillBodyScaleX.setValue(values.pillBodyScaleX);
28327
+ pillRightOffset.setValue(values.pillRightOffset);
28366
28328
  initializedRef.current = true;
28367
28329
  return;
28368
28330
  }
28369
- // All five animations run on the native driver (UI thread):
28370
- // indicatorX — slides the bottom border
28371
- // indicatorScaleX — stretches the bottom border
28372
- // pillX — slides all three pill pieces together
28373
- // pillBodyScaleX — resizes the body piece to fill between caps
28374
- // pillRightOffset — keeps the right cap at the pill's right edge
28375
28331
  var anim = Animated.parallel([Animated.timing(indicatorX, {
28376
- toValue: layout.x,
28332
+ toValue: values.indicatorX,
28377
28333
  useNativeDriver: true
28378
28334
  }), Animated.timing(indicatorScaleX, {
28379
- toValue: indicatorScaleXValue,
28335
+ toValue: values.indicatorScaleX,
28380
28336
  useNativeDriver: true
28381
28337
  }), Animated.timing(pillX, {
28382
- toValue: layout.x,
28338
+ toValue: values.pillX,
28383
28339
  useNativeDriver: true
28384
28340
  }), Animated.timing(pillBodyScaleX, {
28385
- toValue: bodyScaleX,
28341
+ toValue: values.pillBodyScaleX,
28386
28342
  useNativeDriver: true
28387
28343
  }), Animated.timing(pillRightOffset, {
28388
- toValue: rightOffset,
28344
+ toValue: values.pillRightOffset,
28389
28345
  useNativeDriver: true
28390
28346
  })]);
28391
28347
  runningAnimRef.current = anim;
@@ -28400,7 +28356,6 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28400
28356
  if (layoutsRef.current[selectedIndex]) {
28401
28357
  animateTo(selectedIndex, initializedRef.current);
28402
28358
  } else {
28403
- // Layout not yet measured — store as pending and resolve in onTabLayout.
28404
28359
  pendingIndexRef.current = selectedIndex;
28405
28360
  }
28406
28361
  }, [selectedIndex, animateTo]);
@@ -28412,9 +28367,8 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28412
28367
  };
28413
28368
  }, []);
28414
28369
  var onTabLayout = React__default.useCallback(function (index, event) {
28415
- var _event$nativeEvent$la = event.nativeEvent.layout,
28416
- x = _event$nativeEvent$la.x,
28417
- width = _event$nativeEvent$la.width;
28370
+ var x = PixelRatio.roundToNearestPixel(event.nativeEvent.layout.x);
28371
+ var width = PixelRatio.roundToNearestPixel(event.nativeEvent.layout.width);
28418
28372
  var prev = layoutsRef.current[index];
28419
28373
  // Skip if layout hasn't meaningfully changed (sub-pixel tolerance).
28420
28374
  if (prev && Math.abs(prev.x - x) < 0.5 && Math.abs(prev.width - width) < 0.5) {
@@ -28424,23 +28378,24 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28424
28378
  x: x,
28425
28379
  width: width
28426
28380
  };
28427
- // Animate if this tab is the selected one (covers the pending case where
28428
- // selectedIndex was set before the layout was measured).
28429
28381
  if (index === selectedIndex || index === pendingIndexRef.current) {
28430
28382
  if (index === pendingIndexRef.current) pendingIndexRef.current = undefined;
28431
28383
  animateTo(index, initializedRef.current);
28432
28384
  }
28433
- // If no tab is selected yet, snap indicators to tab 0 on its first
28434
- // layout so they appear at a sensible default position.
28385
+ // If no tab is selected yet, snap indicators to tab 0 on its first layout.
28435
28386
  if (!initializedRef.current && index === 0 && selectedIndex === undefined) {
28436
- indicatorScaleX.setValue(width);
28437
- pillX.setValue(x);
28438
- pillBodyScaleX.setValue(Math.max(width - pillCapWidth * 2, 0));
28439
- pillRightOffset.setValue(Math.max(width - pillCapWidth, 0));
28387
+ var values = computeValues({
28388
+ x: x,
28389
+ width: width
28390
+ }, pillCapWidth);
28391
+ indicatorX.setValue(values.indicatorX);
28392
+ indicatorScaleX.setValue(values.indicatorScaleX);
28393
+ pillX.setValue(values.pillX);
28394
+ pillBodyScaleX.setValue(values.pillBodyScaleX);
28395
+ pillRightOffset.setValue(values.pillRightOffset);
28440
28396
  initializedRef.current = true;
28441
28397
  }
28442
- }, [animateTo, selectedIndex, pillCapWidth]);
28443
- // Layer 1: transformOrigin 'left center' pins scaleX expansion to left edge.
28398
+ }, [selectedIndex, animateTo, pillCapWidth, indicatorX, indicatorScaleX, pillX, pillBodyScaleX, pillRightOffset]);
28444
28399
  var indicatorStyle = {
28445
28400
  transformOrigin: 'left center',
28446
28401
  transform: [{
@@ -28449,8 +28404,6 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28449
28404
  scaleX: indicatorScaleX
28450
28405
  }]
28451
28406
  };
28452
- // Layer 2: three pieces, all absolutely positioned, all native driver.
28453
- // Animated.add computes derived positions without creating JS-driver nodes.
28454
28407
  var pillLeftStyle = {
28455
28408
  transform: [{
28456
28409
  translateX: pillX
package/lib/index.js CHANGED
@@ -28186,7 +28186,7 @@ var HeaderTabPillBody = index$c(reactNative.Animated.View)(function (_ref4) {
28186
28186
  top: 0,
28187
28187
  bottom: 0,
28188
28188
  left: 0,
28189
- width: 1,
28189
+ width: 1 / reactNative.PixelRatio.get(),
28190
28190
  backgroundColor: theme.__hd__.tabs.colors.highlightedActiveBackground
28191
28191
  };
28192
28192
  });
@@ -28207,7 +28207,7 @@ var HeaderTabItemActiveBorder = index$c(reactNative.Animated.View)(function (_re
28207
28207
  return {
28208
28208
  position: 'absolute',
28209
28209
  bottom: 0,
28210
- width: 1,
28210
+ width: 1 / reactNative.PixelRatio.get(),
28211
28211
  height: theme.__hd__.tabs.borderWidths.highlightedActiveBorder,
28212
28212
  backgroundColor: theme.__hd__.tabs.colors.highlightedActiveBorder
28213
28213
  };
@@ -28225,7 +28225,7 @@ var HeaderTabItemWrapper = index$c(reactNative.View)(function (_ref7) {
28225
28225
  var HeaderTabItemIndicator = index$c(reactNative.Animated.View)(function (_ref8) {
28226
28226
  var theme = _ref8.theme;
28227
28227
  return {
28228
- width: 1,
28228
+ width: 1 / reactNative.PixelRatio.get(),
28229
28229
  height: theme.__hd__.tabs.sizes.indicator,
28230
28230
  position: 'absolute',
28231
28231
  bottom: theme.__hd__.tabs.space.tabIndicatorBottom,
@@ -28306,44 +28306,17 @@ var TabWithBadge = function TabWithBadge(_ref) {
28306
28306
  return /*#__PURE__*/React__namespace.default.createElement(reactNative.View, null, tabItem);
28307
28307
  };
28308
28308
 
28309
- /**
28310
- * Drives two visual layers that slide to the selected tab on every press:
28311
- *
28312
- * Layer 1 — bottom border / underline (indicatorStyle)
28313
- * ─────────────────────────────────────────────────────
28314
- * Uses the "width:1 + scaleX" trick: the element has a fixed stylesheet
28315
- * width of 1px and scaleX is set to the target pixel width, giving a visual
28316
- * width of 1 × scaleX pixels without touching any layout property.
28317
- * Both translateX and scaleX are transform properties → native driver.
28318
- * Caveat: scaleX also scales border-radius, so this layer has no border-radius.
28319
- *
28320
- * Layer 2 — pill background (pillLeftStyle / pillBodyStyle / pillRightStyle)
28321
- * ─────────────────────────────────────────────────────────────────────────────
28322
- * The pill is split into three absolutely-positioned children so that
28323
- * border-radius is never distorted by scale:
28324
- *
28325
- * ┌──────────────────────────────────────────────────────┐
28326
- * │ [cap-left 8px] [body width-1 + scaleX] [cap-right 8px] │
28327
- * └──────────────────────────────────────────────────────┘
28328
- *
28329
- * cap-left — fixed 8px wide, borderTopLeftRadius:8, translateX = pillX
28330
- * body — width:1 + scaleX trick (scaleX = tabWidth - 16),
28331
- * transformOrigin 'left center',
28332
- * translateX = pillX + 8 (via Animated.add)
28333
- * cap-right — fixed 8px wide, borderTopRightRadius:8,
28334
- * translateX = pillX + tabWidth - 8 (via Animated.add)
28335
- *
28336
- * All four animated values use the native driver (translateX and scaleX are
28337
- * transform properties). `width` is never animated, so no JS driver needed.
28338
- *
28339
- * Driver summary:
28340
- * indicatorX native translateX — slides the bottom border
28341
- * indicatorScaleX native scaleX — stretches the bottom border
28342
- * pillX native translateX — slides all three pill pieces
28343
- * pillBodyScaleX native scaleX — stretches the pill body
28344
- * pillRightOffsetX native translateX — positions the right cap
28345
- * (Animated.add: pillX + tabWidth - 8)
28346
- */
28309
+ /** Centralised calculation for all animated values given a tab layout. */
28310
+ var computeValues = function computeValues(layout, pillCapWidth) {
28311
+ var pr = reactNative.PixelRatio.get();
28312
+ return {
28313
+ indicatorX: layout.x,
28314
+ indicatorScaleX: layout.width * pr,
28315
+ pillX: layout.x,
28316
+ pillBodyScaleX: Math.max(layout.width - pillCapWidth * 2, 0) * pr,
28317
+ pillRightOffset: Math.max(layout.width - pillCapWidth, 0)
28318
+ };
28319
+ };
28347
28320
  var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28348
28321
  var selectedIndex = _ref.selectedIndex,
28349
28322
  tabsLength = _ref.tabsLength,
@@ -28352,9 +28325,6 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28352
28325
  var indicatorX = React__namespace.default.useRef(new reactNative.Animated.Value(0)).current;
28353
28326
  var indicatorScaleX = React__namespace.default.useRef(new reactNative.Animated.Value(1)).current;
28354
28327
  // Layer 2 — native driver (pill background, three-piece split).
28355
- // pillX: left edge of the pill (shared by all three pieces as base).
28356
- // pillBodyScaleX: scaleX for the body piece (tabWidth - 2 * CAP_WIDTH).
28357
- // pillRightOffset: additional x offset for the right cap (tabWidth - CAP_WIDTH).
28358
28328
  var pillX = React__namespace.default.useRef(new reactNative.Animated.Value(0)).current;
28359
28329
  var pillBodyScaleX = React__namespace.default.useRef(new reactNative.Animated.Value(1)).current;
28360
28330
  var pillRightOffset = React__namespace.default.useRef(new reactNative.Animated.Value(0)).current;
@@ -28377,44 +28347,30 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28377
28347
  if (!layout) return;
28378
28348
  (_runningAnimRef$curre = runningAnimRef.current) === null || _runningAnimRef$curre === void 0 || _runningAnimRef$curre.stop();
28379
28349
  runningAnimRef.current = null;
28380
- // Layer 1: bottom-border element has width:1, so scaleX = pixel width.
28381
- var indicatorScaleXValue = layout.width;
28382
- // Layer 2 body: width:1 element, scaleX fills space between the two caps.
28383
- var bodyScaleX = Math.max(layout.width - pillCapWidth * 2, 0);
28384
- // Layer 2 right cap: offset from pillX to reach the right edge.
28385
- // Clamped to 0 so the right cap never slides left of the pill's origin
28386
- // when the tab is narrower than one cap width.
28387
- var rightOffset = Math.max(layout.width - pillCapWidth, 0);
28350
+ var values = computeValues(layout, pillCapWidth);
28388
28351
  if (!animate || !initializedRef.current) {
28389
- // First render — snap all values immediately without animation.
28390
- indicatorX.setValue(layout.x);
28391
- indicatorScaleX.setValue(indicatorScaleXValue);
28392
- pillX.setValue(layout.x);
28393
- pillBodyScaleX.setValue(bodyScaleX);
28394
- pillRightOffset.setValue(rightOffset);
28352
+ indicatorX.setValue(values.indicatorX);
28353
+ indicatorScaleX.setValue(values.indicatorScaleX);
28354
+ pillX.setValue(values.pillX);
28355
+ pillBodyScaleX.setValue(values.pillBodyScaleX);
28356
+ pillRightOffset.setValue(values.pillRightOffset);
28395
28357
  initializedRef.current = true;
28396
28358
  return;
28397
28359
  }
28398
- // All five animations run on the native driver (UI thread):
28399
- // indicatorX — slides the bottom border
28400
- // indicatorScaleX — stretches the bottom border
28401
- // pillX — slides all three pill pieces together
28402
- // pillBodyScaleX — resizes the body piece to fill between caps
28403
- // pillRightOffset — keeps the right cap at the pill's right edge
28404
28360
  var anim = reactNative.Animated.parallel([reactNative.Animated.timing(indicatorX, {
28405
- toValue: layout.x,
28361
+ toValue: values.indicatorX,
28406
28362
  useNativeDriver: true
28407
28363
  }), reactNative.Animated.timing(indicatorScaleX, {
28408
- toValue: indicatorScaleXValue,
28364
+ toValue: values.indicatorScaleX,
28409
28365
  useNativeDriver: true
28410
28366
  }), reactNative.Animated.timing(pillX, {
28411
- toValue: layout.x,
28367
+ toValue: values.pillX,
28412
28368
  useNativeDriver: true
28413
28369
  }), reactNative.Animated.timing(pillBodyScaleX, {
28414
- toValue: bodyScaleX,
28370
+ toValue: values.pillBodyScaleX,
28415
28371
  useNativeDriver: true
28416
28372
  }), reactNative.Animated.timing(pillRightOffset, {
28417
- toValue: rightOffset,
28373
+ toValue: values.pillRightOffset,
28418
28374
  useNativeDriver: true
28419
28375
  })]);
28420
28376
  runningAnimRef.current = anim;
@@ -28429,7 +28385,6 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28429
28385
  if (layoutsRef.current[selectedIndex]) {
28430
28386
  animateTo(selectedIndex, initializedRef.current);
28431
28387
  } else {
28432
- // Layout not yet measured — store as pending and resolve in onTabLayout.
28433
28388
  pendingIndexRef.current = selectedIndex;
28434
28389
  }
28435
28390
  }, [selectedIndex, animateTo]);
@@ -28441,9 +28396,8 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28441
28396
  };
28442
28397
  }, []);
28443
28398
  var onTabLayout = React__namespace.default.useCallback(function (index, event) {
28444
- var _event$nativeEvent$la = event.nativeEvent.layout,
28445
- x = _event$nativeEvent$la.x,
28446
- width = _event$nativeEvent$la.width;
28399
+ var x = reactNative.PixelRatio.roundToNearestPixel(event.nativeEvent.layout.x);
28400
+ var width = reactNative.PixelRatio.roundToNearestPixel(event.nativeEvent.layout.width);
28447
28401
  var prev = layoutsRef.current[index];
28448
28402
  // Skip if layout hasn't meaningfully changed (sub-pixel tolerance).
28449
28403
  if (prev && Math.abs(prev.x - x) < 0.5 && Math.abs(prev.width - width) < 0.5) {
@@ -28453,23 +28407,24 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28453
28407
  x: x,
28454
28408
  width: width
28455
28409
  };
28456
- // Animate if this tab is the selected one (covers the pending case where
28457
- // selectedIndex was set before the layout was measured).
28458
28410
  if (index === selectedIndex || index === pendingIndexRef.current) {
28459
28411
  if (index === pendingIndexRef.current) pendingIndexRef.current = undefined;
28460
28412
  animateTo(index, initializedRef.current);
28461
28413
  }
28462
- // If no tab is selected yet, snap indicators to tab 0 on its first
28463
- // layout so they appear at a sensible default position.
28414
+ // If no tab is selected yet, snap indicators to tab 0 on its first layout.
28464
28415
  if (!initializedRef.current && index === 0 && selectedIndex === undefined) {
28465
- indicatorScaleX.setValue(width);
28466
- pillX.setValue(x);
28467
- pillBodyScaleX.setValue(Math.max(width - pillCapWidth * 2, 0));
28468
- pillRightOffset.setValue(Math.max(width - pillCapWidth, 0));
28416
+ var values = computeValues({
28417
+ x: x,
28418
+ width: width
28419
+ }, pillCapWidth);
28420
+ indicatorX.setValue(values.indicatorX);
28421
+ indicatorScaleX.setValue(values.indicatorScaleX);
28422
+ pillX.setValue(values.pillX);
28423
+ pillBodyScaleX.setValue(values.pillBodyScaleX);
28424
+ pillRightOffset.setValue(values.pillRightOffset);
28469
28425
  initializedRef.current = true;
28470
28426
  }
28471
- }, [animateTo, selectedIndex, pillCapWidth]);
28472
- // Layer 1: transformOrigin 'left center' pins scaleX expansion to left edge.
28427
+ }, [selectedIndex, animateTo, pillCapWidth, indicatorX, indicatorScaleX, pillX, pillBodyScaleX, pillRightOffset]);
28473
28428
  var indicatorStyle = {
28474
28429
  transformOrigin: 'left center',
28475
28430
  transform: [{
@@ -28478,8 +28433,6 @@ var useIndicatorAnimation = function useIndicatorAnimation(_ref) {
28478
28433
  scaleX: indicatorScaleX
28479
28434
  }]
28480
28435
  };
28481
- // Layer 2: three pieces, all absolutely positioned, all native driver.
28482
- // Animated.add computes derived positions without creating JS-driver nodes.
28483
28436
  var pillLeftStyle = {
28484
28437
  transform: [{
28485
28438
  translateX: pillX
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.131.1",
3
+ "version": "8.131.3",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -92,7 +92,7 @@ interface BasicAlertProps {
92
92
  actionLabel?: string;
93
93
  }
94
94
 
95
- type AlertProps =
95
+ export type AlertProps =
96
96
  | (BasicAlertProps & {
97
97
  actionLabel?: undefined;
98
98
  })
@@ -18,7 +18,7 @@ import Icon from '../Icon';
18
18
  import { useTheme } from '../../theme';
19
19
  import { calculatePosition, calulateContentMaxWidth } from './utils';
20
20
 
21
- interface AppCueProps {
21
+ export interface AppCueProps {
22
22
  /*
23
23
  * The content of the App Cue.
24
24
  */
@@ -12,7 +12,7 @@ import Icon from '../Icon';
12
12
  import Typography from '../Typography';
13
13
  import type { ImageProps } from '../Image';
14
14
 
15
- interface AttachmentProps {
15
+ export interface AttachmentProps {
16
16
  /**
17
17
  * Attachment filename.
18
18
  */
@@ -36,7 +36,7 @@ export type BottomNavigationTabType = {
36
36
  testID?: string;
37
37
  };
38
38
  };
39
- interface BottomNavigationProps extends ViewProps {
39
+ export interface BottomNavigationProps extends ViewProps {
40
40
  /**
41
41
  * Callback which is called on tab press, receiving key of upcoming active Tab.
42
42
  */
@@ -22,7 +22,7 @@ import {
22
22
  } from './StyledCarousel';
23
23
  import type { CarouselData } from './types';
24
24
 
25
- interface CarouselProps extends ViewProps {
25
+ export interface CarouselProps extends ViewProps {
26
26
  /**
27
27
  * Additional style.
28
28
  */
@@ -14,7 +14,7 @@ type DeprecatedVariant = 'outlined' | 'filled';
14
14
 
15
15
  type ValidVariant = 'selection' | 'filter' | 'compact' | 'compact-outlined';
16
16
 
17
- interface ChipProps extends ViewProps {
17
+ export interface ChipProps extends ViewProps {
18
18
  /**
19
19
  * The label of the chip.
20
20
  */
@@ -6,7 +6,7 @@ import Button from '../Button';
6
6
  import Typography from '../Typography';
7
7
  import { useTheme } from '../../theme';
8
8
 
9
- interface ContentNavigatorProps {
9
+ export interface ContentNavigatorProps {
10
10
  /**
11
11
  * The navigator's content value.
12
12
  */
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { StyleProp, ViewStyle, ViewProps } from 'react-native';
3
3
  import { StyledDivider } from './StyledDivider';
4
4
 
5
- interface DividerProps extends ViewProps {
5
+ export interface DividerProps extends ViewProps {
6
6
  /**
7
7
  * Horizontal margin size. There is no margin by default.
8
8
  */
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  const BACKDROP_OPACITY = 0.56;
14
14
 
15
- interface DrawerProps {
15
+ export interface DrawerProps {
16
16
  /**
17
17
  * Drawer's visibility.
18
18
  */
@@ -9,7 +9,7 @@ import {
9
9
  } from './StyledFloatingIsland';
10
10
  import type { IconName } from '../Icon';
11
11
 
12
- interface FloatingIslandProps extends TouchableOpacityProps {
12
+ export interface FloatingIslandProps extends TouchableOpacityProps {
13
13
  /**
14
14
  * Callback that is called when the floating island is pressed.
15
15
  */
@@ -7,7 +7,7 @@ import LocaleProvider from '../LocaleProvider';
7
7
  import type { LocaleValues } from '../../locales/types';
8
8
  import enAULocale from '../../locales/en_AU';
9
9
 
10
- interface HeroDesignProviderProps extends ThemeProviderProps {
10
+ export interface HeroDesignProviderProps extends ThemeProviderProps {
11
11
  locale?: LocaleValues;
12
12
  }
13
13
 
@@ -12,8 +12,6 @@ export type IconName = typeof IconList[number];
12
12
  export interface IconProps extends AccessibilityProps {
13
13
  /**
14
14
  * Name of the Icon.
15
- *
16
- * icon['carat-*'] - @deprecated Icons starting with 'carat' are deprecated and will be removed in the next major release, please use 'caret' instead.
17
15
  */
18
16
  icon: IconName;
19
17
  /**
@@ -4,7 +4,7 @@ import { LocaleContext } from './context';
4
4
  import { getDateFnsLocale } from './utils';
5
5
  import type { LocaleValues } from '../../locales/types';
6
6
 
7
- interface LocaleProviderProps {
7
+ export interface LocaleProviderProps {
8
8
  locale: LocaleValues;
9
9
  }
10
10
 
@@ -22,7 +22,7 @@ import {
22
22
  } from './StyledPinInput';
23
23
  import type { State } from './StyledPinInput';
24
24
 
25
- interface PinInputProps {
25
+ export interface PinInputProps {
26
26
  /**
27
27
  * The value to show for the input.
28
28
  */
@@ -8,7 +8,7 @@ interface RateOption<T extends string | number> {
8
8
  value: T;
9
9
  }
10
10
 
11
- interface RateProps<T extends string | number> extends ViewProps {
11
+ export interface RateProps<T extends string | number> extends ViewProps {
12
12
  /**
13
13
  * Options for rate component.
14
14
  */
@@ -3,7 +3,7 @@ import type { RefreshControlProps as NativeRefreshControlProps } from 'react-nat
3
3
  import { RefreshControl as NativeRefreshControl } from 'react-native';
4
4
  import { useTheme } from '../../theme';
5
5
 
6
- type RefreshControlProps = Omit<
6
+ export type RefreshControlProps = Omit<
7
7
  NativeRefreshControlProps,
8
8
  'colors' | 'tintColor'
9
9
  >;
@@ -11,7 +11,7 @@ import {
11
11
  import type { IconName, IconProps } from '../Icon';
12
12
  import { useDeprecation } from '../../utils/hooks';
13
13
 
14
- interface SectionHeadingProps extends ViewProps {
14
+ export interface SectionHeadingProps extends ViewProps {
15
15
  /**
16
16
  * Heading text.
17
17
  */
@@ -12,7 +12,7 @@ import type { Theme } from '../../theme';
12
12
  import { useTheme } from '../../theme';
13
13
  import { StyledContainer, StyledGradientContainer } from './StyledSkeleton';
14
14
 
15
- interface SkeletonProps extends ViewProps {
15
+ export interface SkeletonProps extends ViewProps {
16
16
  /**
17
17
  * Intent of the component.
18
18
  */