react-native-unit-components 3.1.1 → 3.1.2-beta.2

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 (61) hide show
  1. package/android/src/main/java/com/unitreactnativecomponents/UnitReactNativeComponentsPackage.kt +2 -0
  2. package/android/src/main/java/com/unitreactnativecomponents/nativeModules/navigationBar/UNNavigationBarModule.kt +38 -0
  3. package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js +3 -26
  4. package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js.map +1 -1
  5. package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.js +37 -37
  6. package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.js.map +1 -1
  7. package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js +6 -4
  8. package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js.map +1 -1
  9. package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js +7 -6
  10. package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js.map +1 -1
  11. package/lib/commonjs/helpers/BottomSheet/BottomSheet.js +21 -12
  12. package/lib/commonjs/helpers/BottomSheet/BottomSheet.js.map +1 -1
  13. package/lib/commonjs/helpers/BottomSheet/BottomSheet.styles.js +4 -2
  14. package/lib/commonjs/helpers/BottomSheet/BottomSheet.styles.js.map +1 -1
  15. package/lib/commonjs/hooks/useSafeAreaDimensions.js +14 -3
  16. package/lib/commonjs/hooks/useSafeAreaDimensions.js.map +1 -1
  17. package/lib/commonjs/nativeModulesHelpers/UNNavigationBarHelper.js +17 -0
  18. package/lib/commonjs/nativeModulesHelpers/UNNavigationBarHelper.js.map +1 -0
  19. package/lib/commonjs/unitComponentsSdkManager/UnitComponentsSdkManager.js +1 -1
  20. package/lib/commonjs/unitComponentsSdkManager/UnitComponentsSdkManager.js.map +1 -1
  21. package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js +4 -27
  22. package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js.map +1 -1
  23. package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.js +38 -38
  24. package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.js.map +1 -1
  25. package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js +6 -4
  26. package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js.map +1 -1
  27. package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js +6 -5
  28. package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js.map +1 -1
  29. package/lib/module/helpers/BottomSheet/BottomSheet.js +22 -13
  30. package/lib/module/helpers/BottomSheet/BottomSheet.js.map +1 -1
  31. package/lib/module/helpers/BottomSheet/BottomSheet.styles.js +4 -2
  32. package/lib/module/helpers/BottomSheet/BottomSheet.styles.js.map +1 -1
  33. package/lib/module/hooks/useSafeAreaDimensions.js +14 -3
  34. package/lib/module/hooks/useSafeAreaDimensions.js.map +1 -1
  35. package/lib/module/nativeModulesHelpers/UNNavigationBarHelper.js +11 -0
  36. package/lib/module/nativeModulesHelpers/UNNavigationBarHelper.js.map +1 -0
  37. package/lib/module/unitComponentsSdkManager/UnitComponentsSdkManager.js +1 -1
  38. package/lib/module/unitComponentsSdkManager/UnitComponentsSdkManager.js.map +1 -1
  39. package/lib/typescript/src/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.d.ts.map +1 -1
  40. package/lib/typescript/src/components/UNBottomSheetComponent/UNBottomSheetComponent.d.ts.map +1 -1
  41. package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.d.ts +1 -0
  42. package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.d.ts.map +1 -1
  43. package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.d.ts +1 -0
  44. package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.d.ts.map +1 -1
  45. package/lib/typescript/src/helpers/BottomSheet/BottomSheet.d.ts.map +1 -1
  46. package/lib/typescript/src/helpers/BottomSheet/BottomSheet.styles.d.ts +4 -2
  47. package/lib/typescript/src/helpers/BottomSheet/BottomSheet.styles.d.ts.map +1 -1
  48. package/lib/typescript/src/hooks/useSafeAreaDimensions.d.ts.map +1 -1
  49. package/lib/typescript/src/nativeModulesHelpers/UNNavigationBarHelper.d.ts +2 -0
  50. package/lib/typescript/src/nativeModulesHelpers/UNNavigationBarHelper.d.ts.map +1 -0
  51. package/lib/typescript/src/unitComponentsSdkManager/UnitComponentsSdkManager.d.ts.map +1 -1
  52. package/package.json +1 -1
  53. package/src/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.ts +4 -29
  54. package/src/components/UNBottomSheetComponent/UNBottomSheetComponent.tsx +58 -53
  55. package/src/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.tsx +7 -4
  56. package/src/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.tsx +8 -5
  57. package/src/helpers/BottomSheet/BottomSheet.styles.ts +4 -2
  58. package/src/helpers/BottomSheet/BottomSheet.tsx +21 -10
  59. package/src/hooks/useSafeAreaDimensions.ts +15 -3
  60. package/src/nativeModulesHelpers/UNNavigationBarHelper.ts +14 -0
  61. package/src/unitComponentsSdkManager/UnitComponentsSdkManager.ts +1 -1
