@momo-kits/foundation 0.165.1-beta.4 → 0.165.1-duotest.1

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.
@@ -58,11 +58,13 @@ export default function BottomTabBar({
58
58
  const { theme } = useContext(ApplicationContext);
59
59
  const { routes } = state;
60
60
  const widthDevice = useWindowDimensions()?.width;
61
+ const insets = useSafeAreaInsets();
61
62
  const useFloating = floatingButton && state.routes.length % 2 === 0;
62
- const itemWidth = widthDevice / (state.routes.length + (useFloating ? 1 : 0));
63
+ const itemWidth =
64
+ (widthDevice - insets.left - insets.right) /
65
+ (state.routes.length + (useFloating ? 1 : 0));
63
66
  // const buildLink = useLinkBuilder();
64
67
  const indicatorAnimated = useSharedValue(0);
65
- const insets = useSafeAreaInsets();
66
68
 
67
69
  const indicatorStyle = useAnimatedStyle(() => ({
68
70
  width: itemWidth,
@@ -246,7 +248,8 @@ export default function BottomTabBar({
246
248
  },
247
249
  {
248
250
  paddingBottom: paddingBottom,
249
- paddingHorizontal: Math.max(insets.left, insets.right),
251
+ paddingLeft: insets.left,
252
+ paddingRight: insets.right,
250
253
  },
251
254
  style,
252
255
  ]}
@@ -233,18 +233,17 @@ const BottomTab: React.FC<BottomTabProps> = ({
233
233
  });
234
234
  }, [itemWidth, indicatorAnimated]);
235
235
 
236
- // TEMP: commented out to test whether the blur reset is needed on a real host.
237
- // Without it, pushing a screen from a tab other than the first leaves the flag true, so that
238
- // pushed screen gets the host floating-arrow instead of its own card swipe-back.
239
- // useFocusEffect(
240
- // React.useCallback(() => {
241
- // NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(
242
- // activeIndex.current !== 0,
243
- // );
244
- // return () =>
245
- // NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(false);
246
- // }, []),
247
- // );
236
+ // Focus, not mount: pushing a screen from a tab leaves BottomTab mounted but blurred, and
237
+ // onFocus only fires on tab changes.
238
+ useFocusEffect(
239
+ React.useCallback(() => {
240
+ NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(
241
+ activeIndex.current !== 0,
242
+ );
243
+ return () =>
244
+ NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(false);
245
+ }, []),
246
+ );
248
247
 
249
248
  const onFocus = (e: any) => {
250
249
  activeIndex.current = tabs.findIndex(i => e.target.includes(i.name));
@@ -253,10 +252,11 @@ const BottomTab: React.FC<BottomTabProps> = ({
253
252
  });
254
253
 
255
254
  const isFirstTab = activeIndex.current === 0;
255
+ const gestureEnabled = Platform.OS === 'ios' && isFirstTab;
256
256
  navigation?.setOptions({
257
- gestureEnabled: Platform.OS === 'ios' && isFirstTab,
257
+ gestureEnabled: gestureEnabled,
258
258
  });
259
- NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(!isFirstTab);
259
+ NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(!gestureEnabled);
260
260
  };
261
261
 
262
262
  const handler: {
@@ -10,10 +10,20 @@ import { Image } from '../../Image';
10
10
  import { Colors } from '../../Consts';
11
11
  import { useNormalizedSharedValue } from '../utils';
12
12
 
13
+ const ASPECT_RATIOS: Record<
14
+ NonNullable<HeaderAnimatedProps['aspectRatio']>,
15
+ number
16
+ > = {
17
+ '16/9': 16 / 9,
18
+ '3/2': 3 / 2,
19
+ '1/1': 1 / 1,
20
+ };
21
+
13
22
  const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
14
23
  animatedValue,
15
24
  image,
16
25
  useScale = true,
26
+ aspectRatio = '16/9',
17
27
  children,
18
28
  }) => {
19
29
  const sharedValue = useNormalizedSharedValue(animatedValue);
@@ -40,7 +50,13 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
40
50
  });
41
51
 
