@momo-kits/foundation 0.169.7-beta.8 → 0.169.7-beta.9

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 (36) hide show
  1. package/Application/BottomTab/ActiveIndicator.tsx +1 -5
  2. package/Application/BottomTab/BottomTabBar.styles.ts +1 -18
  3. package/Application/BottomTab/BottomTabBar.tsx +10 -8
  4. package/Application/BottomTab/CurvedContainer.tsx +2 -8
  5. package/Application/BottomTab/CustomBottomTabItem.tsx +2 -2
  6. package/Application/BottomTab/DuoTabBar.tsx +3 -15
  7. package/Application/BottomTab/metrics.ts +3 -23
  8. package/Application/Components/HeaderAnimated.tsx +13 -37
  9. package/Application/Components/HeaderBackground.tsx +3 -16
  10. package/Application/Components/HeaderExtendHeader.tsx +28 -41
  11. package/Application/Components/HeaderLeft.tsx +18 -4
  12. package/Application/Components/HeaderRight.styles.ts +13 -15
  13. package/Application/Components/HeaderTitle.shared.ts +11 -10
  14. package/Application/Components/HeaderToolkitAction.tsx +37 -12
  15. package/Application/Components/NavigationButton.tsx +6 -9
  16. package/Application/Components/SearchHeader.tsx +7 -20
  17. package/Application/StackScreen.tsx +0 -9
  18. package/Application/index.ts +1 -11
  19. package/Application/navigationOptions.tsx +15 -6
  20. package/Application/types.header.ts +2 -7
  21. package/Application/types.tabs.ts +1 -0
  22. package/Application/types.ts +0 -7
  23. package/Input/InputSearch.tsx +2 -18
  24. package/Input/index.tsx +1 -7
  25. package/Layout/Card.tsx +10 -10
  26. package/Layout/Item.tsx +2 -2
  27. package/Layout/Screen.tsx +0 -3
  28. package/Layout/Section.tsx +8 -9
  29. package/Layout/constants.ts +19 -0
  30. package/Layout/screenHeader.tsx +52 -55
  31. package/Layout/screenTypes.ts +2 -10
  32. package/Layout/types.ts +37 -1
  33. package/Layout/useGridSystem.ts +49 -0
  34. package/Layout/utils.ts +0 -8
  35. package/package.json +1 -1
  36. package/Application/headerLayout.ts +0 -158
@@ -3,9 +3,6 @@ import { MiniAppContext } from '../../Context';
3
3
  import { Spacing } from '../../Consts';
4
4
  import { isWhiteListDesignSystem } from '../utils';
5
5
  import { useScreenLayout } from '../../Layout';
6
- import { HeaderBarMetrics } from '../headerLayout';
7
-
8
- const { sidePadding, buttonSize, titleGap, clusterWidth } = HeaderBarMetrics;
9
6
 
10
7
  /**
11
8
  * Header title font: MoMoTrustDisplay for design-system whitelisted mini apps,
@@ -17,28 +14,32 @@ const useHeaderFontFamily = (): string => {
17
14
  };
18
15
 
19
16
  /**
20
- * side paddings, back button, title gaps and right cluster sharing the
21
- * navigation bar with the title
17
+ * back button and toolkit sharing the navigation bar with the title
18
+ */
19
+ const HEADER_ACTIONS_WIDTH = 172;
20
+
21
+ /**
22
+ * extra width the 48pt back and toolkit take on the iPhone Duo status bar row
22
23
  */
23
- const HEADER_ACTIONS_WIDTH =
24
- sidePadding * 2 + buttonSize + titleGap * 2 + clusterWidth;
24
+ const STATUS_BAR_ROW_ACTIONS_EXTRA = 55;
25
25
 
26
26
  /**
27
27
  * Max header title width. The iPhone Duo side bar takes back and toolkit out of
28
- * the bar, so the title gets the content width; otherwise it shares the bar with
29
- * them, minus the status bar clusters on the iPhone Duo inner portrait row.
28
+ * the bar, so the title gets the content width; otherwise it shares the bar with them.
30
29
  */