@@ -7,7 +7,7 @@ import {
7
7
  import { useDispatch } from 'react-redux';
8
8
  import { setComponentHeight, setScrollState, setShouldEnableBottomSheetScroll } from '../../../../slices/BottomSheetSlice';
9
9
  import { UNAddToWalletComponent } from '../../../../nativeComponents/UNAddToWallet/UNAddToWalletComponent';
10
- import { overFullScreenHeight } from '../../UNBottomSheetComponent.constants';
10
+ import { BOTTOM_SHEET_OVER_FULLSCREEN_PERCENTAGE_SIZE } from '../../UNBottomSheetComponent.constants';
11
11
  import { useSafeAreaDimensions } from '../../../../hooks/useSafeAreaDimensions';
12
12
  import UNACHCreditComponent from '../../../UNACHCreditComponent/UNACHCreditComponent';
13
13
  import UNCheckDepositComponent from '../../../UNCheckDepositComponent/UNCheckDepositComponent';
@@ -22,11 +22,14 @@ import UNKeyboardAvoidingView from '../../../../helpers/UNKeyboardAvoidingView/U
22
22
 
23
23
  export interface UNBottomSheetNativeComponentProps {
24
24
  nativeComponentData: NativeComponentData;
25
+ containerHeight: number;
25
26
  }
26
27
 
27
28
  const UNBottomSheetNativeComponent = (props: UNBottomSheetNativeComponentProps) => {
28
29
  const dispatch = useDispatch();
29
- const { contentHeight, effectiveBottomInset } = useSafeAreaDimensions();
30
+ const { insets, effectiveBottomInset } = useSafeAreaDimensions();
31
+ const overFullScreenHeight = props.containerHeight * BOTTOM_SHEET_OVER_FULLSCREEN_PERCENTAGE_SIZE;
32
+ const modalContentHeight = props.containerHeight - insets.top;
30
33
  const [height, setHeight] = useState<number>(0);
31
34
  const [paddingTop, setPaddingTop] = useState<number>(0);
32
35
  const [paddingBottom, setPaddingBottom] = useState<number>(0);
@@ -67,7 +70,7 @@ const UNBottomSheetNativeComponent = (props: UNBottomSheetNativeComponentProps)
67
70
  adjustedHeight = overFullScreenHeight;
68
71
  break;
69
72
  case BottomSheetNativePlaceType.modal:
70
- adjustedHeight = contentHeight;
73
+ adjustedHeight = modalContentHeight;
71
74
  break;
72
75
  default:
73
76
  return;
@@ -79,7 +82,7 @@ const UNBottomSheetNativeComponent = (props: UNBottomSheetNativeComponentProps)
79
82
  };
80
83
 
81
84
  setBottomSheetNativeComponentViewHeight();
82
- }, [props.nativeComponentData.nativePlace, contentHeight, dispatch]);
85
+ }, [props.nativeComponentData.nativePlace, modalContentHeight, overFullScreenHeight, dispatch]);
83
86
 
