@momo-kits/foundation 0.75.1-beta.8 → 0.75.2-beta.0
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/Application/BottomTab/BottomTabBar.tsx +478 -0
- package/Application/BottomTab/index.tsx +134 -0
- package/Application/Components.tsx +552 -0
- package/Application/ModalScreen.tsx +244 -0
- package/Application/Navigation.ts +50 -0
- package/Application/NavigationContainer.tsx +128 -0
- package/Application/Navigator.ts +151 -0
- package/Application/StackScreen.tsx +146 -0
- package/Application/index.ts +37 -0
- package/{Navigation → Application}/types.ts +96 -27
- package/Application/utils.tsx +175 -0
- package/Assets/DotAnimation.json +256 -0
- package/Assets/SpinnerAnimation.json +1027 -0
- package/Assets/icon.json +89 -5
- package/Assets/icon_bank.json +506 -0
- package/Assets/language.json +202 -0
- package/Badge/Badge.tsx +56 -0
- package/Badge/BadgeDot.tsx +11 -0
- package/Badge/BadgeRibbon.tsx +125 -0
- package/Badge/Shape.tsx +29 -0
- package/Badge/index.tsx +7 -0
- package/Badge/styles.ts +58 -0
- package/Badge/types.ts +63 -0
- package/Button/index.tsx +90 -39
- package/Button/styles.ts +19 -0
- package/CheckBox/index.tsx +58 -43
- package/CheckBox/styles.ts +1 -1
- package/CheckBox/types.ts +6 -4
- package/Consts/colors+spacing+radius.ts +18 -0
- package/Consts/styles.ts +0 -26
- package/Consts/theme.ts +5 -1
- package/Divider/index.tsx +3 -1
- package/Icon/index.tsx +14 -10
- package/Icon/types.ts +4 -3
- package/IconButton/index.tsx +24 -15
- package/Image/index.tsx +63 -45
- package/Image/styles.ts +1 -9
- package/Image/types.ts +5 -1
- package/Input/Input.tsx +227 -115
- package/Input/InputDropDown.tsx +132 -0
- package/Input/InputMoney.tsx +174 -110
- package/Input/InputOTP.tsx +257 -0
- package/Input/InputSearch.tsx +160 -130
- package/Input/InputTextArea.tsx +149 -121
- package/Input/common.tsx +43 -18
- package/Input/index.tsx +205 -17
- package/Input/styles.ts +44 -7
- package/Input/utils.ts +2 -2
- package/Layout/Card.tsx +154 -62
- package/Layout/FloatingButton.tsx +128 -0
- package/Layout/GridSystem.tsx +35 -23
- package/Layout/Item.tsx +56 -0
- package/Layout/ItemList.tsx +55 -0
- package/Layout/ItemSectionList.tsx +39 -0
- package/Layout/Screen.tsx +378 -0
- package/Layout/Section.tsx +74 -39
- package/Layout/index.ts +14 -3
- package/Layout/styles.ts +101 -0
- package/Layout/types.ts +1 -39
- package/Layout/utils.ts +42 -37
- package/Loader/DotLoader.tsx +37 -0
- package/Loader/Loader.tsx +13 -0
- package/Loader/ProgressBar.tsx +44 -0
- package/Loader/Spinner.tsx +29 -0
- package/Loader/index.tsx +4 -0
- package/Loader/styles.ts +10 -0
- package/Loader/types.ts +35 -0
- package/Loader/utils.ts +25 -0
- package/Pagination/Dot.tsx +1 -1
- package/Pagination/PaginationDot.tsx +8 -3
- package/Pagination/PaginationNumber.tsx +8 -7
- package/Pagination/PaginationScroll.tsx +1 -1
- package/Pagination/PaginationWhiteDot.tsx +8 -5
- package/Pagination/styles.ts +3 -0
- package/Pagination/types.ts +2 -0
- package/Popup/PopupNotify.tsx +102 -44
- package/Popup/PopupPromotion.tsx +63 -22
- package/Popup/types.ts +15 -4
- package/Radio/index.tsx +35 -21
- package/Radio/types.ts +7 -5
- package/Skeleton/index.tsx +1 -1
- package/Skeleton/types.ts +3 -0
- package/Switch/index.tsx +35 -24
- package/Switch/types.ts +5 -3
- package/Tag/index.tsx +1 -1
- package/Text/index.tsx +32 -26
- package/Text/styles.ts +38 -0
- package/Text/types.ts +25 -13
- package/Text/utils.ts +14 -0
- package/Title/index.tsx +186 -0
- package/Title/styles.ts +79 -0
- package/Title/types.ts +20 -0
- package/code-scanner.js +143 -0
- package/index.ts +17 -3
- package/migrate_typo.js +56 -0
- package/package.json +44 -39
- package/publish.sh +2 -5
- package/tsconfig.json +24 -0
- package/verify.js +47 -0
- package/Assets/header-background.png +0 -0
- package/Layout/ScreenContainer.tsx +0 -122
- package/Navigation/BottomTab.tsx +0 -39
- package/Navigation/Components.tsx +0 -365
- package/Navigation/ModalScreen.tsx +0 -226
- package/Navigation/Navigation.ts +0 -44
- package/Navigation/NavigationButton.tsx +0 -54
- package/Navigation/NavigationContainer.tsx +0 -77
- package/Navigation/Navigator.ts +0 -82
- package/Navigation/Observer.ts +0 -79
- package/Navigation/StackScreen.tsx +0 -27
- package/Navigation/index.ts +0 -14
- package/Navigation/utils.tsx +0 -137
package/Layout/Card.tsx
CHANGED
|
@@ -1,88 +1,180 @@
|
|
|
1
|
-
import React, {useContext} from 'react';
|
|
2
|
-
import {View} from 'react-native';
|
|
1
|
+
import React, {Fragment, useContext} from 'react';
|
|
2
|
+
import {Dimensions, View, ViewProps} from 'react-native';
|
|
3
|
+
import {useGridSystem, validateChildren} from './utils';
|
|
4
|
+
import {GridContextProps} from './types';
|
|
5
|
+
import {GridContext, GridSystem} from './index';
|
|
6
|
+
import Item from './Item';
|
|
7
|
+
import {Image} from '../Image';
|
|
8
|
+
import {ApplicationContext} from '../Application';
|
|
9
|
+
import styles from './styles';
|
|
10
|
+
import {Colors, Radius, Shadow, Spacing} from '../Consts';
|
|
11
|
+
import ItemList from './ItemList';
|
|
3
12
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
13
|
+
export interface CardProps extends ViewProps {
|
|
14
|
+
/**
|
|
15
|
+
* Optional. Background image for the card.
|
|
16
|
+
*/
|
|
17
|
+
backgroundImage?: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Optional. Use shadow for the card.
|
|
21
|
+
*/
|
|
22
|
+
useShadow?: boolean;
|
|
23
|
+
}
|
|
7
24
|
|
|
8
25
|
const Card: React.FC<CardProps> = ({
|
|
9
|
-
widthSpan = 12,
|
|
10
|
-
heightSpan,
|
|
11
|
-
usePadding,
|
|
12
26
|
children,
|
|
13
27
|
style,
|
|
28
|
+
backgroundImage,
|
|
29
|
+
useShadow = false,
|
|
30
|
+
...props
|
|
14
31
|
}) => {
|
|
15
|
-
const
|
|
32
|
+
const {showGrid, theme} = useContext(ApplicationContext);
|
|
33
|
+
const {numberOfColumns} = useGridSystem();
|
|
34
|
+
|
|
35
|
+
const gutterSize = 8;
|
|
36
|
+
const margin = 12;
|
|
37
|
+
|
|
38
|
+
const widthSection = Dimensions.get('window').width - margin * 2;
|
|
39
|
+
const totalGutterSize = gutterSize * (numberOfColumns - 1);
|
|
40
|
+
const sizePerSpan = (widthSection - totalGutterSize - 24) / numberOfColumns;
|
|
41
|
+
|
|
42
|
+
const gridContext: GridContextProps = {
|
|
43
|
+
numberOfColumns,
|
|
44
|
+
gutterSize,
|
|
45
|
+
sizePerSpan,
|
|
46
|
+
getSizeSpan: span => {
|
|
47
|
+
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
16
50
|
|
|
17
51
|
/**
|
|
18
|
-
* render overlay
|
|
52
|
+
* render overlay only dev mode
|
|
19
53
|
*/
|
|
20
54
|
const renderOverlay = () => {
|
|
55
|
+
return (
|
|
56
|
+
<>
|
|
57
|
+
<GridSystem
|
|
58
|
+
width={widthSection}
|
|
59
|
+
gutterSize={Spacing.S}
|
|
60
|
+
screenGrid={false}
|
|
61
|
+
gridColor={Colors.red_01}
|
|
62
|
+
/>
|
|
63
|
+
<View pointerEvents={'none'} style={styles.boxGridCard} />
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* build a row view in side session
|
|
70
|
+
* @param rows
|
|
71
|
+
* @param cursor
|
|
72
|
+
* @param endRow
|
|
73
|
+
*/
|
|
74
|
+
const addRowView = (
|
|
75
|
+
rows: any[],
|
|
76
|
+
cursor: number = 0,
|
|
77
|
+
endRow: boolean = false,
|
|
78
|
+
) => {
|
|
21
79
|
return (
|
|
22
80
|
<View
|
|
23
|
-
|
|
81
|
+
key={`Item${cursor}`}
|
|
24
82
|
style={{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
83
|
+
flexDirection: 'row',
|
|
84
|
+
marginBottom: endRow ? 0 : gridContext.gutterSize,
|
|
85
|
+
}}>
|
|
86
|
+
{rows.map((i: React.ReactElement, index: number) => {
|
|
87
|
+
return (
|
|
88
|
+
<View key={`Item${cursor}${index}`} style={{flexDirection: 'row'}}>
|
|
89
|
+
{index != 0 && (
|
|
90
|
+
<View style={{width: gridContext.gutterSize}}></View>
|
|
91
|
+
)}
|
|
92
|
+
{i}
|
|
93
|
+
</View>
|
|
94
|
+
);
|
|
95
|
+
})}
|
|
96
|
+
</View>
|
|
34
97
|
);
|
|
35
98
|
};
|
|
36
99
|
|
|
37
|
-
|
|
100
|
+
/**
|
|
101
|
+
* render children content for card
|
|
102
|
+
* @param children
|
|
103
|
+
*/
|
|
104
|
+
const renderView = (
|
|
105
|
+
children: any,
|
|
106
|
+
): React.ReactElement | React.ReactElement[] => {
|
|
107
|
+
const element: React.ReactElement | React.ReactElement[] = [];
|
|
108
|
+
if (Array.isArray(children)) {
|
|
109
|
+
let cursor = 0;
|
|
110
|
+
let rows: any[] = [];
|
|
111
|
+
const arrayChild = children.filter(item => !!item);
|
|
112
|
+
for (let i = 0; i < arrayChild.length; ++i) {
|
|
113
|
+
const item = arrayChild[i];
|
|
114
|
+
const totalSpan = rows
|
|
115
|
+
.concat([item])
|
|
116
|
+
.map(i => i.props?.widthSpan)
|
|
117
|
+
.reduce((previousValue, currentValue) => {
|
|
118
|
+
return previousValue + currentValue;
|
|
119
|
+
});
|
|
38
120
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
121
|
+
if (totalSpan <= gridContext.numberOfColumns) {
|
|
122
|
+
rows.push(item);
|
|
123
|
+
} else {
|
|
124
|
+
cursor += 1;
|
|
125
|
+
element.push(addRowView(rows, cursor));
|
|
126
|
+
rows = [item];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (i == arrayChild.length - 1) {
|
|
130
|
+
cursor += 1;
|
|
131
|
+
element.push(addRowView(rows, cursor, true));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
element.push(children);
|
|
136
|
+
if (children?.type == Fragment) {
|
|
137
|
+
return renderView(children?.props.children);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return element;
|
|
56
141
|
};
|
|
57
142
|
|
|
58
143
|
return (
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
144
|
+
<GridContext.Provider value={gridContext}>
|
|
145
|
+
<View
|
|
146
|
+
{...props}
|
|
147
|
+
style={[
|
|
148
|
+
{backgroundColor: theme.colors.background.surface},
|
|
149
|
+
style,
|
|
150
|
+
styles.protectedStyle,
|
|
151
|
+
styles.card,
|
|
152
|
+
{
|
|
153
|
+
width: widthSection,
|
|
154
|
+
marginHorizontal: margin,
|
|
155
|
+
},
|
|
156
|
+
!!backgroundImage && {backgroundColor: undefined},
|
|
157
|
+
useShadow && Shadow.Light,
|
|
158
|
+
]}>
|
|
159
|
+
{!!backgroundImage && (
|
|
160
|
+
<Image
|
|
161
|
+
source={{uri: backgroundImage}}
|
|
162
|
+
style={[
|
|
163
|
+
styles.imageBackground,
|
|
164
|
+
{
|
|
165
|
+
width: widthSection,
|
|
166
|
+
borderRadius: Radius.M,
|
|
167
|
+
},
|
|
168
|
+
]}
|
|
169
|
+
/>
|
|
170
|
+
)}
|
|
171
|
+
{renderView(validateChildren(children, [Item, ItemList]))}
|
|
172
|
+
{showGrid && renderOverlay()}
|
|
173
|
+
</View>
|
|
174
|
+
</GridContext.Provider>
|
|
78
175
|
);
|
|
79
176
|
};
|
|
80
177
|
|
|
81
|
-
Card.defaultProps = {
|
|
82
|
-
widthSpan: 12,
|
|
83
|
-
usePadding: false,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
178
|
Card.displayName = 'Card';
|
|
87
179
|
|
|
88
180
|
export default Card;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {default as React, useContext, useEffect, useRef, useState} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Animated,
|
|
4
|
+
LayoutChangeEvent,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
TouchableOpacity,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import {ApplicationContext} from '../Application';
|
|
9
|
+
import {Icon} from '../Icon';
|
|
10
|
+
import {Text} from '../Text';
|
|
11
|
+
|
|
12
|
+
export interface FloatingButtonProps {
|
|
13
|
+
label?: string;
|
|
14
|
+
onPress?: () => void;
|
|
15
|
+
position?: 'center' | 'right';
|
|
16
|
+
icon?: string;
|
|
17
|
+
iconColor?: string;
|
|
18
|
+
size?: 'small' | 'large';
|
|
19
|
+
animatedValue?: Animated.Value;
|
|
20
|
+
bottom?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
24
|
+
label = '',
|
|
25
|
+
onPress = () => {},
|
|
26
|
+
position = 'right',
|
|
27
|
+
icon = '',
|
|
28
|
+
iconColor = '',
|
|
29
|
+
size = 'small',
|
|
30
|
+
animatedValue,
|
|
31
|
+
bottom = 12,
|
|
32
|
+
}: FloatingButtonProps) => {
|
|
33
|
+
const {theme} = useContext(ApplicationContext);
|
|
34
|
+
const maxWidth = useRef(0);
|
|
35
|
+
const minWidth = size == 'small' ? 36 : 48;
|
|
36
|
+
const [widthAnimated, setWidthAnimated] = useState<Animated.Value>();
|
|
37
|
+
const lastOffset = useRef(0);
|
|
38
|
+
const debounce = useRef<any>();
|
|
39
|
+
const [showText, setShowText] = React.useState(true);
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!label) return;
|
|
43
|
+
|
|
44
|
+
const listener = animatedValue?.addListener(({value}) => {
|
|
45
|
+
clearTimeout(debounce.current);
|
|
46
|
+
debounce.current = setTimeout(() => {
|
|
47
|
+
const down = value > lastOffset.current;
|
|
48
|
+
lastOffset.current = value;
|
|
49
|
+
if (down) {
|
|
50
|
+
Animated.timing(widthAnimated!, {
|
|
51
|
+
toValue: minWidth,
|
|
52
|
+
duration: 300,
|
|
53
|
+
useNativeDriver: false,
|
|
54
|
+
}).start(() => setShowText(false));
|
|
55
|
+
} else {
|
|
56
|
+
Animated.timing(widthAnimated!, {
|
|
57
|
+
toValue: maxWidth.current,
|
|
58
|
+
duration: 300,
|
|
59
|
+
useNativeDriver: false,
|
|
60
|
+
}).start(() => setShowText(true));
|
|
61
|
+
}
|
|
62
|
+
}, 500);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return () => {
|
|
66
|
+
if (listener != null) {
|
|
67
|
+
animatedValue?.removeListener(listener);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}, [label, widthAnimated]);
|
|
71
|
+
|
|
72
|
+
const handleLayout = (event: LayoutChangeEvent) => {
|
|
73
|
+
const layout = event.nativeEvent.layout;
|
|
74
|
+
if (widthAnimated) return;
|
|
75
|
+
maxWidth.current = layout.width;
|
|
76
|
+
setWidthAnimated(new Animated.Value(layout.width));
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<Animated.View
|
|
81
|
+
onLayout={handleLayout}
|
|
82
|
+
style={[
|
|
83
|
+
styles.container,
|
|
84
|
+
{
|
|
85
|
+
right: position === 'right' ? 12 : undefined,
|
|
86
|
+
alignSelf: position === 'center' ? 'center' : 'flex-end',
|
|
87
|
+
width: widthAnimated,
|
|
88
|
+
height: size == 'small' ? 36 : 48,
|
|
89
|
+
backgroundColor: theme.colors.primary,
|
|
90
|
+
bottom,
|
|
91
|
+
},
|
|
92
|
+
]}>
|
|
93
|
+
<TouchableOpacity
|
|
94
|
+
style={{flexDirection: 'row', alignItems: 'center'}}
|
|
95
|
+
onPress={onPress}>
|
|
96
|
+
<Icon
|
|
97
|
+
source={icon}
|
|
98
|
+
size={size === 'small' ? 12 : 24}
|
|
99
|
+
color={iconColor}
|
|
100
|
+
/>
|
|
101
|
+
{showText && !!label && (
|
|
102
|
+
<Text
|
|
103
|
+
style={styles.label}
|
|
104
|
+
color="white"
|
|
105
|
+
typography="action_default_bold">
|
|
106
|
+
{label}
|
|
107
|
+
</Text>
|
|
108
|
+
)}
|
|
109
|
+
</TouchableOpacity>
|
|
110
|
+
</Animated.View>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const styles = StyleSheet.create({
|
|
115
|
+
container: {
|
|
116
|
+
flexDirection: 'row',
|
|
117
|
+
alignContent: 'center',
|
|
118
|
+
alignItems: 'center',
|
|
119
|
+
position: 'absolute',
|
|
120
|
+
borderRadius: 100,
|
|
121
|
+
paddingHorizontal: 12,
|
|
122
|
+
flexWrap: 'wrap',
|
|
123
|
+
alignSelf: 'flex-end',
|
|
124
|
+
},
|
|
125
|
+
label: {
|
|
126
|
+
marginLeft: 8,
|
|
127
|
+
},
|
|
128
|
+
});
|
package/Layout/GridSystem.tsx
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
2
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
3
3
|
import {Dimensions, StyleSheet, View} from 'react-native';
|
|
4
|
-
import {ApplicationContext} from '../
|
|
4
|
+
import {ApplicationContext} from '../Application';
|
|
5
5
|
import {Colors, Spacing} from '../Consts';
|
|
6
6
|
import {GridContextProps} from './types';
|
|
7
|
+
import {useGridSystem} from './utils';
|
|
7
8
|
|
|
8
|
-
const GridSystem: React.FC = (
|
|
9
|
+
const GridSystem: React.FC<any> = ({
|
|
10
|
+
width = Dimensions.get('window').width,
|
|
11
|
+
useMargin = true,
|
|
12
|
+
gutterSize = Spacing.M,
|
|
13
|
+
screenGrid = true,
|
|
14
|
+
gridColor = Colors.blue_07,
|
|
15
|
+
}) => {
|
|
9
16
|
const {theme} = useContext(ApplicationContext);
|
|
10
|
-
const numberOfColumns =
|
|
11
|
-
|
|
12
|
-
const margin =
|
|
13
|
-
const widthSection =
|
|
17
|
+
const {numberOfColumns} = useGridSystem();
|
|
18
|
+
|
|
19
|
+
const margin = useMargin ? Spacing.M : 0;
|
|
20
|
+
const widthSection = width - margin * 2;
|
|
14
21
|
const totalGutterSize = gutterSize * (numberOfColumns - 1);
|
|
15
22
|
const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
|
|
16
23
|
|
|
17
24
|
const grid: GridContextProps = {
|
|
18
25
|
numberOfColumns,
|
|
19
26
|
gutterSize,
|
|
20
|
-
margin,
|
|
21
27
|
sizePerSpan,
|
|
22
28
|
getSizeSpan: span => {
|
|
23
29
|
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
@@ -25,7 +31,7 @@ const GridSystem: React.FC = () => {
|
|
|
25
31
|
};
|
|
26
32
|
const insets = useSafeAreaInsets();
|
|
27
33
|
|
|
28
|
-
const list = [];
|
|
34
|
+
const list: number[] = [];
|
|
29
35
|
for (let i = 1; i <= grid.numberOfColumns; i++) {
|
|
30
36
|
list.push(i);
|
|
31
37
|
}
|
|
@@ -36,23 +42,26 @@ const GridSystem: React.FC = () => {
|
|
|
36
42
|
pointerEvents="none"
|
|
37
43
|
style={[
|
|
38
44
|
styles.gridContainer,
|
|
39
|
-
insets,
|
|
45
|
+
screenGrid && insets,
|
|
40
46
|
{
|
|
41
47
|
borderColor: theme.colors.error.primary,
|
|
42
|
-
marginHorizontal:
|
|
48
|
+
marginHorizontal: margin,
|
|
49
|
+
top: Spacing.M,
|
|
50
|
+
bottom: Spacing.M,
|
|
43
51
|
},
|
|
44
52
|
]}>
|
|
45
|
-
{list.map((
|
|
53
|
+
{list.map((_, index) => {
|
|
46
54
|
return (
|
|
47
55
|
<View style={{flexDirection: 'row'}} key={index.toString()}>
|
|
48
56
|
{index != -0 && <View style={{width: grid.gutterSize}} />}
|
|
49
57
|
<View
|
|
50
|
-
key={index.toString()}
|
|
58
|
+
key={`Grid${index.toString()}`}
|
|
51
59
|
pointerEvents="none"
|
|
52
60
|
style={[
|
|
53
61
|
styles.gridColumn,
|
|
54
62
|
{
|
|
55
63
|
width: grid.sizePerSpan,
|
|
64
|
+
backgroundColor: gridColor,
|
|
56
65
|
},
|
|
57
66
|
]}
|
|
58
67
|
/>
|
|
@@ -60,16 +69,20 @@ const GridSystem: React.FC = () => {
|
|
|
60
69
|
);
|
|
61
70
|
})}
|
|
62
71
|
</View>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
{screenGrid && (
|
|
73
|
+
<>
|
|
74
|
+
<View pointerEvents="none" style={styles.dangerLeftContainer} />
|
|
75
|
+
<View pointerEvents="none" style={styles.dangerRightContainer} />
|
|
76
|
+
<View
|
|
77
|
+
pointerEvents="none"
|
|
78
|
+
style={[styles.dangerTopContainer, {height: Spacing.M}]}
|
|
79
|
+
/>
|
|
80
|
+
<View
|
|
81
|
+
pointerEvents="none"
|
|
82
|
+
style={[styles.dangerBottomContainer, {height: insets.bottom}]}
|
|
83
|
+
/>
|
|
84
|
+
</>
|
|
85
|
+
)}
|
|
73
86
|
</>
|
|
74
87
|
);
|
|
75
88
|
};
|
|
@@ -87,7 +100,6 @@ const styles = StyleSheet.create({
|
|
|
87
100
|
gridColumn: {
|
|
88
101
|
height: '100%',
|
|
89
102
|
opacity: 0.2,
|
|
90
|
-
backgroundColor: Colors.blue_07,
|
|
91
103
|
},
|
|
92
104
|
dangerTopContainer: {
|
|
93
105
|
opacity: 0.2,
|
package/Layout/Item.tsx
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import {View, ViewProps} from 'react-native';
|
|
3
|
+
|
|
4
|
+
import {GridContext} from './index';
|
|
5
|
+
import {ApplicationContext} from '../Application';
|
|
6
|
+
import styles from './styles';
|
|
7
|
+
|
|
8
|
+
export type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
9
|
+
|
|
10
|
+
export interface ItemProps extends ViewProps {
|
|
11
|
+
/**
|
|
12
|
+
* Represents the width of the Card component in terms of span numbers (1-12).
|
|
13
|
+
*/
|
|
14
|
+
widthSpan?: SpanNumber;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Optional. Represents the height of the Card component in terms of span numbers (1-12).
|
|
18
|
+
*/
|
|
19
|
+
heightSpan?: SpanNumber;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const Item: React.FC<ItemProps> = ({
|
|
23
|
+
widthSpan,
|
|
24
|
+
heightSpan,
|
|
25
|
+
children,
|
|
26
|
+
style,
|
|
27
|
+
}) => {
|
|
28
|
+
const {showGrid} = useContext(ApplicationContext);
|
|
29
|
+
const grid = useContext(GridContext);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* render overlay view only dev mode
|
|
33
|
+
*/
|
|
34
|
+
const renderOverlay = () => {
|
|
35
|
+
return <View pointerEvents={'none'} style={styles.boxGrid} />;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<View
|
|
40
|
+
style={[
|
|
41
|
+
style,
|
|
42
|
+
styles.item,
|
|
43
|
+
{
|
|
44
|
+
width: grid.getSizeSpan(widthSpan ?? grid.numberOfColumns),
|
|
45
|
+
height: heightSpan ? grid.getSizeSpan(heightSpan) : undefined,
|
|
46
|
+
},
|
|
47
|
+
]}>
|
|
48
|
+
{children}
|
|
49
|
+
{showGrid && renderOverlay()}
|
|
50
|
+
</View>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
Item.displayName = 'Item';
|
|
55
|
+
|
|
56
|
+
export default Item;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React, {forwardRef, useContext} from 'react';
|
|
2
|
+
import {FlatList, FlatListProps, View} from 'react-native';
|
|
3
|
+
import Item, {SpanNumber} from './Item';
|
|
4
|
+
import {GridContext} from './index';
|
|
5
|
+
import styles from './styles';
|
|
6
|
+
|
|
7
|
+
export interface ItemListProps extends FlatListProps<any> {
|
|
8
|
+
/**
|
|
9
|
+
* Represents the width of the Card component in terms of span numbers (1-12).
|
|
10
|
+
*/
|
|
11
|
+
widthSpan?: SpanNumber;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ItemList = forwardRef(
|
|
15
|
+
(
|
|
16
|
+
{
|
|
17
|
+
renderItem,
|
|
18
|
+
widthSpan,
|
|
19
|
+
style,
|
|
20
|
+
contentContainerStyle,
|
|
21
|
+
...props
|
|
22
|
+
}: ItemListProps,
|
|
23
|
+
ref,
|
|
24
|
+
) => {
|
|
25
|
+
const {gutterSize, numberOfColumns} = useContext(GridContext);
|
|
26
|
+
const widthItem = (widthSpan ?? numberOfColumns) as SpanNumber;
|
|
27
|
+
const numColumns = Math.floor(numberOfColumns / widthItem);
|
|
28
|
+
const indexBegin = props?.data?.map((_i, index) => index * numColumns);
|
|
29
|
+
const _renderItem = (item: any) => {
|
|
30
|
+
if (indexBegin?.includes(item?.index)) {
|
|
31
|
+
return <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>;
|
|
32
|
+
}
|
|
33
|
+
return (
|
|
34
|
+
<View style={{paddingLeft: gutterSize}}>
|
|
35
|
+
<Item widthSpan={widthItem}>{renderItem?.(item)}</Item>
|
|
36
|
+
</View>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<FlatList
|
|
42
|
+
ref={ref as React.RefObject<FlatList>}
|
|
43
|
+
{...props}
|
|
44
|
+
numColumns={numColumns}
|
|
45
|
+
renderItem={_renderItem}
|
|
46
|
+
horizontal={false}
|
|
47
|
+
ItemSeparatorComponent={() => <View style={{height: gutterSize}} />}
|
|
48
|
+
style={[style, styles.protectedStyle]}
|
|
49
|
+
contentContainerStyle={[contentContainerStyle, styles.protectedStyle]}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
export default ItemList;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {SectionList, SectionListProps, View} from 'react-native';
|
|
3
|
+
import Item, {SpanNumber} from './Item';
|
|
4
|
+
import {GridContext} from './index';
|
|
5
|
+
import styles from './styles';
|
|
6
|
+
|
|
7
|
+
export interface ItemSectionListProps extends SectionListProps<any> {
|
|
8
|
+
/**
|
|
9
|
+
* Represents the width of the Card component in terms of span numbers (1-12).
|
|
10
|
+
*/
|
|
11
|
+
widthSpan?: SpanNumber;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ItemSectionList: FC<ItemSectionListProps> = ({
|
|
15
|
+
renderItem,
|
|
16
|
+
widthSpan,
|
|
17
|
+
style,
|
|
18
|
+
contentContainerStyle,
|
|
19
|
+
...props
|
|
20
|
+
}) => {
|
|
21
|
+
const {gutterSize, numberOfColumns} = useContext(GridContext);
|
|
22
|
+
const widthItem = (widthSpan ?? numberOfColumns) as SpanNumber;
|
|
23
|
+
const _renderItem = (item: any) => {
|
|
24
|
+
return <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<SectionList
|
|
29
|
+
{...props}
|
|
30
|
+
renderItem={_renderItem}
|
|
31
|
+
horizontal={false}
|
|
32
|
+
ItemSeparatorComponent={() => <View style={{height: gutterSize}} />}
|
|
33
|
+
style={[style, styles.protectedStyle]}
|
|
34
|
+
contentContainerStyle={[contentContainerStyle, styles.protectedStyle]}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default ItemSectionList;
|