42
52
  return (
43
- <Animated.View style={[styles.container, animatedStyle]}>
53
+ <Animated.View
54
+ style={[
55
+ styles.container,
56
+ { aspectRatio: ASPECT_RATIOS[aspectRatio] },
57
+ animatedStyle,
58
+ ]}
59
+ >
44
60
  {children ?? (
45
61
  <Image
46
62
  source={{
@@ -54,7 +70,7 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
54
70
  };
55
71
 
56
72
  const styles = StyleSheet.create({
57
- container: { width: '100%', aspectRatio: 16 / 9 },
73
+ container: { width: '100%' },
58
74
  verifiedDot: {
59
75
  width: 4,
60
76
  height: 4,
@@ -1,6 +1,6 @@
1
1
  import React, { Ref, useContext } from 'react';
2
2
  import LinearGradient from 'react-native-linear-gradient';
3
- import { Dimensions, Platform, StyleSheet, View } from 'react-native';
3
+ import { Platform, StyleSheet, View } from 'react-native';
4
4
  import Animated, {
5
5
  Extrapolation,
6
6
  interpolate,
@@ -18,12 +18,11 @@ import {
18
18
  AnimatedCompatValue,
19
19
  useNormalizedSharedValue,
20
20
  } from '../utils';
21
+ import { useHorizontalLayout } from '../../Layout/utils';
21
22
 
22
23
  const SCREEN_PADDING = 12;
23
24
  const BACK_WIDTH = 28;
24
25
 
25
- const { width: screenWidth } = Dimensions.get('window');
26
-
27
26
  const HeaderExtendHeader: React.FC<{
28
27
  headerType?: HeaderType;
29
28
  animatedValue: AnimatedCompatValue;
@@ -52,6 +51,8 @@ const HeaderExtendHeader: React.FC<{
52
51
  const gradientColor = customGradientColor ?? theme.colors.gradient;
53
52
  const headerBackground = customBackground ?? theme.assets?.headerBackground;
54
53
  const leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;
54
+ const layout = useHorizontalLayout(SCREEN_PADDING);
55
+ const { insets } = layout;
55
56
 
56
57
  let useShadowHeader = useShadowHeaderProp;
57
58
  if (inputSearchProps && Platform.OS === 'android') {
@@ -79,7 +80,7 @@ const HeaderExtendHeader: React.FC<{
79
80
  translateX: interpolate(
80
81
  sharedValue.value,
81
82
  [0, 100],
82
- [SCREEN_PADDING, leftPosition],
83
+ [layout.marginLeft, leftPosition + insets.left],
83
84
  Extrapolation.CLAMP,
84
85
  ),
85
86
  },
@@ -88,8 +89,8 @@ const HeaderExtendHeader: React.FC<{
88
89
  sharedValue.value,
89
90
  [0, 100],
90
91
  [
91
- screenWidth - SCREEN_PADDING * 2,
92
- screenWidth - leftPosition - 12 - headerRightWidth,
92
+ layout.width,
93
+ layout.width + SCREEN_PADDING - leftPosition - headerRightWidth,
93
94
  ],
94
95
  Extrapolation.CLAMP,
95
96
  ),
@@ -1,5 +1,5 @@
1
1
  import { BackHandler, StyleSheet, View } from 'react-native';
2
- import { HeaderBackProps } from '../types';
2
+ import type { HeaderBackProps } from '../types';
3
3
  import React, { useCallback, useContext, useEffect } from 'react';
4
4
  import { ApplicationContext, MiniAppContext } from '../../Context';
5
5
  import { PopupNotify } from '../../Popup';
@@ -1,17 +1,13 @@
1
1
  import { Colors, Radius, Spacing, Styles } from '../../Consts';
2
2
  import { InputRef, InputSearch } from '../../Input';
3
- import {
4
- Dimensions,
5
- StyleSheet,
6
- TouchableOpacity,
7
- View,
8
- } from 'react-native';
3
+ import { StyleSheet, TouchableOpacity, View } from 'react-native';
9
4
  import Animated, { useAnimatedStyle } from 'react-native-reanimated';
10
5
  import React, { useContext } from 'react';
11
6
  import { SearchHeaderProps } from '../types';
12
7
  import { ApplicationContext, MiniAppContext } from '../../Context';
13
8
  import { Text } from '../../Text';
14
9
  import { useNormalizedSharedValue } from '../utils';
10
+ import { useHorizontalLayout } from '../../Layout/utils';
15
11
 
16
12
  const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
17
13
  (
@@ -27,7 +23,7 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
27
23
  const { theme, navigator } = useContext(ApplicationContext);
28
24
  const context = useContext<any>(MiniAppContext);
29
25
  const BACK_WIDTH = 28;
30
- const { width: screenWidth } = Dimensions.get('window');
26
+ const { width: safeWidth } = useHorizontalLayout(0);
31
27
 
32
28
  const sharedValue = useNormalizedSharedValue(animatedValue);
33
29
  const leftPosition = props?.leftPosition ?? BACK_WIDTH + 20;
@@ -77,7 +73,7 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
77
73
  style={[
78
74
  Styles.flex,
79
75
  renderButtons && {
80
- maxWidth: screenWidth - leftPosition - 12 - headerRightWidth,
76
+ maxWidth: safeWidth - leftPosition - 12 - headerRightWidth,
81
77
  },
82
78
  ]}
83
79
  >
@@ -1,5 +1,6 @@
1
1
  import React, { useContext, useEffect, useRef, useState } from 'react';
2
2
  import {
3
+ SafeAreaInsetsContext,
3
4
  SafeAreaProvider,
4
5
  useSafeAreaInsets,
5
6
  } from 'react-native-safe-area-context';
@@ -25,6 +26,7 @@ import { HeaderLeft } from './Components/HeaderLeft';
25
26
  import { HeaderRight } from './Components/HeaderRight';
26
27
  import { HeaderTitle } from './Components/HeaderTitle';
27
28
  import { HeaderBackground } from './Components/HeaderBackground';
29
+ import { type EdgeInsets } from 'react-native-safe-area-context';
28
30
 
29
31
  const Stack = createStackNavigator();
30
32
 
@@ -61,8 +63,15 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
61
63
  },
62
64
  };
63
65
 
66
+ const parentInsets = useContext(SafeAreaInsetsContext);
67
+
64
68
  return (
65
- <SafeAreaProvider>
69
+ <SafeAreaProvider
70
+ initialMetrics={{
71
+ insets: parentInsets as EdgeInsets,
72
+ frame: { x: 0, y: 0, width: 0, height: 0 },
73
+ }}
74
+ >
66
75
  <MiniAppContext.Provider value={mergedContext}>
67
76
  <Navigation
68
77
  screen={screen}
@@ -229,6 +229,8 @@ export type HeaderTitleProps = {
229
229
  data: TitleUserProps | TitleLocationProps | TitleJourneyProps;
230
230
  };
231
231
 
232
+ export type HeaderType = 'default' | 'extended' | 'none';
233
+
232
234
  export interface NavigationOptions
233
235
  extends Omit<StackNavigationOptions, 'headerRight' | 'headerTitle'> {
234
236
  preventBack?: PopupNotifyProps;
@@ -302,6 +304,7 @@ export interface HeaderAnimatedProps extends ViewProps {
302
304
  animatedValue: Animated.Value | SharedValue<number>;
303
305
  image: string;
304
306
  useScale?: boolean;
307
+ aspectRatio?: '16/9' | '3/2' | '1/1';
305
308
  }
306
309
 
307
310
  export type BottomTabItemProps = {
package/Button/index.tsx CHANGED
@@ -1,5 +1,6 @@
1
1
  import React, { FC, useContext, useRef } from 'react';
2
2
  import {
3
+ Platform,
3
4
  StyleSheet,
4
5
  TouchableOpacity,
5
6
  TouchableOpacityProps,
@@ -283,6 +284,17 @@ const Button: FC<ButtonProps> = ({
283
284
  { keypath: 'base pink 2.Ellipse 1.Stroke 1', color: textColor },
284
285
  ]}
285
286
  style={[style, { borderRadius: Spacing.M }]}
287
+ webStyle={
288
+ Platform.OS === 'web'
289
+ ? {
290
+ width: iconSize,
291
+ height: iconSize,
292
+ marginRight: isLeft ? space : 0,
293
+ marginLeft: isLeft ? 0 : space,
294
+ borderRadius: Spacing.M,
295
+ }
296
+ : undefined
297
+ }
286
298
  />
287
299
  );
288
300
  }
@@ -144,6 +144,14 @@ const Colors = {
144
144
  red_09: '#fee8ea',
145
145
  red_10: '#fef4f4',
146
146
  red_11: '#fef8f8',
147
+ opacity_white_20: '#ffffff33',
148
+ opacity_white_40: '#ffffff66',
149
+ opacity_white_60: '#ffffff99',
150
+ opacity_white_80: '#ffffffcc',
151
+ opacity_black_20: '#00000033',
152
+ opacity_black_40: '#00000066',
153
+ opacity_black_60: '#00000099',
154
+ opacity_black_80: '#000000cc',
147
155
  };
148
156
  const Spacing = {
149
157
  XXS: 2,
package/Consts/theme.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {Context, Theme} from '../Application/types';
1
+ import type {Context, Theme} from '../Application/types';
2
2
  import {Colors} from './colors+spacing+radius';
3
3
 
4
4
  const defaultTheme: Theme = {
package/Layout/Card.tsx CHANGED
@@ -1,6 +1,6 @@
1
1
  import React, { useContext } from 'react';
2
- import { Dimensions, View, ViewProps } from 'react-native';
3
- import { useGridSystem } from './utils';
2
+ import { View, ViewProps } from 'react-native';
3
+ import { useGridSystem, useHorizontalLayout } from './utils';
4
4
  import { GridContextProps } from './types';
5
5
  import { GridContext, GridSystem } from './index';
6
6
  import { Image } from '../Image';
@@ -32,7 +32,8 @@ const Card: React.FC<CardProps> = ({
32
32
 
33
33
  const gutterSize = 8;
34
34
  const margin = 12;
35
- const widthSection = Dimensions.get('window').width - margin * 2;
35
+ const layout = useHorizontalLayout(margin);
36
+ const widthSection = layout.width;
36
37
  let sizePerSpan =
37
38
  (widthSection - margin * 2 - gutterSize * (numberOfColumns - 1)) /
38
39
  numberOfColumns -
@@ -76,7 +77,8 @@ const Card: React.FC<CardProps> = ({
76
77
  styles.card,
77
78
  {
78
79
  width: widthSection,
79
- marginHorizontal: margin,
80
+ marginLeft: layout.marginLeft,
81
+ marginRight: layout.marginRight,
80
82
  gap: gutterSize,
81
83
  },
82
84
  !!backgroundImage && { backgroundColor: undefined },
@@ -19,6 +19,7 @@ import {
19
19
  AnimatedCompatValue,
20
20
  useNormalizedSharedValue,
21
21
  } from '../Application/utils';
22
+ import { useHorizontalLayout } from './utils';
22
23
 
23
24
  export interface FloatingButtonProps {
24
25
  label?: string;
@@ -55,6 +56,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
55
56
  const lastOffset = useSharedValue(0);
56
57
  const lastDirection = useSharedValue<string | null>(null);
57
58
  const [showText, setShowText] = useState(true);
59
+ const { marginRight } = useHorizontalLayout(12);
58
60
 
59
61
  useEffect(() => {
60
62
  if (!label) return;
@@ -118,7 +120,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
118
120
  style={[
119
121
  styles.container,
120
122
  {
121
- right: position === 'right' ? 12 : undefined,
123
+ right: position === 'right' ? marginRight : undefined,
122
124
  alignSelf: position === 'center' ? 'center' : 'flex-end',
123
125
  bottom,
124
126
  },
@@ -135,7 +137,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
135
137
  style={[
136
138
  styles.container,
137
139
  {
138
- right: position === 'right' ? 12 : undefined,
140
+ right: position === 'right' ? marginRight : undefined,
139
141
  alignSelf: position === 'center' ? 'center' : 'flex-end',
140
142
  height: size === 'small' ? 36 : 48,
141
143
  backgroundColor: theme.colors.primary,
package/Layout/Screen.tsx CHANGED
@@ -26,7 +26,10 @@ import {
26
26
  ViewProps,
27
27
  } from 'react-native';
28
28
  import { useSharedValue, withTiming } from 'react-native-reanimated';
29
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
29
+ import {
30
+ useSafeAreaFrame,
31
+ useSafeAreaInsets,
32
+ } from 'react-native-safe-area-context';
30
33
  import { ApplicationContext, ScreenContext } from '../Context';
31
34
  import Navigation from '../Application/Navigation';
32
35
  import {
@@ -96,6 +99,14 @@ export interface ScreenProps extends ViewProps {
96
99
  */
97
100
  footerComponent?: ReactNode;
98
101
 
102
+ /**
103
+ * Optional. If `true`, the footer is inset by the standard horizontal margin
104
+ * (12pt each side). Set `false` for a footer that should span the full width —
105
+ * e.g. one that already carries its own horizontal padding.
106
+ * Defaults to `true`, on every platform.
107
+ */
108
+ marginFooter?: boolean;
109
+
99
110
  /**
100
111
  * Optional. Background color of the screen.
101
112
  */
@@ -104,7 +115,7 @@ export interface ScreenProps extends ViewProps {
104
115
  /**
105
116
  * Optional. layout card offset overlap header banner.
106
117
  */
107
- layoutOffset?: -8 | -24 | -56;
118
+ layoutOffset?: -8 | -24 | -56 | number;
108
119
 
109
120
  /**
110
121
  * Optional. Width of the right header.
@@ -174,6 +185,7 @@ const Screen = forwardRef(
174
185
  scrollViewProps,
175
186
  headerComponent: Header,
176
187
  footerComponent: Footer,
188
+ marginFooter = true,
177
189
  layoutOffset = -56,
178
190
  headerRightWidth = 73,
179
191
  backgroundColor,
@@ -196,6 +208,7 @@ const Screen = forwardRef(
196
208
  const { theme, navigator } = useContext(ApplicationContext);
197
209
  const screen: any = useContext(ScreenContext);
198
210
  const insets = useSafeAreaInsets();
211
+ const frame = useSafeAreaFrame();
199
212
  const heightHeader = useHeaderHeight();
200
213
 
201
214
  /**
@@ -608,12 +621,31 @@ const Screen = forwardRef(
608
621
  }
609
622
  };
610
623
 
624
+ // Cap the screen container height so a scrollable body with a sticky footer
625
+ // can't push the footer past the visible frame (web previews measure the
626
+ // safe-area frame from the seeded SafeAreaProvider metrics). Subtract the
627
+ // bottom tab bar when present and the header unless it's an animated/extended
628
+ // header (those overlay rather than offset the body).
629
+ const getHeight = () => {
630
+ let newHeight = frame.height;
631
+ if (isTab) {
632
+ newHeight -= 64 + Math.min(insets.bottom, 21);
633
+ }
634
+ if (!animatedHeader && headerType !== 'extended') {
635
+ newHeight -= heightHeader;
636
+ }
637
+ return newHeight;
638
+ };
639
+
611
640
  return (
612
641
  <View
613
642
  style={[
614
643
  Styles.flex,
615
644
  {
616
645
  backgroundColor: backgroundColor ?? theme.colors.background.default,
646
+ // Web-only cap so a scrollable body with a sticky footer can't push
647
+ // the footer past the frame. Native handles this without a cap.
648
+ maxHeight: Platform.OS === 'web' ? getHeight() : undefined,
617
649
  },
618
650
  ]}
619
651
  >
@@ -679,7 +711,9 @@ const Screen = forwardRef(
679
711
  },
680
712
  ]}
681
713
  >
682
- <Section>{Footer}</Section>
714
+ {/* The footer inset is a caller decision, not a platform one — a footer
715
+ that carries its own horizontal padding passes `marginFooter={false}`. */}
716
+ <Section useMargin={marginFooter}>{Footer}</Section>
683
717
  </View>
684
718
  )}
685
719
  </KeyboardAvoidingView>
@@ -1,6 +1,6 @@
1
1
  import React, { useContext } from 'react';
2
- import { Dimensions, View, ViewProps } from 'react-native';
3
- import { useGridSystem } from './utils';
2
+ import { useWindowDimensions, View, ViewProps } from 'react-native';
3
+ import { useGridSystem, useHorizontalLayout } from './utils';
4
4
  import { GridContextProps } from './types';
5
5
  import { GridContext } from './index';
6
6
  import { ApplicationContext, MiniAppContext } from '../Context';
@@ -38,14 +38,9 @@ const Section: React.FC<SectionProps> = ({
38
38
  const { numberOfColumns } = useGridSystem();
39
39
 
40
40
  const gutterSize = 12;
41
- let margin = 0;
42
- if (useMargin) {
43
- margin = 12;
44
- }
45
- let widthSection = Dimensions.get('window').width;
46
- if (useMargin) {
47
- widthSection = widthSection - margin * 2;
48
- }
41
+ const layout = useHorizontalLayout(12);
42
+ const { width: windowWidth } = useWindowDimensions();
43
+ const widthSection = useMargin ? layout.width : windowWidth;
49
44
 
50
45
  const sizePerSpan =
51
46
  (widthSection - gutterSize * (numberOfColumns - 1)) / numberOfColumns -
@@ -77,7 +72,8 @@ const Section: React.FC<SectionProps> = ({
77
72
  styles.protectedStyle,
78
73
  {
79
74
  width: widthSection,
80
- marginHorizontal: margin,
75
+ marginLeft: useMargin ? layout.marginLeft : 0,
76
+ marginRight: useMargin ? layout.marginRight : 0,
81
77
  flexDirection: 'row',
82
78
  flexWrap: 'wrap',
83
79
  gap: gutterSize,
package/Layout/utils.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import React, { Fragment, ReactElement } from 'react';
2
2
  import { useWindowDimensions } from 'react-native';
3
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
3
4
 
4
5
  /**
5
6
  * validate children type
@@ -44,4 +45,18 @@ const useGridSystem = () => {
44
45
  return { numberOfColumns };
45
46
  };
46
47
 
47
- export { useGridSystem, validateChildren };
48
+ // Side insets are 0 on portrait iPhones; iPhone Duo and landscape report them
49
+ const useHorizontalLayout = (margin: number) => {
50
+ const { width } = useWindowDimensions();
51
+ const insets = useSafeAreaInsets();
52
+ const marginLeft = margin + insets.left;
53
+ const marginRight = margin + insets.right;
54
+ return {
55
+ marginLeft,
56
+ marginRight,
57
+ width: width - marginLeft - marginRight,
58
+ insets,
59
+ };
60
+ };
61
+
62
+ export { useGridSystem, useHorizontalLayout, validateChildren };
@@ -1,4 +1,5 @@
1
1
  import React, { FC, useContext } from 'react';
2
+ import { Platform } from 'react-native';
2
3
  import AnimatedLottieView from 'lottie-react-native';
3
4
  import animation from '../Assets/DotAnimation.json';
4
5
  import { ApplicationContext } from '../Context';
@@ -29,6 +30,7 @@ const DotLoader: FC<LoaderProps> = ({ color, style }) => {
29
30
  <AnimatedLottieView
30
31
  source={source}
31
32
  style={[{ width: 52, height: 18 }, style]}
33
+ webStyle={Platform.OS === 'web' ? { width: 52, height: 18 } : undefined}
32
34
  autoPlay
33
35
  />
34
36
  );
@@ -1,4 +1,5 @@
1
1
  import React, { FC, useContext } from 'react';
2
+ import { Platform } from 'react-native';
2
3
  import AnimatedLottieView from 'lottie-react-native';
3
4
  import animation from '../Assets/SpinnerAnimation.json';
4
5
  import { hexToRGBA } from './utils';
@@ -21,6 +22,7 @@ const Spinner: FC<LoaderProps> = ({ color, style }) => {
21
22
  <AnimatedLottieView
22
23
  source={source}
23
24
  style={[{ width: 24, height: 24 }, style]}
25
+ webStyle={Platform.OS === 'web' ? { width: 24, height: 24 } : undefined}
24
26
  autoPlay
25
27
  />
26
28
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.165.1-beta.4",
3
+ "version": "0.165.1-duotest.1",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},