84
87
  const renderNativeComponent = () => {
85
88
  switch (props.nativeComponentData?.component.type) {
@@ -30,7 +30,7 @@ import {
30
30
  } from '../../../../slices/BottomSheetSlice';
31
31
  import { getAccountActionType } from '../../../UNAccountComponent/UNAccountComponent.utils';
32
32
  import { UNAccountAction } from '../../../UNAccountComponent/UNAccountComponent';
33
- import { BOTTOM_PADDING, LEFT_PADDING, overFullScreenHeight, RIGHT_PADDING, TOP_PADDING, VERTICAL_PADDING } from '../../UNBottomSheetComponent.constants';
33
+ import { BOTTOM_PADDING, BOTTOM_SHEET_OVER_FULLSCREEN_PERCENTAGE_SIZE, LEFT_PADDING, RIGHT_PADDING, TOP_PADDING, VERTICAL_PADDING } from '../../UNBottomSheetComponent.constants';
34
34
  import { useSafeAreaDimensions } from '../../../../hooks/useSafeAreaDimensions';
35
35
  import { BottomSheetNativeMessage } from '../../../../messages/nativeMessages/bottomSheetMessage';
36
36
  import { OpenPlaidEvent, PlaidMessage } from '../../../../messages/webMessages/plaidMessages';
@@ -43,6 +43,7 @@ export interface UNBottomSheetSlotComponentProps {
43
43
  requestRenderingEvent: RequestRenderingEvent;
44
44
  componentName?: WebComponentType,
45
45
  componentResourceId?: string,
46
+ containerHeight: number,
46
47
  }
47
48
 
48
49
  const UNBottomSheetSlotComponent = (props: UNBottomSheetSlotComponentProps) => {
@@ -50,7 +51,9 @@ const UNBottomSheetSlotComponent = (props: UNBottomSheetSlotComponentProps) => {
50
51
  const webRef = useRef<WebView>(null);
51
52
  const scrollState = useSelector((state: RootState) => state.bottomSheet.scrollState);
52
53
  const nativePlace = props.requestRenderingEvent?.data?.nativePlace;
53
- const { fullScreenHeight, contentHeight, effectiveBottomInset } = useSafeAreaDimensions();
54
+ const { insets, effectiveBottomInset } = useSafeAreaDimensions();
55
+ const overFullScreenHeight = props.containerHeight * BOTTOM_SHEET_OVER_FULLSCREEN_PERCENTAGE_SIZE;
56
+ const modalContentHeight = props.containerHeight - insets.top;
54
57
 
55
58
  useEffect(() => {
56
59
  const scrollStateForSlot = () => {
@@ -113,8 +116,8 @@ const UNBottomSheetSlotComponent = (props: UNBottomSheetSlotComponentProps) => {
113
116
  }
114
117
  case BottomSheetNativePlaceType.modal: {
115
118
  const injectedHeight = !props.requestRenderingEvent.data.isPaddingIncluded
116
- ? contentHeight - VERTICAL_PADDING - effectiveBottomInset
117
- : contentHeight - effectiveBottomInset;
119
+ ? modalContentHeight - VERTICAL_PADDING - effectiveBottomInset
120
+ : modalContentHeight - effectiveBottomInset;
118
121
  injectHtmlFullScreenHeight(webRef.current, injectedHeight);
119
122
  break;
120
123
  }
@@ -219,7 +222,7 @@ const UNBottomSheetSlotComponent = (props: UNBottomSheetSlotComponentProps) => {
219
222
 
220
223
  return (
221
224
  <View style={{...paddingStyle, flex: 1}}>
222
- <UNKeyboardAvoidingView keyboardVerticalOffset={fullScreenHeight - overFullScreenHeight}>
225
+ <UNKeyboardAvoidingView keyboardVerticalOffset={props.containerHeight - overFullScreenHeight}>
223
226
  <WebComponent
224
227
  ref={webRef}
225
228
  type={WebComponentType.slot}
@@ -18,8 +18,10 @@ export const getStylesObject = (fadeAnim: any) => {
18
18
  opacity: fadeAnim,
19
19
  },
20
20
  container: {
21
- position: 'relative',
22
- flex: 1,
21
+ position: 'absolute',
22
+ bottom: 0,
23
+ left: 0,
24
+ right: 0,
23
25
  shadowColor: VARIABLES.COLORS.BLACK,
24
26
  shadowOffset: {
25
27
  width: 0,
@@ -6,7 +6,6 @@ import {
6
6
  Image,
7
7
  LayoutChangeEvent,
8
8
  PanResponder,
9
- Platform,
10
9
  TouchableOpacity,
11
10
  View,
12
11
  } from 'react-native';
@@ -37,11 +36,11 @@ const BottomSheet = (props: BottomSheetProps) => {
37
36
  const panelHeightValue = useRef(new Animated.Value(props.sliderMaxHeight)).current;
38
37
  const fadeAnim = useRef(new Animated.Value(0)).current;
39
38
  const styles = getStylesObject(fadeAnim);
40
- const [isPanelOpened, setIsPanelOpened] = useState(props.isOpen);
39
+ // Initialize to false: BottomSheet mounts fresh each time (conditionally rendered),
40
+ // so useEffect will trigger fadeIn() when isOpen=true on mount.
41
+ const [isPanelOpened, setIsPanelOpened] = useState(false);
41
42
  const [contentHeight, setContentHeight] = useState<number | undefined>(undefined);
42
- const { insets, fullScreenHeight, isAndroid10AndAbove, isEdgeToEdgeActive } = useSafeAreaDimensions();
43
- // Android 15+ (API 35) enforces edge-to-edge, so marginTop calculation differs
44
- const isAndroid15AndAbove = Platform.OS === 'android' && Platform.Version >= 35;
43
+ const { insets } = useSafeAreaDimensions();
45
44
 
46
45
  const [currentHeight, setCurrentHeight] = useState<number>(props.sliderMaxHeight);
47
46
 
@@ -161,10 +160,25 @@ const BottomSheet = (props: BottomSheetProps) => {
161
160
  return isPanelOpened;
162
161
  };
163
162
 
163
+ // Track the last height we animated to, so we skip duplicate animations
164
+ // (prevents visual jitter when _setSize fires multiple times with the same height)
165
+ // but still re-animate when the height actually changes.
166
+ const lastAnimatedHeight = useRef(0);
167
+
168
+ // Reset when new content starts loading, so the next opening can animate.
169
+ useEffect(() => {
170
+ if (props.isComponentLoading) {
171
+ lastAnimatedHeight.current = 0;
172
+ }
173
+ }, [props.isComponentLoading]);
174
+
164
175
  const _setSize = (e: LayoutChangeEvent) => {
165
176
  const newContentHeight = e.nativeEvent.layout.height;
166
177
  setContentHeight(newContentHeight);
167
- setToContentHeight(newContentHeight);
178
+ if (newContentHeight > 0 && newContentHeight !== lastAnimatedHeight.current) {
179
+ lastAnimatedHeight.current = newContentHeight;
180
+ setToContentHeight(newContentHeight);
181
+ }
168
182
  };
169
183
 
170
184
  const _dismiss = (withAnimation = true) => {
@@ -203,13 +217,10 @@ const BottomSheet = (props: BottomSheetProps) => {
203
217
  borderTopLeftRadius: isModal ? 0 : styles.container.borderTopLeftRadius,
204
218
  borderTopRightRadius: isModal ? 0 : styles.container.borderTopRightRadius,
205
219
  height: props.sliderMaxHeight,
206
- // Android 15+ (edge-to-edge): fullScreenHeight is already the full screen, no adjustment needed
207
- // Android 10-14: fullScreenHeight includes status bar, but view starts below it, so subtract insets.top
208
- marginTop: isModal ? 0 : fullScreenHeight - props.sliderMaxHeight - (isAndroid10AndAbove && !isAndroid15AndAbove ? insets.top : 0),
209
220
  transform: [
210
221
  { translateY: panelHeightValue },
211
222
  ],
212
- paddingTop: isModal && (Platform.OS === 'ios' || isEdgeToEdgeActive) ? insets.top : 0,
223
+ paddingTop: isModal ? insets.top : 0,
213
224
  }}
214
225
  >
215
226
  <View
@@ -1,5 +1,6 @@
1
1
  import { Dimensions, Platform } from 'react-native';
2
2
  import { initialWindowMetrics } from 'react-native-safe-area-context';
3
+ import { isNavigationBarTranslucent } from '../nativeModulesHelpers/UNNavigationBarHelper';
3
4
 
4
5
  const isAndroid = Platform.OS === 'android';
5
6
  const isAndroid10To14 = isAndroid && Platform.Version >= 29 && Platform.Version < 35;
@@ -9,12 +10,20 @@ const insets = initialWindowMetrics?.insets ?? { top: 0, bottom: 0, left: 0, rig
9
10
  const windowHeight = Dimensions.get('window').height;
10
11
  const screenHeight = Dimensions.get('screen').height;
11
12
 
12
- // Detect edge-to-edge by comparing window to screen height
13
- // Edge-to-edge ON: windowHeight ≈ screenHeight | OFF: windowHeight < screenHeight
13
+ // Detect edge-to-edge on API 35+ by comparing window to screen height
14
14
  const heightDifference = Math.abs(screenHeight - windowHeight);
15
15
  const isEdgeToEdgeActive = isAndroid15AndAbove && heightDifference < 10;
16
16
 
17
- const effectiveBottomInset = isEdgeToEdgeActive ? insets.bottom : 0;
17
+ // Resolved once at module load time; defaults to false until resolved.
18
+ // The native call is fast (reads a window flag), so it resolves before
19
+ // any bottom sheet is opened.
20
+ let _navBarTranslucent = false;
21
+
22
+ if (isAndroid) {
23
+ isNavigationBarTranslucent().then((result) => {
24
+ _navBarTranslucent = result;
25
+ });
26
+ }
18
27
 
19
28
  const calculateFullScreenHeight = (): number => {
20
29
  if (isAndroid15AndAbove) {
@@ -41,6 +50,9 @@ const calculateContentHeight = (): number => {
41
50
  const contentHeight = calculateContentHeight();
42
51
 
43
52
  export const useSafeAreaDimensions = () => {
53
+ const shouldApplyBottomInset = isEdgeToEdgeActive || _navBarTranslucent;
54
+ const effectiveBottomInset = shouldApplyBottomInset ? insets.bottom : 0;
55
+
44
56
  return {
45
57
  insets,
46
58
  fullScreenHeight,
@@ -0,0 +1,14 @@
1
+ import { Platform, NativeModules } from 'react-native';
2
+
3
+ const UNNavigationBarModule = Platform.OS === 'android'
4
+ ? NativeModules.UNNavigationBarModule
5
+ : undefined;
6
+
7
+ export async function isNavigationBarTranslucent(): Promise<boolean> {
8
+ if (!UNNavigationBarModule) return false;
9
+ try {
10
+ return await UNNavigationBarModule.isNavigationBarTranslucent();
11
+ } catch {
12
+ return false;
13
+ }
14
+ }
@@ -26,7 +26,7 @@ export class UnitComponentsSDK {
26
26
  protected static fonts?: UNFonts;
27
27
  protected static signedNonce?: string;
28
28
  protected static pushProvisionModule?: typeof NativeModules;
29
- protected static sdkVersion = '3.1.1';
29
+ protected static sdkVersion = '3.1.2-beta.2';
30
30
  static iosFontBase64Map: Record<string, string> = {};
31
31
 
32
32
  public static init = async (