@momo-kits/foundation 0.167.1-beta.7 → 0.167.1-duo.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.
@@ -6,10 +6,9 @@ import React, {
6
6
  useState,
7
7
  } from 'react';
8
8
  import {
9
- NativeSyntheticEvent,
10
9
  StyleSheet,
11
10
  TextInput,
12
- TextInputFocusEventData,
11
+ TextInputFocusEvent,
13
12
  TouchableOpacity,
14
13
  View,
15
14
  } from 'react-native';
@@ -93,12 +92,12 @@ const InputPhoneNumber = forwardRef(
93
92
  onChangeText?.(text);
94
93
  };
95
94
 
96
- const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
95
+ const _onFocus = (e: TextInputFocusEvent) => {
97
96
  setFocused(true);
98
97
  onFocus?.(e);
99
98
  };
100
99
 
101
- const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
100
+ const _onBlur = (e: TextInputFocusEvent) => {
102
101
  setFocused(false);
103
102
  onBlur?.(e);
104
103
  };
@@ -10,9 +10,8 @@ import React, {
10
10
  useState,
11
11
  } from 'react';
12
12
  import {
13
- NativeSyntheticEvent,
14
13
  TextInput,
15
- TextInputFocusEventData,
14
+ TextInputFocusEvent,
16
15
  TouchableOpacity,
17
16
  View,
18
17
  } from 'react-native';
@@ -166,12 +165,12 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
166
165
  props.accessibilityLabel,
167
166
  );
168
167
 
169
- const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
168
+ const _onFocus = (e: TextInputFocusEvent) => {
170
169
  setFocused(true);
171
170
  onFocus?.(e);
172
171
  };
173
172
 
174
- const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
173
+ const _onBlur = (e: TextInputFocusEvent) => {
175
174
  setFocused(false);
176
175
  onBlur?.(e);
177
176
  };
@@ -7,9 +7,8 @@ import React, {
7
7
  useState,
8
8
  } from 'react';
9
9
  import {
10
- NativeSyntheticEvent,
11
10
  TextInput,
12
- TextInputFocusEventData,
11
+ TextInputFocusEvent,
13
12
  TouchableOpacity,
14
13
  View,
15
14
  } from 'react-native';
@@ -79,12 +78,12 @@ const InputTextArea = forwardRef(
79
78
  setInputValue(text);
80
79
  };
81
80
 
82
- const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
81
+ const _onFocus = (e: TextInputFocusEvent) => {
83
82
  setFocused(true);
84
83
  onFocus?.(e);
85
84
  };
86
85
 
87
- const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
86
+ const _onBlur = (e: TextInputFocusEvent) => {
88
87
  setFocused(false);
89
88
  onBlur?.(e);
90
89
  };
package/Layout/Card.tsx CHANGED
@@ -1,12 +1,12 @@
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, useScreenLayout } from './utils';
4
4
  import { GridContextProps } from './types';
5
- import { GridContext, GridSystem } from './index';
5
+ import { GridContext } from './index';
6
6
  import { Image } from '../Image';
7
- import { ApplicationContext, MiniAppContext } from '../Context';
7
+ import { ApplicationContext } from '../Context';
8
8
  import styles from './styles';
9
- import { Colors, Radius, Shadow, Spacing } from '../Consts';
9
+ import { Radius, Shadow, Spacing } from '../Consts';
10
10
 
11
11
  export interface CardProps extends ViewProps {
12
12
  /**
@@ -27,12 +27,13 @@ const Card: React.FC<CardProps> = ({
27
27
  useShadow = false,
28
28
  ...props
29
29
  }) => {
30
- const { showGrid, theme } = useContext(ApplicationContext);
30
+ const { theme } = useContext(ApplicationContext);
31
31
  const { numberOfColumns } = useGridSystem();
32
+ const { contentWidth } = useScreenLayout();
32
33
 
33
34
  const gutterSize = 8;
34
35
  const margin = 12;
35
- const widthSection = Dimensions.get('window').width - margin * 2;
36
+ const widthSection = contentWidth - margin * 2;
36
37
  let sizePerSpan =
37
38
  (widthSection - margin * 2 - gutterSize * (numberOfColumns - 1)) /
38
39
  numberOfColumns -
@@ -47,23 +48,6 @@ const Card: React.FC<CardProps> = ({
47
48
  },
48
49
  };
49
50
 
50
- /**
51
- * render overlay only dev mode
52
- */
53
- const renderOverlay = () => {
54
- return (
55
- <>
56
- <GridSystem
57
- width={widthSection}
58
- gutterSize={Spacing.S}
59
- screenGrid={false}
60
- gridColor={Colors.red_01}
61
- />
62
- <View pointerEvents={'none'} style={styles.boxGridCard} />
63
- </>
64
- );
65
- };
66
-
67
51
  return (
68
52
  <GridContext.Provider value={gridContext}>
69
53
  <View
@@ -95,9 +79,7 @@ const Card: React.FC<CardProps> = ({
95
79
  ]}
96
80
  />
97
81
  )}
