@momo-kits/foundation 0.167.1-beta.7 → 0.167.1-duo.12

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 (46) hide show
  1. package/Application/BottomSheet.tsx +115 -14
  2. package/Application/BottomTab/BottomTabBar.tsx +6 -3
  3. package/Application/BottomTab/DuoBarCompression.tsx +135 -0
  4. package/Application/BottomTab/DuoTabBar.tsx +462 -0
  5. package/Application/BottomTab/index.tsx +155 -134
  6. package/Application/Components/DuoGlassBackground.tsx +179 -0
  7. package/Application/Components/DuoQuickReturnHeader.tsx +42 -0
  8. package/Application/Components/HeaderExtendHeader.tsx +65 -28
  9. package/Application/Components/HeaderLeft.tsx +23 -0
  10. package/Application/Components/HeaderRight.tsx +104 -9
  11. package/Application/Components/HeaderTitle.tsx +47 -21
  12. package/Application/Components/OptionalGlassView.ts +11 -0
  13. package/Application/Components/SearchHeader.tsx +15 -14
  14. package/Application/Components/SideBarButton.tsx +128 -0
  15. package/Application/ModalScreen.tsx +16 -2
  16. package/Application/NavigationContainer.tsx +36 -48
  17. package/Application/Navigator.ts +1 -3
  18. package/Application/StackScreen.tsx +2 -5
  19. package/Application/WidgetContainer.tsx +9 -15
  20. package/Application/device.ts +29 -0
  21. package/Application/types.ts +10 -1
  22. package/Application/utils.tsx +10 -3
  23. package/Consts/index.ts +0 -1
  24. package/Consts/theme.ts +3 -4
  25. package/Input/Input.tsx +3 -4
  26. package/Input/InputMoney.tsx +31 -51
  27. package/Input/InputPhoneNumber.tsx +3 -4
  28. package/Input/InputSearch.tsx +3 -4
  29. package/Input/InputTextArea.tsx +3 -4
  30. package/Layout/Card.tsx +8 -26
  31. package/Layout/FloatingButton.tsx +3 -3
  32. package/Layout/Item.tsx +1 -10
  33. package/Layout/ReservedRegions.tsx +47 -0
  34. package/Layout/Screen.tsx +240 -48
  35. package/Layout/Section.tsx +5 -18
  36. package/Layout/index.ts +4 -4
  37. package/Layout/styles.ts +5 -0
  38. package/Layout/utils.ts +375 -5
  39. package/Popup/PopupNotify.tsx +33 -22
  40. package/Popup/PopupPromotion.tsx +20 -8
  41. package/Popup/utils.ts +32 -0
  42. package/Text/index.tsx +5 -15
  43. package/Text/utils.ts +1 -2
  44. package/package.json +3 -2
  45. package/Consts/designSystemFont.ts +0 -25
  46. package/Layout/GridSystem.tsx +0 -137
