@momo-kits/foundation 1.0.13 → 1.0.14

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/Button/index.tsx CHANGED
@@ -10,7 +10,6 @@ import {Text} from '../Text';
10
10
  import {Typography} from '../Text/types';
11
11
  import {Colors} from '../Consts';
12
12
  import styles from './styles';
13
- import {Image} from '../Image';
14
13
  import {Icon} from '../Icon';
15
14
 
16
15
  export interface ButtonProps extends TouchableOpacityProps {
@@ -224,6 +223,7 @@ const Button: FC<ButtonProps> = ({
224
223
  return (
225
224
  <TouchableOpacity
226
225
  {...rest}
226
+ accessibilityLabel={`Button/${title}`}
227
227
  activeOpacity={activeOpacity}
228
228
  onPress={onPressButton}
229
229
  style={buttonStyle}>
@@ -35,6 +35,7 @@ const CheckBox: FC<CheckBoxProps> = props => {
35
35
  };
36
36
  return (
37
37
  <TouchableOpacity
38
+ accessibilityLabel={`CheckBox/${label}`}
38
39
  activeOpacity={0.8}
39
40
  onPress={onChangeValue}
40
41
  disabled={disabled}
@@ -48,7 +49,7 @@ const CheckBox: FC<CheckBoxProps> = props => {
48
49
  />
49
50
  )}
50
51
  </View>
51
- <Text typography={'description_default'}>{label}</Text>
52
+ {!!label && <Text typography={'description_default'}>{label}</Text>}
52
53
  </TouchableOpacity>
53
54
  );
54
55
  };
package/Icon/index.tsx CHANGED
@@ -20,6 +20,7 @@ const Icon: React.FC<IconProps> = ({source, size, color, style = {}}) => {
20
20
 
21
21
  return (
22
22
  <Image
23
+ accessibilityLabel={`Icon/${getIconSource()}`}
23
24
  loading={false}
24
25
  source={getIconSource()}
25
26
  style={[style, {width: size, height: size}]}
@@ -111,6 +111,7 @@ const IconButton: React.FC<IconButtonProps> = ({
111
111
  return (
112
112
  <TouchableOpacity
113
113
  {...rest}
114
+ accessibilityLabel={`IconButton/${icon}`}
114
115
  activeOpacity={activeOpacity}
115
116
  onPress={onPressButton}
116
117
  style={buttonStyle}>
package/Image/index.tsx CHANGED
@@ -11,9 +11,15 @@ import {FastImagePropsWithoutStyle} from './types';
11
11
  export interface ImageProps extends FastImagePropsWithoutStyle {
12
12
  style?: StyleProp<ViewStyle>;
13
13
  loading?: boolean;
14
+ accessibilityLabel?: string;
14
15
  }
15
16
 
16
- const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
17
+ const Image: React.FC<ImageProps> = ({
18
+ style,
19
+ source,
20
+ accessibilityLabel,
21
+ ...rest
22
+ }) => {
17
23
  const {theme} = useContext(ApplicationContext);
18
24
  const [loading, setLoading] = useState(rest.loading);
19
25
  const [fail, setFail] = useState(false);
@@ -48,7 +54,9 @@ const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
48
54
  };
49
55
 
50
56
  return (
51
- <View style={[styles.container, style]}>
57
+ <View
58
+ style={[styles.container, style]}
59
+ accessibilityLabel={`Image/${accessibilityLabel ?? source}`}>
52
60
  <FastImage
53
61
  {...rest}
54
62
  source={source}
@@ -68,4 +76,5 @@ const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
68
76
  Image.defaultProps = {
69
77
  loading: true,
70
78
  };
79
+
71
80
  export {Image};
package/Input/Input.tsx CHANGED
@@ -8,7 +8,6 @@ import {
8
8
  } from 'react-native';
9
9
  import {ApplicationContext} from '../Navigation';
10
10
  import styles from './styles';
11
- import {Image} from '../Image';
12
11
  import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
13
12
  import {InputProps} from './index';
14
13
  import {Icon} from '../Icon';
@@ -112,16 +111,14 @@ const Input: FC<InputProps> = ({
112
111
  />
113
112
  </TouchableOpacity>
114
113
  )}
115
- {icon && (
116
- <Icon icon={iconTintColor} source={icon} style={styles.icon} />
117
- )}
114
+ {icon && <Icon color={iconTintColor} source={icon} size={24} />}
118
115
  </View>
119
116
  </View>
120
117
  );
121
118
  };
122
119
 
123
120
  return (
124
- <View style={styles.wrapper}>
121
+ <View style={styles.wrapper} accessibilityLabel={`Input`}>
125
122
  {renderInputView()}
126
123
  <ErrorView errorMessage={errorMessage} />
127
124
  </View>
@@ -123,7 +123,7 @@ const InputMoney: FC<InputMoneyProps> = ({
123
123
  };
124
124
 
125
125
  return (
126
- <View style={styles.wrapper}>
126
+ <View style={styles.wrapper} accessibilityLabel={`InputMoney`}>
127
127
  {renderInputView()}
128
128
  <ErrorView errorMessage={errorMessage} />
129
129
  </View>
@@ -125,7 +125,9 @@ const InputSearch: FC<InputSearchProps> = ({
125
125
  );
126
126
  };
127
127
  return (
128
- <View style={[style, styles.searchInputContainer]}>
128
+ <View
129
+ style={[style, styles.searchInputContainer]}
130
+ accessibilityLabel={`InputSearch`}>
129
131
  <View
130
132
  style={[
131
133
  getBorderColor(),
@@ -138,7 +138,7 @@ const InputTextArea: FC<InputTextAreaProps> = props => {
138
138
  };
139
139
 
140
140
  return (
141
- <View style={styles.wrapper}>
141
+ <View style={styles.wrapper} accessibilityLabel={`InputTextArea`}>
142
142
  {renderInputView()}
143
143
  <ErrorView errorMessage={errorMessage} />
144
144
  </View>
@@ -0,0 +1,87 @@
1
+ import React, {useContext} from 'react';
2
+ import {View} from 'react-native';
3
+
4
+ import {CardProps, GridContextProps} from './types';
5
+ import {GridContext} from './index';
6
+
7
+ const Card: React.FC<CardProps> = ({
8
+ widthSpan = 12,
9
+ heightSpan,
10
+ usePadding,
11
+ children,
12
+ style,
13
+ }) => {
14
+ const grid = useContext(GridContext);
15
+
16
+ /**
17
+ * render overlay view only dev mode
18
+ */
19
+ const renderOverlay = () => {
20
+ return (
21
+ <View
22
+ pointerEvents={'none'}
23
+ style={{
24
+ position: 'absolute',
25
+ top: 0,
26
+ bottom: 0,
27
+ left: 0,
28
+ right: 0,
29
+ borderColor: 'red',
30
+ borderWidth: 1,
31
+ }}
32
+ />
33
+ );
34
+ };
35
+
36
+ const styles: any = style ?? {};
37
+
38
+ const numberOfColumns = 12;
39
+ const gutterSize = 8;
40
+ let margin = 0;
41
+ if (usePadding) {
42
+ margin = 12;
43
+ }
44
+ const widthSection = grid.getSizeSpan(widthSpan) - margin * 2;
45
+ const totalGutterSize = gutterSize * (numberOfColumns - 1);
46
+ const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
47
+ const gridContext: GridContextProps = {
48
+ numberOfColumns,
49
+ gutterSize,
50
+ margin,
51
+ sizePerSpan,
52
+ getSizeSpan: span => {
53
+ return span * sizePerSpan + (span - 1) * gutterSize;
54
+ },
55
+ };
56
+
57
+ return (
58
+ <View
59
+ accessibilityLabel={`Card`}
60
+ style={{
61
+ ...styles,
62
+ width: grid.getSizeSpan(widthSpan),
63
+ height: heightSpan ? grid.getSizeSpan(heightSpan) : undefined,
64
+ paddingHorizontal: margin,
65
+ overflow: 'hidden',
66
+ margin: undefined,
67
+ marginTop: undefined,
68
+ marginBottom: undefined,
69
+ marginLeft: undefined,
70
+ marginRight: undefined,
71
+ }}>
72
+ <GridContext.Provider value={gridContext}>
73
+ {children}
74
+ </GridContext.Provider>
75
+ {__DEV__ && renderOverlay()}
76
+ </View>
77
+ );
78
+ };
79
+
80
+ Card.defaultProps = {
81
+ widthSpan: 12,
82
+ usePadding: false,
83
+ };
84
+
85
+ Card.displayName = 'Card';
86
+
87
+ export default Card;
@@ -1,13 +1,28 @@
1
1
  import React, {useContext} from 'react';
2
2
  import {useSafeAreaInsets} from 'react-native-safe-area-context';
3
- import {StyleSheet, View} from 'react-native';
3
+ import {Dimensions, StyleSheet, View} from 'react-native';
4
4
  import {ApplicationContext} from '../Navigation';
5
- import {useGridSystem} from './index';
6
5
  import {Colors, Spacing} from '../Consts';
6
+ import {GridContextProps} from './types';
7
7
 
8
8
  const GridSystem: React.FC = () => {
9
9
  const {theme} = useContext(ApplicationContext);
10
- const grid = useGridSystem();
10
+ const numberOfColumns = 12;
11
+ const gutterSize = 12;
12
+ const margin = 12;
13
+ const widthSection = Dimensions.get('window').width - margin * 2;
14
+ const totalGutterSize = gutterSize * (numberOfColumns - 1);
15
+ const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
16
+
17
+ const grid: GridContextProps = {
18
+ numberOfColumns,
19
+ gutterSize,
20
+ margin,
21
+ sizePerSpan,
22
+ getSizeSpan: span => {
23
+ return span * sizePerSpan + (span - 1) * gutterSize;
24
+ },
25
+ };
11
26
  const insets = useSafeAreaInsets();
12
27
 
13
28
  const list = [];
@@ -24,7 +39,7 @@ const GridSystem: React.FC = () => {
24
39
  insets,
25
40
  {
26
41
  borderColor: theme.colors.error.primary,
27
- marginHorizontal: grid.screenPadding,
42
+ marginHorizontal: grid.margin,
28
43
  },
29
44
  ]}>
30
45
  {list.map((i, index) => {
@@ -4,35 +4,57 @@ import {SafeAreaView} from 'react-native-safe-area-context';
4
4
  import React from 'react';
5
5
  import {ScreenContainerProps} from '../Navigation/types';
6
6
  import {Spacing, Styles} from '../Consts';
7
- import {ScreenSection, validateChildren} from './index';
8
- import {Image} from '../Image';
7
+ import {Section, validateChildren} from './index';
9
8
 
10
9
  const ScreenContainer: React.FC<ScreenContainerProps> = ({
11
10
  children,
12
11
  edges,
13
12
  enableKeyboardAvoidingView,
14
13
  scrollable,
14
+ scrollY,
15
+ headerBackground,
15
16
  scrollViewProps,
16
- headerImage,
17
+ footerComponent: Footer,
17
18
  }) => {
19
+ let marginHeader = 0;
20
+ let handleScroll;
21
+ let imageAnimatedStyle = {};
18
22
  let Component: any = View;
19
23
  const headerHeight = useHeaderHeight();
20
24
  if (scrollable) {
21
25
  Component = Animated.ScrollView;
22
26
  }
27
+ if (scrollY) {
28
+ marginHeader = useHeaderHeight();
29
+ imageAnimatedStyle = {
30
+ transform: [
31
+ {
32
+ scale: scrollY.interpolate?.({
33
+ inputRange: [-300, -110, 100],
34
+ outputRange: [1.75, 1, 1],
35
+ extrapolate: 'clamp',
36
+ }),
37
+ },
38
+ ],
39
+ };
40
+ handleScroll = Animated.event(
41
+ [{nativeEvent: {contentOffset: {y: scrollY}}}],
42
+ {useNativeDriver: true},
43
+ );
44
+ }
23
45
 
24
46
  /**
25
47
  * build content for screen
26
48
  */
27
49
  const renderContent = () => {
28
- const results = validateChildren(children, ScreenSection);
50
+ const results = validateChildren(children, Section);
29
51
  if (Array.isArray(results)) {
30
52
  return results.map((item, index) => {
31
53
  return (
32
54
  <View
33
- key={`ScreenSection${index}`}
55
+ key={`Section${index}`}
34
56
  style={{
35
- paddingTop: index != 0 ? 12 : Spacing.S,
57
+ marginTop: item.props?.useMargin ? Spacing.M : 0,
36
58
  flex: item.props?.expanded ? 1 : undefined,
37
59
  }}>
38
60
  {item}
@@ -44,7 +66,28 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
44
66
  };
45
67
 
46
68
  return (
47
- <SafeAreaView style={Styles.flex} edges={edges}>
69
+ <SafeAreaView
70
+ style={Styles.flex}
71
+ edges={edges}
72
+ accessibilityLabel={`ScreenContainer`}>
73
+ <View
74
+ style={{
75
+ position: 'absolute',
76
+ height: 300,
77
+ width: '100%',
78
+ }}>
79
+ {headerBackground && (
80
+ <Animated.Image
81
+ source={{
82
+ uri: headerBackground,
83
+ }}
84
+ style={{
85
+ aspectRatio: 1.3,
86
+ ...imageAnimatedStyle,
87
+ }}
88
+ />
89
+ )}
90
+ </View>
48
91
  <KeyboardAvoidingView
49
92
  style={Styles.flex}
50
93
  keyboardVerticalOffset={headerHeight}
@@ -53,17 +96,13 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
53
96
  ios: 'padding',
54
97
  android: undefined,
55
98
  })}>
56
- <Component {...scrollViewProps} style={Styles.flex}>
57
- {headerImage && (
58
- <Image
59
- source={{
60
- uri: headerImage,
61
- }}
62
- style={{width: '100%', height: 300}}
63
- />
64
- )}
99
+ <Component
100
+ {...scrollViewProps}
101
+ onScroll={handleScroll}
102
+ style={[Styles.flex, {marginTop: marginHeader}]}>
65
103
  {renderContent()}
66
104
  </Component>
105
+ {Footer && <Section>{Footer}</Section>}
67
106
  </KeyboardAvoidingView>
68
107
  </SafeAreaView>
69
108
  );
@@ -1,11 +1,31 @@
1
1
  import React from 'react';
2
- import {View} from 'react-native';
3
- import {useGridSystem, validateChildren} from './utils';
4
- import SectionItem from './SectionItem';
5
- import {ScreenSectionProps} from './types';
2
+ import {Dimensions, View} from 'react-native';
3
+ import {validateChildren} from './utils';
4
+ import Card from './Card';
5
+ import {GridContextProps, SectionProps} from './types';
6
+ import {GridContext} from './index';
6
7
 
7
- const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
8
- const grid = useGridSystem();
8
+ const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
9
+ const numberOfColumns = 12;
10
+ const gutterSize = 12;
11
+ let margin = 0;
12
+ if (useMargin) {
13
+ margin = 12;
14
+ }
15
+ let widthSection = Dimensions.get('window').width;
16
+ if (useMargin) widthSection = widthSection - margin * 2;
17
+ const totalGutterSize = gutterSize * (numberOfColumns - 1);
18
+ const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
19
+
20
+ const gridContext: GridContextProps = {
21
+ numberOfColumns,
22
+ gutterSize,
23
+ margin,
24
+ sizePerSpan,
25
+ getSizeSpan: span => {
26
+ return span * sizePerSpan + (span - 1) * gutterSize;
27
+ },
28
+ };
9
29
 
10
30
  /**
11
31
  * render overlay only dev mode
@@ -40,17 +60,17 @@ const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
40
60
  ) => {
41
61
  return (
42
62
  <View
43
- key={`SectionItem${cursor}`}
63
+ key={`Card${cursor}`}
44
64
  style={{
45
65
  flexDirection: 'row',
46
- marginBottom: endRow ? 0 : grid.gutterSize,
66
+ marginBottom: endRow ? 0 : gridContext.gutterSize,
47
67
  }}>
48
68
  {rows.map((i: React.ReactElement, index: number) => {
49
69
  return (
50
- <View
51
- key={`SectionItem${cursor}${index}`}
52
- style={{flexDirection: 'row'}}>
53
- {index != 0 && <View style={{width: grid.gutterSize}}></View>}
70
+ <View key={`Card${cursor}${index}`} style={{flexDirection: 'row'}}>
71
+ {index != 0 && (
72
+ <View style={{width: gridContext.gutterSize}}></View>
73
+ )}
54
74
  {i}
55
75
  </View>
56
76
  );
@@ -79,7 +99,7 @@ const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
79
99
  return previousValue + currentValue;
80
100
  });
81
101
 
82
- if (totalSpan <= grid.numberOfColumns) {
102
+ if (totalSpan <= gridContext.numberOfColumns) {
83
103
  rows.push(item);
84
104
  } else {
85
105
  cursor += 1;
@@ -99,19 +119,25 @@ const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
99
119
  };
100
120
 
101
121
  return (
102
- <View
103
- style={{
104
- width: grid.getSizeSpan(),
105
- marginHorizontal: grid.screenPadding,
106
- flexDirection: 'row',
107
- flexWrap: 'wrap',
108
- }}>
109
- {renderView(validateChildren(children, SectionItem))}
110
- {grid.isDevMode && renderOverlay()}
111
- </View>
122
+ <GridContext.Provider value={gridContext}>
123
+ <View
124
+ accessibilityLabel={`Section`}
125
+ style={{
126
+ width: gridContext.getSizeSpan(12),
127
+ marginHorizontal: gridContext.margin,
128
+ flexDirection: 'row',
129
+ flexWrap: 'wrap',
130
+ }}>
131
+ {renderView(validateChildren(children, Card))}
132
+ {__DEV__ && renderOverlay()}
133
+ </View>
134
+ </GridContext.Provider>
112
135
  );
113
136
  };
114
137
 
115
- ScreenSection.displayName = 'ScreenSection';
138
+ Section.displayName = 'Section';
116
139
 
117
- export default ScreenSection;
140
+ Section.defaultProps = {
141
+ useMargin: true,
142
+ };
143
+ export default Section;
package/Layout/index.ts CHANGED
@@ -1,12 +1,16 @@
1
- import SectionItem from './SectionItem';
2
- import ScreenSection from './ScreenSection';
1
+ import Card from './Card';
2
+ import Section from './Section';
3
3
  import GridSystem from './GridSystem';
4
- import {useGridSystem, validateChildren} from './utils';
4
+ import {validateChildren} from './utils';
5
+ import {createContext} from 'react';
6
+ import {GridContextProps} from './types';
5
7
 
6
- export {
7
- SectionItem,
8
- ScreenSection,
9
- GridSystem,
10
- useGridSystem,
11
- validateChildren,
12
- };
8
+ const GridContext = createContext<GridContextProps>({
9
+ numberOfColumns: 12,
10
+ gutterSize: 12,
11
+ margin: 12,
12
+ sizePerSpan: 0,
13
+ getSizeSpan: span => 0,
14
+ });
15
+
16
+ export {GridContext, Card, Section, GridSystem, validateChildren};
package/Layout/types.ts CHANGED
@@ -2,11 +2,20 @@ import {ViewProps} from 'react-native';
2
2
 
3
3
  type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
4
4
 
5
- export interface ScreenSectionProps extends ViewProps {
5
+ export type GridContextProps = {
6
+ numberOfColumns: number;
7
+ gutterSize: number;
8
+ margin?: number;
9
+ sizePerSpan: number;
10
+ getSizeSpan: (span: number) => number;
11
+ };
12
+ export interface SectionProps extends ViewProps {
6
13
  expanded?: boolean;
14
+ useMargin?: boolean;
7
15
  }
8
16
 
9
- export interface SectionItemProps extends ViewProps {
17
+ export interface CardProps extends ViewProps {
10
18
  widthSpan: SpanNumber;
11
19
  heightSpan?: SpanNumber;
20
+ usePadding?: boolean;
12
21
  }
package/Layout/utils.ts CHANGED
@@ -1,38 +1,5 @@
1
- import {Alert, Dimensions} from 'react-native';
1
+ import {Alert} from 'react-native';
2
2
  import React, {ReactElement} from 'react';
3
- import {GutterSize, NumberOfColumns, ScreenPadding} from '../Consts';
4
-
5
- /**
6
- * hook component for use grid system
7
- * @param useMargin
8
- */
9
- const useGridSystem = (useMargin: boolean = true) => {
10
- const isDevMode = false;
11
- const gutterSize = GutterSize;
12
- const screenPadding = useMargin ? ScreenPadding : 0;
13
- const numberOfColumns = NumberOfColumns;
14
- const widthDevice = Dimensions.get('window').width;
15
- const parentWidth = widthDevice - screenPadding * 2;
16
- const totalGutterSize = gutterSize * (numberOfColumns - 1);
17
- const sizePerSpan = (parentWidth - totalGutterSize) / numberOfColumns;
18
-
19
- /**
20
- * get size of element with number span
21
- * @param span
22
- */
23
- const getSizeSpan = (span: number = numberOfColumns): number => {
24
- return span * sizePerSpan + (span - 1) * gutterSize;
25
- };
26
-
27
- return {
28
- isDevMode,
29
- gutterSize,
30
- screenPadding,
31
- numberOfColumns,
32
- sizePerSpan,
33
- getSizeSpan,
34
- };
35
- };
36
3
 
37
4
  /**
38
5
  * validate children type
@@ -80,4 +47,4 @@ const validateChildren = (
80
47
  return results;
81
48
  };
82
49
 
83
- export {useGridSystem, validateChildren};
50
+ export {validateChildren};
@@ -11,7 +11,6 @@ import {ApplicationContext, NavigationButton} from './index';
11
11
  import {Colors, Spacing, Styles} from '../Consts';
12
12
  import {Image} from '../Image';
13
13
  import {HeaderBackgroundProps, TitleCustomProps} from './types';
14
- import {useGridSystem} from '../Layout';
15
14
  import {Text} from '../Text';
16
15
  import {Icon} from '../Icon';
17
16
 
@@ -25,6 +24,7 @@ const styles = StyleSheet.create({
25
24
  headerTitleContainer: {
26
25
  alignItems: 'center',
27
26
  justifyContent: 'center',
27
+ width: '100%',
28
28
  },
29
29
  avatar: {width: 36, height: 36, borderRadius: 18},
30
30
  dotAvatar: {
@@ -74,6 +74,7 @@ const HeaderTitle: React.FC<any> = props => {
74
74
  return (
75
75
  <Animated.Text
76
76
  {...props}
77
+ accessibilityLabel={`HeaderTitle/${props.children}`}
77
78
  style={[styles.title, {opacity, color: props.tintColor}]}
78
79
  />
79
80
  );
@@ -94,7 +95,12 @@ const HeaderLeft: React.FC<any> = ({tintColor}) => {
94
95
 
95
96
  return (
96
97
  <View style={styles.headerLeft}>
97
- <NavigationButton icon="ic_back" tintColor={tintColor} onPress={goBack} />
98
+ <NavigationButton
99
+ icon="ic_back"
100
+ tintColor={tintColor}
101
+ onPress={goBack}
102
+ accessibilityLabel={'Back'}
103
+ />
98
104
  </View>
99
105
  );
100
106
  };
@@ -106,7 +112,9 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
106
112
  }) => {
107
113
  const {theme} = useContext(ApplicationContext);
108
114
  let headerImage = theme.assets?.headerBackground;
115
+ let borderBottomWidth = 0;
109
116
  if (image === null) {
117
+ borderBottomWidth = 1;
110
118
  headerImage = undefined;
111
119
  }
112
120
  const opacity = animatedValue?.interpolate({
@@ -114,6 +122,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
114
122
  outputRange: [0, 1],
115
123
  extrapolate: 'clamp',
116
124
  });
125
+
117
126
  return (
118
127
  <Animated.View
119
128
  style={[
@@ -121,7 +130,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
121
130
  {
122
131
  backgroundColor: backgroundColor ?? theme.colors.background.default,
123
132
  overflow: 'hidden',
124
- borderBottomWidth: headerImage ? 0 : 1,
133
+ borderBottomWidth: borderBottomWidth,
125
134
  borderColor: theme.colors.border.default,
126
135
  opacity,
127
136
  },
@@ -144,8 +153,6 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
144
153
  tintColor,
145
154
  dotColor,
146
155
  }) => {
147
- const {getSizeSpan} = useGridSystem();
148
-
149
156
  const header = (
150
157
  <View style={Styles.row}>
151
158
  <View>
@@ -164,11 +171,7 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
164
171
  </View>
165
172
  </View>
166
173
  );
167
- return (
168
- <View style={[styles.headerTitleContainer, {width: getSizeSpan(10)}]}>
169
- {content ?? header}
170
- </View>
171
- );
174
+ return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
172
175
  };
173
176
 
174
177
  const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
@@ -214,11 +217,11 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
214
217
  borderWidth: backgroundColor ? 0.5 : 0,
215
218
  },
216
219
  ]}>
217
- <TouchableOpacity>
220
+ <TouchableOpacity accessibilityLabel={'Toolkit/More'}>
218
221
  <Icon color={tintColor} source="navigation_more_horiz" size={20} />
219
222
  </TouchableOpacity>
220
223
  <View style={[styles.divider, {backgroundColor: tintColor}]} />
221
- <TouchableOpacity>
224
+ <TouchableOpacity accessibilityLabel={'Toolkit/Close'}>
222
225
  <Icon
223
226
  color={tintColor}
224
227
  source="16_navigation_close_circle"
@@ -63,7 +63,7 @@ const Modal: React.FC<ModalParams> = ({navigation, route}) => {
63
63
  style={styles.modalSpaceVertical}
64
64
  onPress={() => onDismiss()}
65
65
  />
66
- <View style={styles.modalContent}>
66
+ <View style={styles.modalContent} accessibilityLabel={'Modal'}>
67
67
  <Component {...params} />
68
68
  </View>
69
69
  <Pressable
@@ -128,7 +128,9 @@ const BottomSheet: React.FC<BottomSheetParams> = ({navigation, route}) => {
128
128
  }}
129
129
  handleComponent={null}
130
130
  backdropComponent={backdropComponent}>
131
- <View style={{paddingBottom: bottom}}>
131
+ <View
132
+ style={{paddingBottom: bottom}}
133
+ accessibilityLabel={'BottomSheet'}>
132
134
  <View style={[styles.sheetContainer, {backgroundColor}]}>
133
135
  <View style={styles.indicatorContainer}>
134
136
  <View
@@ -11,6 +11,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
11
11
  onPress,
12
12
  backgroundColor,
13
13
  useBorder = true,
14
+ accessibilityLabel,
14
15
  }) => {
15
16
  const {theme} = useContext(ApplicationContext);
16
17
  if (!backgroundColor && tintColor != Colors.black_01) {
@@ -19,6 +20,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
19
20
 
20
21
  return (
21
22
  <TouchableOpacity
23
+ accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
22
24
  style={[
23
25
  styles.container,
24
26
  {
@@ -10,7 +10,7 @@ import StackScreen from './StackScreen';
10
10
  import ModalScreen from './ModalScreen';
11
11
  import Navigator from './Navigator';
12
12
  import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
13
- import {GridSystem, useGridSystem} from '../Layout';
13
+ import {GridSystem} from '../Layout';
14
14
  import {defaultContext} from '../Consts';
15
15
  import {NavigationContainerProps} from './types';
16
16
 
@@ -22,7 +22,6 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
22
22
  theme,
23
23
  options,
24
24
  }) => {
25
- const grid = useGridSystem();
26
25
  const navigationRef = React.useRef<NavigationContainerRef>(null);
27
26
  const navigator = useRef(new Navigator(navigationRef));
28
27
 
@@ -75,7 +74,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
75
74
  </ReactNavigationContainer>
76
75
  </ApplicationContext.Provider>
77
76
  </BottomSheetModalProvider>
78
- {grid.isDevMode && <GridSystem />}
77
+ {__DEV__ && <GridSystem />}
79
78
  </SafeAreaProvider>
80
79
  );
81
80
  };
@@ -24,7 +24,6 @@ const StackScreen: React.FC<any> = props => {
24
24
  }
25
25
  }, [options]);
26
26
 
27
- console.log(params);
28
27
  return <Component {...params} />;
29
28
  };
30
29
 
@@ -71,9 +71,11 @@ export type NavigationContainerProps = {
71
71
  export interface ScreenContainerProps extends ViewProps {
72
72
  edges?: any[];
73
73
  enableKeyboardAvoidingView?: boolean;
74
- scrollable: boolean;
74
+ headerBackground?: string;
75
+ scrollable?: boolean;
76
+ scrollY?: Animated.Value;
75
77
  scrollViewProps?: ScrollViewProps;
76
- headerImage?: string;
78
+ footerComponent?: React.ElementType;
77
79
  }
78
80
 
79
81
  export type ScreenParams = {
@@ -100,6 +102,7 @@ export type NavigationButtonProps = {
100
102
  backgroundColor?: string;
101
103
  useBorder?: boolean;
102
104
  onPress: () => void;
105
+ accessibilityLabel?: string;
103
106
  };
104
107
 
105
108
  export type NavigationOptions = {
@@ -132,6 +132,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
132
132
 
133
133
  return (
134
134
  <View
135
+ accessibilityLabel={'PopupNotify'}
135
136
  style={[
136
137
  styles.container,
137
138
  {backgroundColor: theme.colors.background.surface},
@@ -38,7 +38,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({image, onClose}) => {
38
38
  };
39
39
 
40
40
  return (
41
- <>
41
+ <View accessibilityLabel={'PopupPromotion'}>
42
42
  <Image
43
43
  style={styles.container}
44
44
  source={{
@@ -46,7 +46,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({image, onClose}) => {
46
46
  }}
47
47
  />
48
48
  {buildCloseIcon()}
49
- </>
49
+ </View>
50
50
  );
51
51
  };
52
52
 
package/Radio/index.tsx CHANGED
@@ -39,6 +39,7 @@ const Radio: FC<RadioProps> = ({
39
39
 
40
40
  return (
41
41
  <TouchableOpacity
42
+ accessibilityLabel={`Radio/${label}`}
42
43
  onPress={onChange}
43
44
  disabled={disabled}
44
45
  style={[
@@ -42,7 +42,7 @@ const Skeleton: React.FC<SkeletonTypes> = ({style}) => {
42
42
  }
43
43
  };
44
44
  return (
45
- <View style={[styles.container, style]}>
45
+ <View style={[styles.container, style]} accessibilityLabel={'Skeleton'}>
46
46
  <View
47
47
  onLayout={e => onLayout(e.nativeEvent.layout.width)}
48
48
  style={[Styles.flex, {backgroundColor: PRIMARY_COLOR}]}>
package/Switch/index.tsx CHANGED
@@ -18,6 +18,7 @@ const Switch: FC<SwitchProps> = props => {
18
18
 
19
19
  return (
20
20
  <TouchableOpacity
21
+ accessibilityLabel={'Switch'}
21
22
  disabled={disabled}
22
23
  onPress={() => onChange?.(!value)}
23
24
  style={[
package/Text/index.tsx CHANGED
@@ -3,6 +3,7 @@ import {Text as RNText, TextProps as RNTextProps} from 'react-native';
3
3
  import styles from './styles';
4
4
  import {Typography, TypographyWeight} from './types';
5
5
  import {ApplicationContext} from '../Navigation';
6
+ import {GridContext} from '../Layout';
6
7
 
7
8
  const SFProText: TypographyWeight = {
8
9
  100: 'Thin',
@@ -40,6 +41,7 @@ const FontStyle: {[key: string]: string} = {
40
41
  export interface TextProps extends RNTextProps {
41
42
  typography: Typography;
42
43
  color?: string;
44
+ widthSpan?: number;
43
45
  }
44
46
 
45
47
  const Text: React.FC<TextProps> = ({
@@ -47,8 +49,10 @@ const Text: React.FC<TextProps> = ({
47
49
  color,
48
50
  children,
49
51
  style,
52
+ widthSpan,
50
53
  ...rest
51
54
  }) => {
55
+ const grid = useContext(GridContext);
52
56
  const {theme} = useContext(ApplicationContext);
53
57
 
54
58
  const getTypoStyle = (typo: Typography) => {
@@ -83,11 +87,17 @@ const Text: React.FC<TextProps> = ({
83
87
  };
84
88
 
85
89
  const textStyle = getTypoStyle(typography);
86
-
90
+ const spanStyle = widthSpan ? {width: grid.getSizeSpan(widthSpan)} : {};
87
91
  return (
88
92
  <RNText
89
93
  {...rest}
90
- style={[style, textStyle, {color: color ?? theme.colors.text.default}]}>
94
+ accessibilityLabel={`Text/${children}`}
95
+ style={[
96
+ style,
97
+ textStyle,
98
+ spanStyle,
99
+ {color: color ?? theme.colors.text.default},
100
+ ]}>
91
101
  {children ?? ''}
92
102
  </RNText>
93
103
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {
@@ -1,63 +0,0 @@
1
- import React, {useContext} from 'react';
2
- import {View} from 'react-native';
3
- import {useGridSystem} from './index';
4
- import {SectionItemProps} from './types';
5
- import {ApplicationContext} from '../Navigation';
6
-
7
- const SectionItem: React.FC<SectionItemProps> = ({
8
- widthSpan = 12,
9
- heightSpan,
10
- children,
11
- style,
12
- }) => {
13
- const {theme} = useContext(ApplicationContext);
14
- const grid = useGridSystem();
15
-
16
- /**
17
- * render overlay view only dev mode
18
- */
19
- const renderOverlay = () => {
20
- return (
21
- <View
22
- pointerEvents={'none'}
23
- style={{
24
- position: 'absolute',
25
- top: 0,
26
- bottom: 0,
27
- left: 0,
28
- right: 0,
29
- borderColor: 'red',
30
- borderWidth: 1,
31
- }}
32
- />
33
- );
34
- };
35
-
36
- const styles: any = style ?? {};
37
-
38
- return (
39
- <View
40
- style={{
41
- ...styles,
42
- width: grid.getSizeSpan(widthSpan),
43
- height: heightSpan ? grid.getSizeSpan(heightSpan) : undefined,
44
- overflow: 'hidden',
45
- margin: undefined,
46
- marginTop: undefined,
47
- marginBottom: undefined,
48
- marginLeft: undefined,
49
- marginRight: undefined,
50
- }}>
51
- {children}
52
- {grid.isDevMode && renderOverlay()}
53
- </View>
54
- );
55
- };
56
-
57
- SectionItem.defaultProps = {
58
- widthSpan: 12,
59
- };
60
-
61
- SectionItem.displayName = 'SectionItem';
62
-
63
- export default SectionItem;