98
- {/* Render only allowed children as valid React elements */}
99
82
  {children}
100
- {showGrid && renderOverlay()}
101
83
  </View>
102
84
  </GridContext.Provider>
103
85
  );
@@ -10,8 +10,8 @@ import Animated, {
10
10
  useAnimatedStyle,
11
11
  useSharedValue,
12
12
  withTiming,
13
- runOnJS,
14
13
  } from 'react-native-reanimated';
14
+ import { scheduleOnRN } from 'react-native-worklets';
15
15
  import { ApplicationContext } from '../Context';
16
16
  import { Icon } from '../Icon';
17
17
  import { useScaleSize, exportFontFamily } from '../Text';
@@ -78,7 +78,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
78
78
  minWidth,
79
79
  { duration: 100 },
80
80
  finished => {
81
- if (finished) runOnJS(setShowText)(false);
81
+ if (finished) scheduleOnRN(setShowText, false);
82
82
  },
83
83
  );
84
84
  } else {
@@ -87,7 +87,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
87
87
  maxWidth.value,
88
88
  { duration: 100 },
89
89
  finished => {
90
- if (finished) runOnJS(setShowText)(true);
90
+ if (finished) scheduleOnRN(setShowText, true);
91
91
  },
92
92
  );
93
93
  }
package/Layout/Item.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import React, { useContext } from 'react';
2
2
  import { View, ViewProps } from 'react-native';
3
3
  import { GridContext } from './index';
4
- import { ApplicationContext, MiniAppContext } from '../Context';
4
+ import { MiniAppContext } from '../Context';
5
5
  import styles from './styles';
6
6
  import { SpanNumber } from './types';
7
7
 