31
30
  const useTitleMaxWidth = () => {
32
31
  const layout = useScreenLayout();
33
32
  const { width, contentWidth, sideBar, statusBarClearance } = layout;
34
33
  let clearance = 0;
34
+ let rowActionsExtra = 0;
35
35
  if (statusBarClearance) {
36
36
  clearance = statusBarClearance.left + statusBarClearance.right;
37
+ rowActionsExtra = STATUS_BAR_ROW_ACTIONS_EXTRA;
37
38
  }
38
39
  if (sideBar) {
39
40
  return contentWidth - Spacing.M * 2 - clearance;
40
41
  }
41
- return width - HEADER_ACTIONS_WIDTH - clearance;
42
+ return width - HEADER_ACTIONS_WIDTH - rowActionsExtra - clearance;
42
43
  };
43
44
 
44
45
  export { useHeaderFontFamily, HEADER_ACTIONS_WIDTH, useTitleMaxWidth };
@@ -4,12 +4,11 @@ import { NavigationButton } from './NavigationButton';
4
4
  import { MiniAppContext } from '../../Context';
5
5
  import { Colors, Spacing, Styles } from '../../Consts';
6
6
  import { Icon } from '../../Icon';
7
- import { DuoMetrics } from '../../Layout/utils';
7
+ import { DuoMetrics, useScreenLayout } from '../../Layout/utils';
8
8
  import { SideBarButton, SideBarGroup, SideBarGroupItem } from './SideBarButton';
9
9
  import { useDuoBarCompression } from '../BottomTab/DuoBarCompression';
10
10
  import { styles } from './HeaderRight.styles';
11
11
  import { useToolkitActions } from './useToolkitActions';
12
- import { HeaderBarMetrics } from '../headerLayout';
13
12
 
14
13
  const CLOSE_ICON = '16_navigation_close_circle';
15
14
  const HOME_ICON = '16_basic_home';