@@ -0,0 +1,128 @@
1
+ import React, { ReactNode, useContext } from 'react';
2
+ import {
3
+ StyleProp,
4
+ StyleSheet,
5
+ TouchableOpacity,
6
+ View,
7
+ ViewStyle,
8
+ } from 'react-native';
9
+ import { NavigationButtonProps } from '../types';
10
+ import { ApplicationContext } from '../../Context';
11
+ import { Colors, Radius, Shadow, Spacing } from '../../Consts';
12
+ import { Icon } from '../../Icon';
13
+ import { BadgeDot } from '../../Badge';
14
+ import { DuoMetrics } from '../../Layout/utils';
15
+
16
+ const SIDE_BAR_ICON_SIZE = 24;
17
+
18
+ /**
19
+ * glass material for side bar controls: dark glass under light icons (banner headers),
20
+ * light glass otherwise
21
+ */
22
+ const getGlassStyle = (tintColor?: string) =>
23
+ tintColor === Colors.black_01 || tintColor === 'white'
24
+ ? styles.glassDark
25
+ : styles.glassLight;
26
+
27
+ /**
28
+ * 48pt glass circle used for a single control in the iPhone Duo side bar
29
+ */
30
+ const SideBarButton: React.FC<NavigationButtonProps> = ({
31
+ icon,
32
+ tintColor,
33
+ showBadge = false,
34
+ style,
35
+ ...props
36
+ }) => {
37
+ const { theme } = useContext(ApplicationContext);
38
+
39
+ return (
40
+ <View>
41
+ <TouchableOpacity
42
+ {...props}
43
+ style={[styles.control, getGlassStyle(tintColor), style]}
44
+ >
45
+ <Icon
46
+ source={icon}
47
+ color={tintColor ?? theme.colors.text.default}
48
+ size={SIDE_BAR_ICON_SIZE}
49
+ />
50
+ </TouchableOpacity>
51
+ {showBadge && <BadgeDot size={'small'} style={styles.badgeDot} />}
52
+ </View>
53
+ );
54
+ };
55
+
56
+ /**
57
+ * 48pt wide glass capsule grouping related controls, one item per 50pt
58
+ */
59
+ const SideBarGroup: React.FC<{
60
+ tintColor?: string;
61
+ style?: StyleProp<ViewStyle>;
62
+ children: ReactNode;
63
+ }> = ({ tintColor, style, children }) => {
64
+ const count = React.Children.toArray(children).length;
65
+ const height =
66
+ count > 1 ? count * DuoMetrics.itemPitch : DuoMetrics.controlSize;
67
+
68
+ return (
69
+ <View style={[styles.control, getGlassStyle(tintColor), { height }, style]}>
70
+ {children}
71
+ </View>
72
+ );
73
+ };
74
+
75
+ /**
76
+ * icon item inside a SideBarGroup
77
+ */
78
+ const SideBarGroupItem: React.FC<NavigationButtonProps> = ({
79
+ icon,
80
+ tintColor,
81
+ ...props
82
+ }) => {
83
+ const { theme } = useContext(ApplicationContext);
84
+
85
+ return (
86
+ <TouchableOpacity {...props} style={styles.groupItem}>
87
+ <Icon
88
+ source={icon}
89
+ color={tintColor ?? theme.colors.text.default}
90
+ size={SIDE_BAR_ICON_SIZE}
91
+ />
92
+ </TouchableOpacity>
93
+ );
94
+ };
95
+
96
+ const styles = StyleSheet.create({
97
+ control: {
98
+ width: DuoMetrics.controlSize,
99
+ height: DuoMetrics.controlSize,
100
+ borderRadius: Radius.XL,
101
+ justifyContent: 'center',
102
+ alignItems: 'center',
103
+ },
104
+ glassLight: {
105
+ backgroundColor: Colors.black_01 + 'D9',
106
+ borderWidth: StyleSheet.hairlineWidth,
107
+ borderColor: Colors.black_20 + '14',
108
+ ...Shadow.Light,
109
+ },
110
+ glassDark: {
111
+ backgroundColor: Colors.black_20 + '80',
112
+ borderWidth: StyleSheet.hairlineWidth,
113
+ borderColor: Colors.black_01 + '33',
114
+ },
115
+ groupItem: {
116
+ flex: 1,
117
+ alignSelf: 'stretch',
118
+ justifyContent: 'center',
119
+ alignItems: 'center',
120
+ },
121
+ badgeDot: {
122
+ position: 'absolute',
123
+ top: Spacing.XXS,
124
+ right: Spacing.XXS,
125
+ },
126
+ });
127
+
128
+ export { SideBarButton, SideBarGroup, SideBarGroupItem };
@@ -8,15 +8,18 @@ import {
8
8
  Platform,
9
9
  Pressable,
10
10
  StyleSheet,
11
+ useWindowDimensions,
11
12
  View,
12
13
  } from 'react-native';
14
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
13
15
 
14
16
  import { ApplicationContext, MiniAppContext } from '../Context';
15
17
  import { Styles } from '../Consts';
16
18
  import Navigation from './Navigation';
17
19
  import { ModalParams } from './types';
18
20
  import BottomSheet from './BottomSheet';
19
- import { runOnJS } from 'react-native-reanimated';
21
+ import { getDuoTopInset, isIPhoneDuo } from './device';
22
+ import { scheduleOnRN } from 'react-native-worklets';
20
23
 