@@ -23,19 +23,11 @@ const Item: React.FC<ItemProps> = ({
23
23
  children,
24
24
  style,
25
25
  }) => {
26
- const { showGrid } = useContext(ApplicationContext);
27
26
  const context = useContext<any>(MiniAppContext);
28
27
  const grid = useContext(GridContext);
29
28
 
30
29
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
31
30
 
32
- /**
33
- * render overlay view only dev mode
34
- */
35
- const renderOverlay = () => {
36
- return <View pointerEvents={'none'} style={styles.boxGrid} />;
37
- };
38
-
39
31
  return (
40
32
  <View
41
33
  style={[
@@ -49,7 +41,6 @@ const Item: React.FC<ItemProps> = ({
49
41
  ]}
50
42
  >
51
43
  {children}
52
- {showGrid && renderOverlay()}
53
44
  </View>
54
45
  );
55
46
  };
package/Layout/Screen.tsx CHANGED
@@ -21,7 +21,6 @@ import {
21
21
  ScrollViewProps,
22
22
  StatusBar,
23
23
  StatusBarStyle,
24
- useWindowDimensions,
25
24
  View,
26
25
  ViewProps,
27
26
  } from 'react-native';
@@ -44,7 +43,7 @@ import styles from './styles';
44
43
  import { HeaderType } from './types';
45
44
  import { InputRef } from '../Input';
46
45
  import { exportHeaderTitle, getOptions } from '../Application/utils';
47
- import { validateChildren } from './utils';
46
+ import { getHeaderMargin, useScreenLayout, validateChildren } from './utils';
48
47
  import Section from './Section';
49
48
  import {
50
49
  HeaderBackground,
@@ -118,7 +117,8 @@ export interface ScreenProps extends ViewProps {
118
117
  layoutOffset?: -8 | -24 | -56 | number;
119
118
 
120
119
  /**
121
- * Optional. Width of the right header.
120
+ * Optional. Width of the right header. Defaults to the toolkit width (73), or 0 when
121
+ * iPhone Duo floats the toolkit into its side bar.
122
122
  */
123
123
  headerRightWidth?: 0 | 73 | 110 | number;
124
124
 
@@ -187,7 +187,7 @@ const Screen = forwardRef(
187
187
  footerComponent: Footer,
188
188
  marginFooter = true,
189
189
  layoutOffset = -56,
190
- headerRightWidth = 73,
190
+ headerRightWidth,
191
191
  backgroundColor,
192
192
  headerType = 'default',
193
193
  floatingButtonProps,
@@ -204,8 +204,8 @@ const Screen = forwardRef(
204
204
  ref: any,
205
205
  ) => {
206
206
  const screenRef = useRef<View | ScrollView>(null);
207
- const { width: widthDevice } = useWindowDimensions();
208
- const { theme, navigator } = useContext(ApplicationContext);
207
+ const layout = useScreenLayout();
208
+ const { theme } = useContext(ApplicationContext);
209
209
  const screen: any = useContext(ScreenContext);
210
210
  const insets = useSafeAreaInsets();
211
211
  const frame = useSafeAreaFrame();
@@ -245,7 +245,7 @@ const Screen = forwardRef(
245
245
  }, [customAnimatedValue, internalShared]);
246
246
 
247
247
  const currentTint = useRef<string | undefined>(undefined);
248
-
248
+
249
249
  const isTab = !!screen?.bottomTab;
250
250
 
251
251
  let handleScroll;
@@ -425,7 +425,13 @@ const Screen = forwardRef(
425
425
  * export search header
426
426
  */
427
427
  const setSearchHeader = (params: SearchHeaderProps) => {
428
- const searchWidth = widthDevice - 24;
428
+ let searchWidth = layout.width - 24;
429
+ let searchLeft = Spacing.M;
430
+ if (layout.sideBar) {
431
+ // back floats in the side bar: the search spans the content width
432
+ searchWidth = layout.contentWidth - Spacing.M * 2;
433
+ searchLeft = Spacing.M - getHeaderMargin(layout.width);
434
+ }
429
435
  const options: StackNavigationOptions = {
430
436
  headerRight: undefined,
431
437
  headerTitleContainerStyle: {
@@ -437,10 +443,10 @@ const Screen = forwardRef(
437
443
  marginHorizontal: 0,
438
444
  marginVertical: 0,
439
445
  margin: 0,
440
- left: Spacing.M,
446
+ left: searchLeft,
441
447
  },
442
448
  headerLeft: (props: any) =>
443
- params?.hiddenBack ? null : <HeaderLeft {...props} />,
449
+ params?.hiddenBack ? null : <HeaderLeft {...props} floating />,
444
450
  headerTitle: () => (
445
451
  <SearchHeader {...params} animatedValue={sharedValue} />
446
452
  ),
@@ -591,6 +597,8 @@ const Screen = forwardRef(
591
597
  key={`ScreenItem${index}`}
592
598
  style={{
593
599
  marginTop: space,
600
+ marginLeft: layout.insetLeft,
601
+ marginRight: layout.insetRight,
594
602
  flex: item.props?.expanded ? 1 : undefined,
595
603
  }}
596
604
  onLayout={item.props?.onLayout}
@@ -611,6 +619,8 @@ const Screen = forwardRef(
611
619
  key={`ScreenItem`}
612
620
  style={{
613
621
  marginTop: space,
622
+ marginLeft: layout.insetLeft,
623
+ marginRight: layout.insetRight,
614
624
  flex: item?.props?.expanded ? 1 : undefined,
615
625
  }}
616
626
  onLayout={item?.props?.onLayout}
@@ -637,6 +647,15 @@ const Screen = forwardRef(
637
647
  return newHeight;
638
648
  };
639
649
 
650
+ // without the grid, the content container keeps clear of the horizontal insets.
651
+ // Only set when there are insets, so a caller's paddingHorizontal is never overridden.
652
+ const hasContentInset = layout.insetLeft > 0 || layout.insetRight > 0;
653
+ const contentInsetStyle = !useGridLayout &&
654
+ hasContentInset && {
655
+ paddingLeft: layout.insetLeft,
656
+ paddingRight: layout.insetRight,
657
+ };
658
+
640
659
  return (
641
660
  <View
642
661
  style={[
@@ -680,9 +699,10 @@ const Screen = forwardRef(
680
699
  onScroll={handleScroll}
681
700
  onScrollEndDrag={handleScrollEnd}
682
701
  scrollEventThrottle={16}
683
- style={[Styles.flex]}
702
+ style={[Styles.flex, !scrollable && contentInsetStyle]}
684
703
  contentContainerStyle={[
685
704
  scrollable && !Footer && !isTab && { paddingBottom: bottomInset },
705
+ scrollable && contentInsetStyle,
686
706
  scrollViewProps?.contentContainerStyle,
687
707
  ]}
688
708
  >
@@ -692,7 +712,12 @@ const Screen = forwardRef(
692
712
  </Component>
693
713
 
694
714
  {floatingButtonProps && (
695
- <View>
715
+ <View
716
+ style={{
717
+ marginLeft: layout.insetLeft,
718
+ marginRight: layout.insetRight,
719
+ }}
720
+ >
696
721
  <FloatingButton
697
722
  {...floatingButtonProps}
698
723
  animatedValue={sharedValue}
@@ -707,6 +732,8 @@ const Screen = forwardRef(
707
732
  styles.shadow,
708
733
  {
709
734
  paddingBottom: bottomInset + Spacing.S,
735
+ paddingLeft: layout.insetLeft,
736
+ paddingRight: layout.insetRight,
710
737
  backgroundColor: theme.colors.background.surface,
711
738
  },
712
739
  ]}
@@ -1,9 +1,8 @@
1
- import React, { useContext } from 'react';
2
- import { Dimensions, View, ViewProps } from 'react-native';
3
- import { useGridSystem } from './utils';
1
+ import React from 'react';
2
+ import { View, ViewProps } from 'react-native';
3
+ import { useGridSystem, useScreenLayout } from './utils';
4
4
  import { GridContextProps } from './types';
5
5
  import { GridContext } from './index';
6
- import { ApplicationContext, MiniAppContext } from '../Context';
7
6
  import styles from './styles';
8
7
  import { Image } from '../Image';
9
8
  import { Spacing } from '../Consts';
@@ -34,18 +33,15 @@ const Section: React.FC<SectionProps> = ({
34
33
  style,
35
34
  ...props
36
35
  }) => {
37
- const { showGrid } = useContext(ApplicationContext);
38
36
  const { numberOfColumns } = useGridSystem();
37
+ const { contentWidth } = useScreenLayout();
39
38
 
40
39
  const gutterSize = 12;
41
40
  let margin = 0;
42
41
  if (useMargin) {
43
42
  margin = 12;
44
43
  }
45
- let widthSection = Dimensions.get('window').width;
46
- if (useMargin) {
47
- widthSection = widthSection - margin * 2;
48
- }
44
+ const widthSection = contentWidth - margin * 2;
49
45
 
50
46
  const sizePerSpan =
51
47
  (widthSection - gutterSize * (numberOfColumns - 1)) / numberOfColumns -
@@ -60,13 +56,6 @@ const Section: React.FC<SectionProps> = ({
60
56
  },
61
57
  };
62
58
 
63
- /**
64
- * render overlay only dev mode
65
- */
66
- const renderOverlay = () => {
67
- return <View pointerEvents={'none'} style={styles.boxGridSection} />;
68
- };
69
-
70
59
  return (
71
60
  <GridContext.Provider value={gridContext}>
72
61
  <View
@@ -90,9 +79,7 @@ const Section: React.FC<SectionProps> = ({
90
79
  style={styles.imageBackground}
91
80
  />
92
81
  )}
93
- {/* Render only allowed children as valid React elements */}
94
82
  {children}
95
- {showGrid && renderOverlay()}
96
83
  </View>
97
84
  </GridContext.Provider>
98
85
  );
package/Layout/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import Card from './Card';
2
2
  import Section from './Section';
3
- import GridSystem from './GridSystem';
4
- import { validateChildren } from './utils';
3
+ import { useScreenLayout, validateChildren } from './utils';
4
+ import type { ScreenLayout, SideBarEdge, SideBarLayout } from './utils';
5
5
  import { createContext } from 'react';
6
6
  import { GridContextProps } from './types';
7
7
  import Item from './Item';
@@ -18,14 +18,14 @@ const GridContext = createContext<GridContextProps>({
18
18
  getSizeSpan: () => 0,
19
19
  });
20
20
 
21
- export type { ScreenProps };
21
+ export type { ScreenProps, ScreenLayout, SideBarEdge, SideBarLayout };
22
22
 
23
23
  export {
24
24
  GridContext,
25
25
  Card,
26
26
  Section,
27
- GridSystem,
28
27
  validateChildren,
28
+ useScreenLayout,
29
29
  Item,
30
30
  ItemList,
31
31
  ItemSectionList,