@@ -32,6 +31,7 @@ const HeaderToolkitAction: React.FC<any> = ({
32
31
  const compression = useDuoBarCompression();
33
32
  const { toolbarCompressed, toolbarHidden } = compression;
34
33
  const { expandToolbar, setToolbarHeight } = compression;
34
+ const { statusBarClearance } = useScreenLayout();
35
35
  const {
36
36
  isLoading,
37
37
  iconShortcut,
@@ -131,6 +131,39 @@ const HeaderToolkitAction: React.FC<any> = ({
131
131
  );
132
132
  }
133
133
 
134
+ // on the status bar row the controls keep the side bar size
135
+ if (statusBarClearance) {
136
+ return (
137
+ <View style={styles.sideBarRow}>
138
+ {useShortcut && (
139
+ <SideBarButton
140
+ disabled={isLoading}
141
+ icon={iconShortcut}
142
+ onPress={shortcutOnPress}
143
+ tintColor={tintColor}
144
+ showBadge={showBadge}
145
+ />
146
+ )}
147
+ <SideBarGroup tintColor={tintColor} horizontal>
148
+ {useHelpCenter && (
149
+ <SideBarGroupItem
150
+ accessibilityLabel={'btn_navigation_help_center'}
151
+ icon={'help_center'}
152
+ tintColor={tintColor}
153
+ onPress={onPressHelpCenter}
154
+ />
155
+ )}
156
+ <SideBarGroupItem
157
+ accessibilityLabel={'btn_navigation_close'}
158
+ icon={closeIcon}
159
+ tintColor={tintColor}
160
+ onPress={onClose}
161
+ />
162
+ </SideBarGroup>
163
+ </View>
164
+ );
165
+ }
166
+
134
167
  return (
135
168
  <View style={Styles.row}>
136
169
  {useShortcut && (
@@ -151,11 +184,7 @@ const HeaderToolkitAction: React.FC<any> = ({
151
184
  onPress={onPressHelpCenter}
152
185
  hitSlop={{ top: 7, bottom: 7, left: 7, right: 0 }}
153
186
  >
154
- <Icon
155
- color={tintColor}
156
- source={'help_center'}
157
- size={HeaderBarMetrics.iconSize}
158
- />
187
+ <Icon color={tintColor} source={'help_center'} size={20} />
159
188
  </TouchableOpacity>
160
189
  <View style={[styles.divider, { backgroundColor: tintColor }]} />
161
190
  </>
@@ -166,11 +195,7 @@ const HeaderToolkitAction: React.FC<any> = ({
166
195
  style={styles.toolkitButton}
167
196
  hitSlop={{ top: 7, bottom: 7, left: 0, right: 7 }}
168
197
  >
169
- <Icon
170
- color={tintColor}
171
- source={closeIcon}
172
- size={HeaderBarMetrics.iconSize}
173
- />
198
+ <Icon color={tintColor} source={closeIcon} size={20} />
174
199
  </TouchableOpacity>
175
200
  </View>
176
201
  </View>
@@ -5,12 +5,9 @@ import { StyleSheet, TouchableOpacity, View, ViewStyle } from 'react-native';
5
5
  import { Colors, Spacing } from '../../Consts';
6
6
  import { Icon } from '../../Icon';
7
7
  import { BadgeDot } from '../../Badge';
8
- import { HeaderBarMetrics } from '../headerLayout';
9
-
10
- const { buttonSize, iconSize } = HeaderBarMetrics;
11
8
 
12
9
  /**
13
- * Round 32pt icon button of the header (back, shortcut) with an optional badge
10
+ * Round 28pt icon button of the header (back, shortcut) with an optional badge
14
11
  * dot; switches to a dark fill under a white tint so the icon stays readable.
15
12
  */
16
13
  const NavigationButton: React.FC<NavigationButtonProps> = ({
@@ -38,7 +35,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
38
35
  <Icon
39
36
  source={icon}
40
37
  color={tintColor ?? theme.colors.text.default}
41
- size={iconSize}
38
+ size={20}
42
39
  />
43
40
  </TouchableOpacity>
44
41
  {showBadge && <BadgeDot size={'small'} style={styles.badgeDot} />}
@@ -48,12 +45,12 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
48
45
 
49
46
  const styles = StyleSheet.create({
50
47
  container: {
51
- width: buttonSize,
48
+ width: 28,
52
49
  },
53
50
  navigationButton: {
54
- height: buttonSize,
55
- width: buttonSize,
56
- borderRadius: buttonSize / 2,
51
+ height: 28,
52
+ width: 28,
53
+ borderRadius: 14,
57
54
  justifyContent: 'center',
58
55
  alignItems: 'center',
59
56
  backgroundColor: Colors.black_01 + '99',
@@ -1,5 +1,5 @@
1
1
  import { Colors, Radius, Spacing, Styles } from '../../Consts';
2
- import { InputRef, InputSearch, type InputSearchProps } from '../../Input';
2
+ import { InputRef, InputSearch } from '../../Input';
3
3
  import { StyleSheet, TouchableOpacity, View } from 'react-native';
4
4
  import Animated, { useAnimatedStyle } from 'react-native-reanimated';
5
5
  import React, { useContext } from 'react';
@@ -8,13 +8,7 @@ import { ApplicationContext, MiniAppContext } from '../../Context';
8
8
  import { Text } from '../../Text';
9
9
  import { useNormalizedSharedValue } from '../hooks';
10
10
  import { useScreenLayout } from '../../Layout';
11
- import { HeaderBarMetrics } from '../headerLayout';
12
-
13
- const { buttonSize, pillWidth, sidePadding, titleGap } = HeaderBarMetrics;
14
- // help center | home pill and the bar padding right of it
15
- const TOOLKIT_WIDTH = pillWidth + sidePadding;
16
- // the iPhone Duo side bar keeps its right header width
17
- const DUO_TOOLKIT_WIDTH = 73;
11
+ import { DuoMetrics } from '../../Layout/utils';
18
12
 
19
13
  /**
20
14
  * Header search bar whose fill turns from surface to default once scrolled, with
@@ -34,21 +28,15 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
34
28
  const { theme, navigator } = useContext(ApplicationContext);
35
29
  const context = useContext<any>(MiniAppContext);
36
30
  const layout = useScreenLayout();
37
- let defaultRightWidth = TOOLKIT_WIDTH;
38
- let searchSize: InputSearchProps['size'] = 'header';
39
- if (layout.sideBar) {
40
- defaultRightWidth = DUO_TOOLKIT_WIDTH;
41
- searchSize = 'default';
42
- }
31
+ // the iPhone Duo status bar row keeps a side bar sized back button
32
+ const BACK_WIDTH = layout.statusBarClearance ? DuoMetrics.controlSize : 28;
43
33
 
44
34
  const sharedValue = useNormalizedSharedValue(animatedValue);
45
- const defaultLeft = buttonSize + sidePadding + titleGap;
46
- const leftPosition = props?.leftPosition ?? defaultLeft;
47
- const headerRightWidth = props?.headerRightWidth ?? defaultRightWidth;
35
+ const leftPosition = props?.leftPosition ?? BACK_WIDTH + 20;
36
+ const headerRightWidth = props?.headerRightWidth ?? 73;
48
37
 
49
38
  // iPhone Duo side bar holds back: the search shares the content width with the buttons only
50
- const rowWidth = layout.width - leftPosition - sidePadding;
51
- let searchMaxWidth = rowWidth - headerRightWidth;
39
+ let searchMaxWidth = layout.width - leftPosition - 12 - headerRightWidth;
52
40
  if (layout.sideBar) {
53
41
  searchMaxWidth = layout.contentWidth - Spacing.M * 2 - headerRightWidth;
54
42
  }
@@ -117,7 +105,6 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
117
105
  <InputSearch
118
106
  ref={ref}
119
107
  {...props}
120
- size={searchSize}
121
108
  backgroundColor={'transparent'}
122
109
  showButtonText={false}
123
110
  />
@@ -8,7 +8,6 @@ import { SwipeBackHaptic } from './Components/SwipeBackHaptic';
8
8
  import { useAppState } from './hooks';
9
9
  import { createScreenTracking } from './StackScreen.tracking';
10
10
  import { TooltipPortalHost, TooltipPortalProvider } from './TooltipPortal';
11
- import { useHeaderFrameOptions } from './headerLayout';
12
11
 
13
12
  const runAfterInteractions = InteractionManager.runAfterInteractions;
14
13
 
@@ -52,7 +51,6 @@ const StackScreen: React.FC<any> = props => {
52
51
  const navigation = useRef(new Navigation(props.navigation, context)).current;
53
52
  const heightHeader = useHeaderHeight();
54
53
  const { isBackgroundToForeground } = useAppState();
55
- const headerFrameOptions = useHeaderFrameOptions(options?.contentLayout);
56
54
 
57
55
  const data = {
58
56
  ...initialParams,
@@ -71,13 +69,6 @@ const StackScreen: React.FC<any> = props => {
71
69
  }
72
70
  }, [navigation, options]);
73
71
 
74
- // re-applied on fold, unfold and rotation, apart from the other options
75
- useLayoutEffect(() => {
76
- if (headerFrameOptions) {
77
- navigation.instance.setOptions(headerFrameOptions);
78
- }
79
- }, [navigation, headerFrameOptions]);
80
-
81
72
  useEffect(() => {
82
73
  let focusScreen: any;
83
74
  let onFocusApp: any;
@@ -26,13 +26,6 @@ import {
26
26
  type ModalLayout,
27
27
  type ModalRect,
28
28
  } from './modalLayout';
29
- import {
30
- HeaderBarMetrics,
31
- getHeaderLayout,
32
- useHeaderLayout,
33
- type HeaderContentLayout,
34
- type HeaderLayout,
35
- } from './headerLayout';
36
29
 
37
30
  export {
38
31
  NavigationContainer,
@@ -48,9 +41,6 @@ export {
48
41
  useTooltipPortal,
49
42
  getModalLayout,
50
43
  useModalLayout,
51
- HeaderBarMetrics,
52
- getHeaderLayout,
53
- useHeaderLayout,
54
44
  };
55
45
 
56
- export type { ModalLayout, ModalRect, HeaderContentLayout, HeaderLayout };
46
+ export type { ModalLayout, ModalRect };
@@ -8,12 +8,11 @@ import {
8
8
  TransitionPresets,
9
9
  } from '@react-navigation/stack';
10
10
  import type { SharedValue } from 'react-native-reanimated';
11
- import { Colors } from '../Consts';
11
+ import { Colors, Spacing } from '../Consts';
12
12
  import { HeaderBackground } from './Components/HeaderBackground';
13
13
  import { HeaderLeft } from './Components/HeaderLeft';
14
14
  import { HeaderRight } from './Components/HeaderRight';
15
15
  import { HeaderTitle, TitleCustom } from './Components/HeaderTitle';
16
- import { HeaderBarMetrics, TITLE_CONTAINER_RESET } from './headerLayout';
17
16
  import type { HeaderTitleProps, NavigationOptions } from './types';
18
17
 
19
18
  const CARD_SHADOW_OPACITY = 0.3;
@@ -56,8 +55,13 @@ const getStackOptions = (): StackNavigationOptions => {
56
55
  headerTitleAlign: 'left',
57
56
  headerTitle: props => <HeaderTitle {...props} />,
58
57
  headerTitleContainerStyle: {
59
- ...TITLE_CONTAINER_RESET,
60
- left: HeaderBarMetrics.titleGap,
58
+ marginLeft: 0,
59
+ marginEnd: 0,
60
+ marginStart: 0,
61
+ marginHorizontal: 0,
62
+ marginVertical: 0,
63
+ margin: 0,
64
+ left: Spacing.S,
61
65
  },
62
66
  headerBackground: (props: any) => <HeaderBackground {...props} />,
63
67
  headerLeft: (props: any) => <HeaderLeft {...props} floating />,
@@ -168,8 +172,13 @@ const getOptions = (
168
172
  if (params.hiddenBack) {
169
173
  headerLeft = null;
170
174
  options.headerTitleContainerStyle = {
171
- ...TITLE_CONTAINER_RESET,
172
- left: HeaderBarMetrics.sidePadding,
175
+ marginLeft: 0,
176
+ marginEnd: 0,
177
+ marginStart: 0,
178
+ marginHorizontal: 0,
179
+ marginVertical: 0,
180
+ margin: 0,
181
+ left: Spacing.M,
173
182
  };
174
183
  }
175
184
  options = {
@@ -98,11 +98,6 @@ export interface HeaderAnimatedProps extends ViewProps {
98
98
  image: string;
99
99
  useScale?: boolean;
100
100
  aspectRatio?: '16/9' | '3/2' | '1/1';
101
- /**
102
- * Optional. On wide windows the image keeps its phone width, centered; this
103
- * color fills the sides and fades to transparent downward. No fill when unset.
104
- */
105
- bannerBackgroundColor?: string;
106
101
  }
107
102
 
108
103
  export type AnimatedHeader = {
@@ -114,8 +109,8 @@ export type AnimatedHeader = {
114
109
  export interface SearchHeaderProps extends InputSearchProps {
115
110
  ref?: React.RefObject<InputRef>;
116
111
  animatedValue?: Animated.Value | SharedValue<number>;
117
- headerRightWidth?: 0 | 84 | 124 | number;
118
- leftPosition?: 12 | 52 | number;
112
+ headerRightWidth?: 0 | 74 | 110 | number;
113
+ leftPosition?: 12 | 48 | number;
119
114
  renderButtons?: () => ReactNode;
120
115
  hiddenBack?: boolean;
121
116
  }
@@ -36,6 +36,7 @@ export type BottomTabProps = {
36
36
  };
37
37
 
38
38
  export type FloatingButtonProps = {
39
+ container?: React.ReactNode;
39
40
  icon: string | React.ReactNode;
40
41
  label: string;
41
42
  onPress: () => void;
@@ -9,7 +9,6 @@ import type {
9
9
  OnBoarding,
10
10
  } from './types.header';
11
11
  import type { LocalizeProps, Theme } from './types.theme';
12
- import type { HeaderContentLayout } from './headerLayout';
13
12
 
14
13
  export * from './types.theme';
15
14
  export * from './types.header';
@@ -129,10 +128,4 @@ export interface NavigationOptions
129
128
  hiddenBack?: boolean;
130
129
  headerTitle?: HeaderTitleProps | string;
131
130
  headerRight?: OnBoarding | HeaderRightToolkit | any;
132
- /**
133
- * Optional. `stretch` centers back, title and the right cluster in a 600pt
134
- * frame on wide windows (foldable inner display, tablet); the background stays
135
- * full width. Defaults to `grid`, the header row at the window edges.
136
- */
137
- contentLayout?: HeaderContentLayout;
138
131
  }
@@ -13,7 +13,6 @@ import {
13
13
  View,
14
14
  } from 'react-native';
15
15
  import { useComponentId } from '../Application';
16
- import { HeaderBarMetrics } from '../Application/headerLayout';
17
16
  import {
18
17
  ApplicationContext,
19
18
  ComponentContext,
@@ -27,8 +26,6 @@ import styles from './styles';
27
26
  import { Styles } from '../Consts';
28
27
  import SystemTextInput from './SystemTextInput';
29
28
 
30
- const SEARCH_ICON_SIZE = 24;
31
-
32
29
  /**
33
30
  * Search field with search icon, clear icon, optional trailing icon and a
34
31
  * cancel button; with `typingData` it shows an animated placeholder instead.
@@ -52,7 +49,6 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
52
49
  backgroundColor,
53
50
  onPress,
54
51
  typingData,
55
- size = 'default',
56
52
  ...props
57
53
  },
58
54
  ref,
@@ -63,13 +59,6 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
63
59
  const searchFontFamily = exportFontFamily('regular');
64
60
 
65
61
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
66
- const isHeaderSize = size === 'header';
67
- const inputHeightStyle = isHeaderSize && {
68
- height: HeaderBarMetrics.searchHeight,
69
- };
70
- const searchIconSize = isHeaderSize
71
- ? HeaderBarMetrics.iconSize
72
- : SEARCH_ICON_SIZE;
73
62
 
74
63
  const [focused, setFocused] = useState(false);
75
64
  const [internalText, setInternalText] = useState(defaultValue || '');
@@ -125,11 +114,7 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
125
114
  if (typingData && typingData?.length > 0) {
126
115
  return (
127
116
  <TouchableOpacity
128
- style={[
129
- styles.searchInput,
130
- styles.searchInputTyping,
131
- inputHeightStyle,
132
- ]}
117
+ style={[styles.searchInput, styles.searchInputTyping]}
133
118
  onPress={onPress}
134
119
  activeOpacity={onPress ? 0.6 : 1}
135
120
  >
@@ -147,7 +132,6 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
147
132
  ref={inputRef}
148
133
  style={[
149
134
  styles.searchInput,
150
- inputHeightStyle,
151
135
  {
152
136
  fontSize: scaledFontSize,
153
137
  color: theme.colors.text.default,
@@ -241,7 +225,7 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
241
225
  >
242
226
  <Icon
243
227
  source={'navigation_search'}
244
- size={searchIconSize}
228
+ size={24}
245
229
  color={theme.colors.text.hint}
246
230
  />
247
231
  {renderInputView()}
package/Input/index.tsx CHANGED
@@ -194,12 +194,6 @@ export interface InputSearchProps extends TextInputProps {
194
194
  */
195
195
  typingData?: string[];
196
196
 
197
- /**
198
- * Optional. `header` is the 32pt field with a 20pt search icon that sits in the
199
- * navigation header. Defaults to `default`, the 36pt field for content.
200
- */
201
- size?: 'default' | 'header';
202
-
203
197
  /**
204
198
  * Optional. Called when the field is pressed while showing `typingData`.
205
199
  */
@@ -373,4 +367,4 @@ export {
373
367
  InputPhoneNumber,
374
368
  };
375
369
 
376
- export { checkValidPhoneNumber };
370
+ export {checkValidPhoneNumber};
package/Layout/Card.tsx CHANGED
@@ -1,12 +1,13 @@
1
1
  import React, { useContext } from 'react';
2
2
  import { View, ViewProps } from 'react-native';
3
- import { useGridSystem, useScreenLayout } from './utils';
3
+ import { GRID_GUTTER, GRID_MARGIN } from './constants';
4
+ import { useGridSystem } from './useGridSystem';
4
5
  import { GridContextProps } from './types';
5
6
  import { GridContext } from './index';
6
7
  import { Image } from '../Image';
7
8
  import { ApplicationContext } from '../Context';
8
9
  import styles from './styles';
9
- import { Radius, Shadow, Spacing } from '../Consts';
10
+ import { Radius, Shadow } from '../Consts';
10
11
 
11
12
  export interface CardProps extends ViewProps {
12
13
  /**
@@ -21,7 +22,7 @@ export interface CardProps extends ViewProps {
21
22
  }
22
23
 
23
24
  /**
24
- * Surface card across the content width minus 12pt margins, with its own grid for child
25
+ * Surface card across the grid width minus 12pt margins, with its own grid for child
25
26
  * Items; optional background image and light shadow.
26
27
  */
27
28
  const Card: React.FC<CardProps> = ({
@@ -32,19 +33,18 @@ const Card: React.FC<CardProps> = ({
32
33
  ...props
33
34
  }) => {
34
35
  const { theme } = useContext(ApplicationContext);
35
- const { numberOfColumns } = useGridSystem();
36
- const { contentWidth } = useScreenLayout();
36
+ const { numberOfColumns, gridWidth, gridOffset } = useGridSystem();
37
37
 
38
- const gutterSize = 8;
39
- const margin = 12;
40
- const widthSection = contentWidth - margin * 2;
38
+ const gutterSize = GRID_GUTTER;
39
+ const margin = GRID_MARGIN;
40
+ const widthSection = gridWidth - margin * 2;
41
41
  const innerWidth = widthSection - margin * 2;
42
42
  const columnsWidth = innerWidth - gutterSize * (numberOfColumns - 1);
43
43
  const sizePerSpan = columnsWidth / numberOfColumns - 1 / numberOfColumns;
44
44
 
45
45
  const gridContext: GridContextProps = {
46
46
  numberOfColumns,
47
- gutterSize: Spacing.S,
47
+ gutterSize: GRID_GUTTER,
48
48
  sizePerSpan,
49
49
  getSizeSpan: span => {
50
50
  return sizePerSpan * span + gutterSize * (span - 1);
@@ -63,7 +63,7 @@ const Card: React.FC<CardProps> = ({
63
63
  styles.card,
64
64
  {
65
65
  width: widthSection,
66
- marginHorizontal: margin,
66
+ marginHorizontal: gridOffset + margin,
67
67
  gap: gutterSize,
68
68
  },
69
69
  !!backgroundImage && { backgroundColor: undefined },
package/Layout/Item.tsx CHANGED
@@ -7,12 +7,12 @@ import { SpanNumber } from './types';
7
7
 
8
8
  export interface ItemProps extends ViewProps {
9
9
  /**
10
- * Width in grid columns (1-12). Defaults to the full row.
10
+ * Width in grid columns (1-36, out of the grid's 12, 24 or 36). Defaults to the full row.
11
11
  */
12
12
  widthSpan?: SpanNumber;
13
13
 
14
14
  /**
15
- * Optional. Height in grid spans (1-12). Unset keeps the content height.
15
+ * Optional. Height in grid spans (1-36, out of the grid's 12, 24 or 36). Unset keeps the content height.
16
16
  */
17
17
  heightSpan?: SpanNumber;
18
18
  }
package/Layout/Screen.tsx CHANGED
@@ -67,7 +67,6 @@ const Screen = forwardRef(
67
67
  headerBackground,
68
68
  gradientColor,
69
69
  trackingParams,
70
- contentLayout,
71
70
  }: ScreenProps,
72
71
  ref: any,
73
72
  ) => {
@@ -145,7 +144,6 @@ const Screen = forwardRef(
145
144
  gradientColor,
146
145
  headerBackground,
147
146
  layoutOffset,
148
- contentLayout,
149
147
  });
150
148
 
151
149
  // mutates the content node so callers keep its methods plus the header setters
@@ -225,7 +223,6 @@ const Screen = forwardRef(
225
223
  useShadowHeader={useShadowHeader}
226
224
  gradientColor={gradientColor}
227
225
  headerBackground={headerBackground}
228
- contentLayout={contentLayout}
229
226
  />
230
227
  );
231
228
  };
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import { View, ViewProps } from 'react-native';
3
- import { useGridSystem, useScreenLayout } from './utils';
3
+ import { GRID_GUTTER, GRID_MARGIN } from './constants';
4
+ import { useGridSystem } from './useGridSystem';
4
5
  import { GridContextProps } from './types';
5
6
  import { GridContext } from './index';
6
7
  import styles from './styles';
7
8
  import { Image } from '../Image';
8
- import { Spacing } from '../Consts';
9
9
 
10
10
  export interface SectionProps extends ViewProps {
11
11
  /**
@@ -37,22 +37,21 @@ const Section: React.FC<SectionProps> = ({
37
37
  style,
38
38
  ...props
39
39
  }) => {
40
- const { numberOfColumns } = useGridSystem();
41
- const { contentWidth } = useScreenLayout();
40
+ const { numberOfColumns, gridWidth, gridOffset } = useGridSystem();
42
41
 
43
- const gutterSize = 12;
42
+ const gutterSize = GRID_GUTTER;
44
43
  let margin = 0;
45
44
  if (useMargin) {
46
- margin = 12;
45
+ margin = GRID_MARGIN;
47
46
  }
48
- const widthSection = contentWidth - margin * 2;
47
+ const widthSection = gridWidth - margin * 2;
49
48
 
50
49
  const columnsWidth = widthSection - gutterSize * (numberOfColumns - 1);
51
50
  const sizePerSpan = columnsWidth / numberOfColumns - 1 / numberOfColumns;
52
51
 
53
52
  const gridContext: GridContextProps = {
54
53
  numberOfColumns,
55
- gutterSize: Spacing.M,
54
+ gutterSize: GRID_GUTTER,
56
55
  sizePerSpan,
57
56
  getSizeSpan: span => {
58
57
  return span * sizePerSpan + gutterSize * (span - 1);
@@ -70,7 +69,7 @@ const Section: React.FC<SectionProps> = ({
70
69
  styles.rowWrap,
71
70
  {
72
71
  width: widthSection,
73
- marginHorizontal: margin,
72
+ marginHorizontal: gridOffset + margin,
74
73
  gap: gutterSize,
75
74
  },
76
75
  ]}
@@ -0,0 +1,19 @@
1
+ const GRID_MARGIN = 12;
2
+ const GRID_GUTTER = 12;
3
+ const GRID_PHONE_MAX_WIDTH = 600;
4
+ const GRID_TABLET_MIN_WIDTH = 800;
5
+ const GRID_DESKTOP_MIN_WIDTH = 1100;
6
+ const GRID_PHONE_COLUMNS = 12;
7
+ const GRID_TABLET_COLUMNS = 24;
8
+ const GRID_DESKTOP_COLUMNS = 36;
9
+
10
+ export {
11
+ GRID_DESKTOP_COLUMNS,
12
+ GRID_DESKTOP_MIN_WIDTH,
13
+ GRID_GUTTER,
14
+ GRID_MARGIN,
15
+ GRID_PHONE_COLUMNS,
16
+ GRID_PHONE_MAX_WIDTH,
17
+ GRID_TABLET_COLUMNS,
18
+ GRID_TABLET_MIN_WIDTH,
19
+ };