21
24
  const ModalScreen: React.FC<any> = props => {
22
25
  if (props.route?.params?.isBottomSheet) {
@@ -37,6 +40,8 @@ const Modal: React.FC<ModalParams> = props => {
37
40
  title,
38
41
  } = props.route.params;
39
42
  const Component = useRef(screen).current;
43
+ const insets = useSafeAreaInsets();
44
+ const windowSize = useWindowDimensions();
40
45
 
41
46
  /**
42
47
  * Fire auto_popup_displayed tracking event on mount
@@ -106,7 +111,7 @@ const Modal: React.FC<ModalParams> = props => {
106
111
  }),
107
112
  ]).start(() => {
108
113
  navigator?.pop();
109
- runOnJS(callback)();
114
+ scheduleOnRN(callback);
110
115
  });
111
116
  },
112
117
  [navigator, opacity, scale],
@@ -147,6 +152,15 @@ const Modal: React.FC<ModalParams> = props => {
147
152
  opacity,
148
153
  transform: [{ scale }],
149
154
  },
155
+ // center below the side status bar and above the home indicator
156
+ isIPhoneDuo() && {
157
+ marginTop: getDuoTopInset(
158
+ insets,
159
+ windowSize.width,
160
+ windowSize.height,
161
+ ),
162
+ marginBottom: insets.bottom,
163
+ },
150
164
  modalStyle,
151
165
  ]}
152
166
  >
@@ -2,7 +2,6 @@ import React, { useContext, useEffect, useRef, useState } from 'react';
2
2
  import {
3
3
  SafeAreaInsetsContext,
4
4
  SafeAreaProvider,
5
- useSafeAreaInsets,
6
5
  } from 'react-native-safe-area-context';
7
6
  import {
8
7
  NavigationContainer as ReactNavigationContainer,
@@ -13,17 +12,17 @@ import {
13
12
  StackNavigationOptions,
14
13
  TransitionPresets,
15
14
  } from '@react-navigation/stack';
16
- import { DeviceEventEmitter } from 'react-native';
17
15
  import StackScreen from './StackScreen';
18
16
  import ModalScreen from './ModalScreen';
19
17
  import Navigator from './Navigator';
20
- import { getModalOptions, getStackOptions, useNativeCanGoBack } from './utils';
18
+ import {
19
+ getModalOptions,
20
+ getStackOptions,
21
+ isWhiteListDesignSystem,
22
+ useNativeCanGoBack,
23
+ } from './utils';
21
24
  import { NavigationContainerProps } from './types';
22
25
  import { ApplicationContext, MiniAppContext } from '../Context';
23
- import {
24
- useDefaultRegularFontFamily,
25
- useResolvedFontFamily,
26
- } from '../Consts/designSystemFont';
27
26
  import Localize from './Localize';
28
27
  import { Colors, defaultTheme } from '../Consts';
29
28
  import { HeaderLeft } from './Components/HeaderLeft';
@@ -31,6 +30,8 @@ import { HeaderRight } from './Components/HeaderRight';
31
30
  import { HeaderTitle } from './Components/HeaderTitle';
32
31
  import { HeaderBackground } from './Components/HeaderBackground';
33
32
  import { type EdgeInsets } from 'react-native-safe-area-context';
33
+ import { useScreenLayout } from '../Layout';
34
+ import { ReservedRegionsProvider } from '../Layout/ReservedRegions';
34
35
 
35
36
  const Stack = createStackNavigator();
36
37
 
@@ -76,17 +77,19 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
76
77
  frame: { x: 0, y: 0, width: 0, height: 0 },
77
78
  }}
78
79
  >
79
- <MiniAppContext.Provider value={mergedContext}>
80
- <Navigation
81
- screen={screen}
82
- theme={theme}
83
- options={options}
84
- maxApi={maxApi}
85
- setCurrentContext={setCurrentContext}
86
- initialParams={initialParams}
87
- localize={localize}
88
- />
89
- </MiniAppContext.Provider>
80
+ <ReservedRegionsProvider>
81
+ <MiniAppContext.Provider value={mergedContext}>
82
+ <Navigation
83
+ screen={screen}
84
+ theme={theme}
85
+ options={options}
86
+ maxApi={maxApi}
87
+ setCurrentContext={setCurrentContext}
88
+ initialParams={initialParams}
89
+ localize={localize}
90
+ />
91
+ </MiniAppContext.Provider>
92
+ </ReservedRegionsProvider>
90
93
  </SafeAreaProvider>
91
94
  );
92
95
  };
@@ -104,11 +107,11 @@ const Navigation: React.FC<any> = ({
104
107
  const navigationRef = useRef<any>(null);
105
108
  const isReady = useRef(false);
106
109
  const navigator = useRef(new Navigator(navigationRef, isReady));
107
- const [showGrid, setShowGrid] = useState(false);
108
- const insets = useSafeAreaInsets();
109
- const defaultRegularFontFamily = useDefaultRegularFontFamily();
110
- const themeFont = useResolvedFontFamily(theme.font);
110
+ const { headerHeight, headerStatusBarHeight } = useScreenLayout();
111
111
  const syncCanGoBack = useNativeCanGoBack();
112
+ const isWhiteList = isWhiteListDesignSystem(context);
113
+ const fontFamily = isWhiteList ? 'MomoTrustSans' : 'SFProText';
114
+ const navigationFontFamily = isWhiteList ? 'MomoTrustSans-Regular' : 'SFProText';
112
115
  let headerBackground = context?.designSystemConfig?.config?.headerBar;
113
116
  let headerGradient = theme.colors?.gradient;
114
117
 
@@ -124,23 +127,6 @@ const Navigation: React.FC<any> = ({
124
127
  */
125
128
  navigator.current.maxApi = maxApi;
126
129
 
127
- /**
128
- * handle mini language & listen change
129
- * engine only shake to enable grid view
130
- */
131
- useEffect(() => {
132
- const subscription = DeviceEventEmitter.addListener(
133
- 'onChangeGrid',
134
- enable => {
135
- setShowGrid(!!enable);
136
- },
137
- );
138
-
139
- return () => {
140
- subscription?.remove?.();
141
- };
142
- }, []);
143
-
144
130
  /**
145
131
  * translate context method
146
132
  * @param data
@@ -160,7 +146,7 @@ const Navigation: React.FC<any> = ({
160
146
  navigator: navigator.current,
161
147
  theme: {
162
148
  ...theme,
163
- font: themeFont,
149
+ font: fontFamily,
164
150
  colors: {
165
151
  ...theme.colors,
166
152
  gradient: headerGradient,
@@ -170,7 +156,6 @@ const Navigation: React.FC<any> = ({
170
156
  headerBackground,
171
157
  },
172
158
  },
173
- showGrid,
174
159
  translate,
175
160
  }}
176
161
  >
@@ -188,19 +173,19 @@ const Navigation: React.FC<any> = ({
188
173
  },
189
174
  fonts: {
190
175
  regular: {
191
- fontFamily: defaultRegularFontFamily,
176
+ fontFamily: navigationFontFamily,
192
177
  fontWeight: '400',
193
178
  },
194
179
  medium: {
195
- fontFamily: defaultRegularFontFamily,
180
+ fontFamily: navigationFontFamily,
196
181
  fontWeight: '400',
197
182
  },
198
183
  bold: {
199
- fontFamily: defaultRegularFontFamily,
184
+ fontFamily: navigationFontFamily,
200
185
  fontWeight: '400',
201
186
  },
202
187
  heavy: {
203
- fontFamily: defaultRegularFontFamily,
188
+ fontFamily: navigationFontFamily,
204
189
  fontWeight: '400',
205
190
  },
206
191
  },
@@ -220,8 +205,9 @@ const Navigation: React.FC<any> = ({
220
205
  headerTitleAlign: 'center',
221
206
  headerTintColor: theme.colors.text.default,
222
207
  headerStyle: {
223
- height: 52 + insets.top,
208
+ height: headerHeight,
224
209
  },
210
+ headerStatusBarHeight,
225
211
  }}
226
212
  >
227
213
  <Stack.Screen
@@ -244,11 +230,13 @@ const Navigation: React.FC<any> = ({
244
230
  cardStyle: {
245
231
  backgroundColor: theme.colors.background.default,
246
232
  },
247
- headerLeft: (props: any) => <HeaderLeft {...props} />,
233
+ headerLeft: (props: any) => <HeaderLeft {...props} floating />,
248
234
  headerBackground: (props: any) => (
249
235
  <HeaderBackground {...props} />
250
236
  ),
251
- headerRight: (props: any) => <HeaderRight {...props} />,
237
+ headerRight: (props: any) => (
238
+ <HeaderRight {...props} floating />
239
+ ),
252
240
  headerTintColor: Colors.black_17,
253
241
  ...TransitionPresets.ModalTransition,
254
242
  }}
@@ -118,9 +118,7 @@ class Navigator {
118
118
  navigate = (name: string) => {
119
119
  if (this.isReady.current) {
120
120
  this.ref.current?.dispatch?.(
121
- CommonActions.navigate({
122
- name,
123
- })
121
+ CommonActions.navigate(name)
124
122
  );
125
123
  }
126
124
  };
@@ -4,7 +4,6 @@ import { useHeaderHeight } from '@react-navigation/elements';
4
4
  import { ScreenTrackingParams } from './types';
5
5
  import Navigation from './Navigation';
6
6
  import { ApplicationContext, MiniAppContext, ScreenContext } from '../Context';
7
- import { GridSystem } from '../Layout';
8
7
  import { version } from '../package.json';
9
8
  import { SwipeBackHaptic, useAppState } from './utils';
10
9
  import { TooltipPortalHost, TooltipPortalProvider } from './TooltipPortal';
@@ -17,7 +16,7 @@ const runAfterInteractions = InteractionManager.runAfterInteractions;
17
16
  * @constructor
18
17
  */
19
18
  const StackScreen: React.FC<any> = props => {
20
- const { showGrid, navigator } = useContext(ApplicationContext);
19
+ const { navigator } = useContext(ApplicationContext);
21
20
  const tracking = useRef<any>({
22
21
  mounted: false,
23
22
  timeoutLoad: undefined,
@@ -42,6 +41,7 @@ const StackScreen: React.FC<any> = props => {
42
41
  });
43
42
  const widgets = useRef<any>([]);
44
43
  const context = useContext<any>(MiniAppContext);
44
+
45
45
  const {
46
46
  screen: Component,
47
47
  options,
@@ -411,10 +411,7 @@ const StackScreen: React.FC<any> = props => {
411
411
  >
412
412
  <TooltipPortalProvider>
413
413
  <Component heightHeader={heightHeader} {...data} />
414
- {showGrid && <GridSystem />}
415
414
  <TooltipPortalHost />
416
- {/* a leaf on purpose: it subscribes to CardAnimationContext, which changes on every
417
- Card render, and must not pull this screen into those renders */}
418
415
  <SwipeBackHaptic />
419
416
  </TooltipPortalProvider>
420
417
  </ScreenContext.Provider>
@@ -3,10 +3,6 @@ import { SafeAreaProvider } from 'react-native-safe-area-context';
3
3
  import Navigator from './Navigator';
4
4
  import { WidgetContainerProps } from './types';
5
5
  import { ApplicationContext, MiniAppContext } from '../Context';
6
- import {
7
- resolveFontFamily,
8
- useDefaultRegularFontFamily,
9
- } from '../Consts/designSystemFont';
10
6
  import Localize from './Localize';
11
7
  import { defaultTheme } from '../Consts';
12
8
  import {
@@ -14,7 +10,7 @@ import {
14
10
  NavigationContainerRef,
15
11
  NavigationIndependentTree,
16
12
  } from '@react-navigation/native';
17
- import { getModalOptions } from './utils';
13
+ import { getModalOptions, isWhiteListDesignSystem } from './utils';
18
14
  import { createStackNavigator } from '@react-navigation/stack';
19
15
  import ModalScreen from './ModalScreen';
20
16
  import { View } from 'react-native';
@@ -46,7 +42,6 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
46
42
  const isReady = useRef(false);
47
43
  const navigator = useRef(new Navigator(navigationRef, isReady, true));
48
44
  const [currentContext, setCurrentContext] = useState({});
49
- const defaultRegularFontFamily = useDefaultRegularFontFamily();
50
45
 
51
46
  useEffect(() => {
52
47
  const sub = maxApi?.observer?.('font_scale_config', (data: any) => {
@@ -83,6 +78,9 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
83
78
  ...context,
84
79
  ...currentContext,
85
80
  };
81
+ const isWhiteList = isWhiteListDesignSystem(mergedContext);
82
+ const fontFamily = isWhiteList ? 'MomoTrustSans' : 'SFProText';
83
+ const navigationFontFamily = isWhiteList ? 'MomoTrustSans-Regular' : 'SFProText';
86
84
 
87
85
  return (
88
86
  <View style={{ height: height ?? '100%', minHeight: 1 }}>
@@ -93,11 +91,7 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
93
91
  navigator: navigator.current,
94
92
  theme: {
95
93
  ...theme,
96
- font: resolveFontFamily(
97
- theme.font,
98
- mergedContext?.designSystemConfig?.isWhiteListDesignSystem ===
99
- true,
100
- ),
94
+ font: fontFamily,
101
95
  colors: {
102
96
  ...theme.colors,
103
97
  gradient: headerGradient,
@@ -124,19 +118,19 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
124
118
  },
125
119
  fonts: {
126
120
  regular: {
127
- fontFamily: defaultRegularFontFamily,
121
+ fontFamily: navigationFontFamily,
128
122
  fontWeight: '400',
129
123
  },
130
124
  medium: {
131
- fontFamily: defaultRegularFontFamily,
125
+ fontFamily: navigationFontFamily,
132
126
  fontWeight: '400',
133
127
  },
134
128
  bold: {
135
- fontFamily: defaultRegularFontFamily,
129
+ fontFamily: navigationFontFamily,
136
130
  fontWeight: '400',
137
131
  },
138
132
  heavy: {
139
- fontFamily: defaultRegularFontFamily,
133
+ fontFamily: navigationFontFamily,
140
134
  fontWeight: '400',
141
135
  },
142
136
  },
@@ -0,0 +1,29 @@
1
+ import { Dimensions, Platform, ScaledSize } from 'react-native';
2
+ import type { EdgeInsets } from 'react-native-safe-area-context';
3
+
4
+ // widest short side of any single-display iPhone
5
+ const IPHONE_MAX_SHORT_SIDE = 440;
6
+
7
+ // iPhone Duo reports idiom "phone"; 'screen' stays on the outer display, so it
8
+ // still matches when Split View narrows the window
9
+ const isIPhoneDuo = () => {
10
+ if (Platform.OS !== 'ios' || Platform.isPad) {
11
+ return false;
12
+ }
13
+ const shortSide = (size: ScaledSize) => Math.min(size.width, size.height);
14
+ return (
15
+ Math.max(
16
+ shortSide(Dimensions.get('screen')),
17
+ shortSide(Dimensions.get('window')),
18
+ ) > IPHONE_MAX_SHORT_SIDE
19
+ );
20
+ };
21
+
22
+ // portrait side status bar is about twice as tall as its inset is wide
23
+ const getDuoTopInset = (insets: EdgeInsets, width: number, height: number) =>
24
+ Math.max(
25
+ insets.top,
26
+ height > width ? Math.max(insets.left, insets.right) * 2 : 0,
27
+ );
28
+
29
+ export { isIPhoneDuo, getDuoTopInset };
@@ -117,7 +117,6 @@ export type Context = {
117
117
  [key: string]: any;
118
118
  theme: Theme;
119
119
  navigator?: NavigatorProps;
120
- showGrid?: boolean;
121
120
  translate?: (data: string | { vi: string; en: string }) => string;
122
121
  };
123
122
 
@@ -258,6 +257,11 @@ export interface HeaderBackProps extends NavigationButtonProps {
258
257
  preventBack?: PopupNotifyProps;
259
258
  onPressLeftHeader?: () => void;
260
259
  onBackHandler?: (goBack: () => void) => void;
260
+ /**
261
+ * Optional. If `true`, the button floats into the iPhone Duo side bar while the
262
+ * device shows one. Set when the button is rendered by the navigation header.
263
+ */
264
+ floating?: boolean;
261
265
  }
262
266
 
263
267
  export type HeaderBackgroundProps = {
@@ -329,6 +333,11 @@ export type BottomTabProps = {
329
333
  blur?: (e: EventArg<'blur', false, unknown>) => void;
330
334
  };
331
335
  floatingButton?: FloatingButtonProps;
336
+ /**
337
+ * iPhone Duo: when the side bar can't hold both bars, which one starts compressed;
338
+ * tapping the compressed one swaps them. Defaults to 'toolbar'
339
+ */
340
+ compressionBehavior?: 'toolbar' | 'tabBar';
332
341
  };
333
342
 
334
343
  export type FloatingButtonProps = {
@@ -73,8 +73,8 @@ const getStackOptions = (): StackNavigationOptions => {
73
73
  left: Spacing.S,
74
74
  },
75
75
  headerBackground: (props: any) => <HeaderBackground {...props} />,
76
- headerLeft: (props: any) => <HeaderLeft {...props} />,
77
- headerRight: (props: any) => <HeaderRight {...props} />,
76
+ headerLeft: (props: any) => <HeaderLeft {...props} floating />,
77
+ headerRight: (props: any) => <HeaderRight {...props} floating />,
78
78
  headerTintColor: Colors.black_17,
79
79
  gestureEnabled: Platform.OS === 'ios',
80
80
  ...TransitionPresets.SlideFromRightIOS,
@@ -129,6 +129,7 @@ const getOptions = (
129
129
  preventBack={params.preventBack}
130
130
  onPressLeftHeader={params.onPressLeftHeader}
131
131
  onBackHandler={params.onBackHandler}
132
+ floating
132
133
  />
133
134
  );
134
135
  if (params.hiddenBack) {
@@ -167,7 +168,9 @@ const getOptions = (
167
168
  ...options,
168
169
  ...{
169
170
  headerRight: (props: any) => {
170
- return <HeaderRight {...props} headerRight={params.headerRight} />;
171
+ return (
172
+ <HeaderRight {...props} headerRight={params.headerRight} floating />
173
+ );
171
174
  },
172
175
  },
173
176
  };
@@ -475,6 +478,9 @@ const SwipeBackHaptic = () => {
475
478
  return null;
476
479
  };
477
480
 
481
+ const isWhiteListDesignSystem = (context: any): boolean =>
482
+ context?.designSystemConfig?.isWhiteListDesignSystem === true;
483
+
478
484
  export {
479
485
  getStackOptions,
480
486
  getModalOptions,
@@ -487,4 +493,5 @@ export {
487
493
  useNativeCanGoBack,
488
494
  useNormalizedSharedValue,
489
495
  SwipeBackHaptic,
496
+ isWhiteListDesignSystem,
490
497
  };
package/Consts/index.ts CHANGED
@@ -2,4 +2,3 @@ export * from './colors+spacing+radius';
2
2
  export * from './theme';
3
3
  export * from './styles';
4
4
  export const GRIDVIEW = false;
5
- export * from './designSystemFont';
package/Consts/theme.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type {Context, Theme} from '../Application/types';
2
- import {Colors} from './colors+spacing+radius';
1
+ import type { Context, Theme } from '../Application/types';
2
+ import { Colors } from './colors+spacing+radius';
3
3
 
4
4
  const defaultTheme: Theme = {
5
5
  dark: false,
@@ -112,10 +112,9 @@ const defaultDarkTheme: Theme = {
112
112
  const defaultContext: Context = {
113
113
  theme: defaultTheme,
114
114
  navigator: undefined,
115
- showGrid: false,
116
115
  translate: () => {
117
116
  return '';
118
117
  },
119
118
  };
120
119
 
121
- export {defaultContext, defaultTheme, defaultDarkTheme};
120
+ export { defaultContext, defaultTheme, defaultDarkTheme };
package/Input/Input.tsx CHANGED
@@ -6,9 +6,8 @@ import React, {
6
6
  useState,
7
7
  } from 'react';
8
8
  import {
9
- NativeSyntheticEvent,
10
9
  TextInput,
11
- TextInputFocusEventData,
10
+ TextInputFocusEvent,
12
11
  TouchableOpacity,
13
12
  View,
14
13
  } from 'react-native';
@@ -102,12 +101,12 @@ const Input = forwardRef(
102
101
  onChangeText?.(text);
103
102
  };
104
103
 
105
- const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
104
+ const _onFocus = (e: TextInputFocusEvent) => {
106
105
  setFocused(true);
107
106
  onFocus?.(e);
108
107
  };
109
108
 
110
- const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
109
+ const _onBlur = (e: TextInputFocusEvent) => {
111
110
  setFocused(false);
112
111
  onBlur?.(e);
113
112
  };