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.
- package/android/src/main/java/com/unitreactnativecomponents/UnitReactNativeComponentsPackage.kt +2 -0
- package/android/src/main/java/com/unitreactnativecomponents/nativeModules/navigationBar/UNNavigationBarModule.kt +38 -0
- package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js +3 -26
- package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js.map +1 -1
- package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.js +37 -37
- package/lib/commonjs/components/UNBottomSheetComponent/UNBottomSheetComponent.js.map +1 -1
- package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js +6 -4
- package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js.map +1 -1
- package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js +7 -6
- package/lib/commonjs/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js.map +1 -1
- package/lib/commonjs/helpers/BottomSheet/BottomSheet.js +21 -12
- package/lib/commonjs/helpers/BottomSheet/BottomSheet.js.map +1 -1
- package/lib/commonjs/helpers/BottomSheet/BottomSheet.styles.js +4 -2
- package/lib/commonjs/helpers/BottomSheet/BottomSheet.styles.js.map +1 -1
- package/lib/commonjs/hooks/useSafeAreaDimensions.js +14 -3
- package/lib/commonjs/hooks/useSafeAreaDimensions.js.map +1 -1
- package/lib/commonjs/nativeModulesHelpers/UNNavigationBarHelper.js +17 -0
- package/lib/commonjs/nativeModulesHelpers/UNNavigationBarHelper.js.map +1 -0
- package/lib/commonjs/unitComponentsSdkManager/UnitComponentsSdkManager.js +1 -1
- package/lib/commonjs/unitComponentsSdkManager/UnitComponentsSdkManager.js.map +1 -1
- package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js +4 -27
- package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.js.map +1 -1
- package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.js +38 -38
- package/lib/module/components/UNBottomSheetComponent/UNBottomSheetComponent.js.map +1 -1
- package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js +6 -4
- package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.js.map +1 -1
- package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js +6 -5
- package/lib/module/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.js.map +1 -1
- package/lib/module/helpers/BottomSheet/BottomSheet.js +22 -13
- package/lib/module/helpers/BottomSheet/BottomSheet.js.map +1 -1
- package/lib/module/helpers/BottomSheet/BottomSheet.styles.js +4 -2
- package/lib/module/helpers/BottomSheet/BottomSheet.styles.js.map +1 -1
- package/lib/module/hooks/useSafeAreaDimensions.js +14 -3
- package/lib/module/hooks/useSafeAreaDimensions.js.map +1 -1
- package/lib/module/nativeModulesHelpers/UNNavigationBarHelper.js +11 -0
- package/lib/module/nativeModulesHelpers/UNNavigationBarHelper.js.map +1 -0
- package/lib/module/unitComponentsSdkManager/UnitComponentsSdkManager.js +1 -1
- package/lib/module/unitComponentsSdkManager/UnitComponentsSdkManager.js.map +1 -1
- package/lib/typescript/src/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.d.ts.map +1 -1
- package/lib/typescript/src/components/UNBottomSheetComponent/UNBottomSheetComponent.d.ts.map +1 -1
- package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.d.ts +1 -0
- package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.d.ts +1 -0
- package/lib/typescript/src/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.d.ts.map +1 -1
- package/lib/typescript/src/helpers/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/helpers/BottomSheet/BottomSheet.styles.d.ts +4 -2
- package/lib/typescript/src/helpers/BottomSheet/BottomSheet.styles.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useSafeAreaDimensions.d.ts.map +1 -1
- package/lib/typescript/src/nativeModulesHelpers/UNNavigationBarHelper.d.ts +2 -0
- package/lib/typescript/src/nativeModulesHelpers/UNNavigationBarHelper.d.ts.map +1 -0
- package/lib/typescript/src/unitComponentsSdkManager/UnitComponentsSdkManager.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/UNBottomSheetComponent/UNBottomSheetComponent.constants.ts +4 -29
- package/src/components/UNBottomSheetComponent/UNBottomSheetComponent.tsx +58 -53
- package/src/components/UNBottomSheetComponent/components/UNBottomSheetNativeComponent/UNBottomSheetNativeComponent.tsx +7 -4
- package/src/components/UNBottomSheetComponent/components/UNBottomSheetSlotComponent/UNBottomSheetSlotComponent.tsx +8 -5
- package/src/helpers/BottomSheet/BottomSheet.styles.ts +4 -2
- package/src/helpers/BottomSheet/BottomSheet.tsx +21 -10
- package/src/hooks/useSafeAreaDimensions.ts +15 -3
- package/src/nativeModulesHelpers/UNNavigationBarHelper.ts +14 -0
- 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 {
|
|
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 {
|
|
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 =
|
|
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,
|
|
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,
|
|
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 {
|
|
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
|
-
?
|
|
117
|
-
:
|
|
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={
|
|
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: '
|
|
22
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
29
|
+
protected static sdkVersion = '3.1.2-beta.2';
|
|
30
30
|
static iosFontBase64Map: Record<string, string> = {};
|
|
31
31
|
|
|
32
32
|
public static init = async (
|