@momo-kits/foundation 0.75.1-beta.10

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 (76) hide show
  1. package/Assets/header-background.png +0 -0
  2. package/Assets/icon.json +3947 -0
  3. package/Button/index.tsx +278 -0
  4. package/Button/styles.ts +41 -0
  5. package/CheckBox/index.tsx +61 -0
  6. package/CheckBox/styles.ts +15 -0
  7. package/CheckBox/types.ts +38 -0
  8. package/Consts/colors+spacing+radius.ts +214 -0
  9. package/Consts/index.ts +4 -0
  10. package/Consts/styles.ts +78 -0
  11. package/Consts/theme.ts +121 -0
  12. package/Divider/index.tsx +19 -0
  13. package/Icon/index.tsx +37 -0
  14. package/Icon/types.ts +27 -0
  15. package/IconButton/index.tsx +140 -0
  16. package/IconButton/styles.ts +19 -0
  17. package/Image/index.tsx +80 -0
  18. package/Image/styles.ts +13 -0
  19. package/Image/types.ts +3 -0
  20. package/Input/Input.tsx +136 -0
  21. package/Input/InputMoney.tsx +132 -0
  22. package/Input/InputSearch.tsx +161 -0
  23. package/Input/InputTextArea.tsx +152 -0
  24. package/Input/common.tsx +118 -0
  25. package/Input/index.tsx +96 -0
  26. package/Input/styles.ts +122 -0
  27. package/Input/utils.ts +69 -0
  28. package/Layout/Card.tsx +141 -0
  29. package/Layout/GridSystem.tsx +124 -0
  30. package/Layout/Item.tsx +60 -0
  31. package/Layout/ScreenContainer.tsx +121 -0
  32. package/Layout/Section.tsx +141 -0
  33. package/Layout/index.ts +17 -0
  34. package/Layout/types.ts +59 -0
  35. package/Layout/utils.ts +60 -0
  36. package/Navigation/BottomTab.tsx +39 -0
  37. package/Navigation/Components.tsx +365 -0
  38. package/Navigation/ModalScreen.tsx +226 -0
  39. package/Navigation/Navigation.ts +44 -0
  40. package/Navigation/NavigationButton.tsx +54 -0
  41. package/Navigation/NavigationContainer.tsx +77 -0
  42. package/Navigation/Navigator.ts +82 -0
  43. package/Navigation/StackScreen.tsx +27 -0
  44. package/Navigation/index.ts +14 -0
  45. package/Navigation/types.ts +158 -0
  46. package/Navigation/utils.tsx +138 -0
  47. package/Pagination/Dot.tsx +16 -0
  48. package/Pagination/PaginationDot.tsx +33 -0
  49. package/Pagination/PaginationNumber.tsx +23 -0
  50. package/Pagination/PaginationScroll.tsx +88 -0
  51. package/Pagination/PaginationWhiteDot.tsx +32 -0
  52. package/Pagination/index.tsx +25 -0
  53. package/Pagination/styles.ts +47 -0
  54. package/Pagination/types.ts +38 -0
  55. package/Popup/PopupNotify.tsx +215 -0
  56. package/Popup/PopupPromotion.tsx +77 -0
  57. package/Popup/index.tsx +4 -0
  58. package/Popup/types.ts +70 -0
  59. package/Radio/index.tsx +65 -0
  60. package/Radio/styles.ts +11 -0
  61. package/Radio/types.ts +38 -0
  62. package/Skeleton/index.tsx +72 -0
  63. package/Skeleton/styles.ts +5 -0
  64. package/Skeleton/types.ts +3 -0
  65. package/Switch/index.tsx +40 -0
  66. package/Switch/styles.ts +23 -0
  67. package/Switch/types.ts +26 -0
  68. package/Tag/index.tsx +79 -0
  69. package/Tag/styles.ts +24 -0
  70. package/Tag/types.ts +36 -0
  71. package/Text/index.tsx +123 -0
  72. package/Text/styles.ts +35 -0
  73. package/Text/types.ts +40 -0
  74. package/index.ts +38 -0
  75. package/package.json +41 -0
  76. package/publish.sh +26 -0
@@ -0,0 +1,141 @@
1
+ import React from 'react';
2
+ import {Dimensions, View} from 'react-native';
3
+ import {validateChildren} from './utils';
4
+ import {GridContextProps, SectionProps} from './types';
5
+ import {GridContext} from './index';
6
+ import {GRIDVIEW} from '../Consts';
7
+ import Item from './Item';
8
+
9
+ const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
10
+ const numberOfColumns = 12;
11
+ const gutterSize = 12;
12
+ let margin = 0;
13
+ if (useMargin) {
14
+ margin = 12;
15
+ }
16
+ let widthSection = Dimensions.get('window').width;
17
+ if (useMargin) widthSection = widthSection - margin * 2;
18
+ const totalGutterSize = gutterSize * (numberOfColumns - 1);
19
+ const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
20
+
21
+ const gridContext: GridContextProps = {
22
+ numberOfColumns,
23
+ gutterSize,
24
+ margin,
25
+ sizePerSpan,
26
+ getSizeSpan: span => {
27
+ return span * sizePerSpan + (span - 1) * gutterSize;
28
+ },
29
+ };
30
+
31
+ /**
32
+ * render overlay only dev mode
33
+ */
34
+ const renderOverlay = () => {
35
+ return (
36
+ <View
37
+ pointerEvents={'none'}
38
+ style={{
39
+ position: 'absolute',
40
+ top: 0,
41
+ bottom: 0,
42
+ left: 0,
43
+ right: 0,
44
+ borderColor: 'red',
45
+ borderWidth: 1,
46
+ }}
47
+ />
48
+ );
49
+ };
50
+
51
+ /**
52
+ * build a row view in side session
53
+ * @param rows
54
+ * @param cursor
55
+ * @param endRow
56
+ */
57
+ const addRowView = (
58
+ rows: any[],
59
+ cursor: number = 0,
60
+ endRow: boolean = false,
61
+ ) => {
62
+ return (
63
+ <View
64
+ key={`Card${cursor}`}
65
+ style={{
66
+ flexDirection: 'row',
67
+ marginBottom: endRow ? 0 : gridContext.gutterSize,
68
+ }}>
69
+ {rows.map((i: React.ReactElement, index: number) => {
70
+ return (
71
+ <View key={`Card${cursor}${index}`} style={{flexDirection: 'row'}}>
72
+ {index != 0 && (
73
+ <View style={{width: gridContext.gutterSize}}></View>
74
+ )}
75
+ {i}
76
+ </View>
77
+ );
78
+ })}
79
+ </View>
80
+ );
81
+ };
82
+
83
+ /**
84
+ * render children content for session
85
+ * @param children
86
+ */
87
+ const renderView = (
88
+ children: any,
89
+ ): React.ReactElement | React.ReactElement[] => {
90
+ const element: React.ReactElement | React.ReactElement[] = [];
91
+ if (Array.isArray(children)) {
92
+ let cursor = 0;
93
+ let rows: any[] = [];
94
+ for (let i = 0; i < children.length; ++i) {
95
+ const item = children[i];
96
+ const totalSpan = rows
97
+ .concat([item])
98
+ .map(i => i.props?.widthSpan)
99
+ .reduce((previousValue, currentValue) => {
100
+ return previousValue + currentValue;
101
+ });
102
+
103
+ if (totalSpan <= gridContext.numberOfColumns) {
104
+ rows.push(item);
105
+ } else {
106
+ cursor += 1;
107
+ element.push(addRowView(rows, cursor));
108
+ rows = [item];
109
+ }
110
+
111
+ if (i == children.length - 1) {
112
+ cursor += 1;
113
+ element.push(addRowView(rows, cursor, true));
114
+ }
115
+ }
116
+ } else {
117
+ element.push(children);
118
+ }
119
+ return element;
120
+ };
121
+
122
+ return (
123
+ <GridContext.Provider value={gridContext}>
124
+ <View
125
+ accessibilityLabel={`Section`}
126
+ style={{
127
+ width: widthSection,
128
+ marginHorizontal: gridContext.margin,
129
+ flexDirection: 'row',
130
+ flexWrap: 'wrap',
131
+ }}>
132
+ {renderView(validateChildren(children, [Item]))}
133
+ {GRIDVIEW && renderOverlay()}
134
+ </View>
135
+ </GridContext.Provider>
136
+ );
137
+ };
138
+
139
+ Section.displayName = 'Section';
140
+
141
+ export default Section;
@@ -0,0 +1,17 @@
1
+ import Card from './Card';
2
+ import Section from './Section';
3
+ import GridSystem from './GridSystem';
4
+ import {validateChildren} from './utils';
5
+ import {createContext} from 'react';
6
+ import {GridContextProps} from './types';
7
+ import Item from './Item';
8
+
9
+ const GridContext = createContext<GridContextProps>({
10
+ numberOfColumns: 12,
11
+ gutterSize: 12,
12
+ margin: 12,
13
+ sizePerSpan: 0,
14
+ getSizeSpan: span => 0,
15
+ });
16
+
17
+ export {GridContext, Card, Section, GridSystem, validateChildren, Item};
@@ -0,0 +1,59 @@
1
+ import {ViewProps} from 'react-native';
2
+
3
+ type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
4
+
5
+ export type GridContextProps = {
6
+ /**
7
+ * Represents the number of columns in the grid.
8
+ */
9
+ numberOfColumns: number;
10
+
11
+ /**
12
+ * Represents the size of the gutter between grid items.
13
+ */
14
+ gutterSize: number;
15
+
16
+ /**
17
+ * Optional. Represents the margin around the grid.
18
+ */
19
+ margin?: number;
20
+
21
+ /**
22
+ * Represents the size (width or height) per span number.
23
+ */
24
+ sizePerSpan: number;
25
+
26
+ /**
27
+ * A function that receives a span number and returns the calculated size for that span.
28
+ */
29
+ getSizeSpan: (span: number) => number;
30
+ };
31
+ export interface SectionProps extends ViewProps {
32
+ /**
33
+ * Optional. If `true`, the Section component will be displayed in an expanded state.
34
+ * Defaults to `false` if not provided.
35
+ */
36
+ expanded?: boolean;
37
+
38
+ /**
39
+ * Optional. If `true`, margin will be applied to the Section component.
40
+ * Defaults to `false` if not provided.
41
+ */
42
+ useMargin?: boolean;
43
+ }
44
+
45
+ export interface ItemProps extends ViewProps {
46
+ /**
47
+ * Represents the width of the Card component in terms of span numbers (1-12).
48
+ */
49
+ widthSpan: SpanNumber;
50
+
51
+ /**
52
+ * Optional. Represents the height of the Card component in terms of span numbers (1-12).
53
+ */
54
+ heightSpan?: SpanNumber;
55
+ }
56
+
57
+ export interface CardProps extends ViewProps {
58
+ background?: string;
59
+ }
@@ -0,0 +1,60 @@
1
+ import {Alert} from 'react-native';
2
+ import React, {ReactElement} from 'react';
3
+ import {SectionProps} from './types';
4
+
5
+ /**
6
+ * validate children type
7
+ * @param children
8
+ * @param childrenTypes
9
+ */
10
+ const validateChildren = (
11
+ children:
12
+ | React.ReactElement<any, string | React.JSXElementConstructor<any>>
13
+ | string
14
+ | number
15
+ | {}
16
+ | Iterable<React.ReactNode>
17
+ | React.ReactPortal
18
+ | null
19
+ | undefined
20
+ | boolean,
21
+ childrenTypes: Array<React.FC<any>>,
22
+ ) => {
23
+ if (!__DEV__) return children;
24
+
25
+ let results: React.ReactElement[] = [];
26
+ const validateType = (child: React.ReactElement) => {
27
+ return childrenTypes.some(childrenType => child?.type === childrenType);
28
+ };
29
+
30
+ const alertWrongType = () => {
31
+ Alert.alert(
32
+ 'Component Kits',
33
+ `Wrong children type for this component, expected are ${childrenTypes
34
+ .map(type => type.displayName)
35
+ .join(', ')}.`,
36
+ );
37
+ };
38
+
39
+ if (Array.isArray(children)) {
40
+ const flattenChildren = children.flat();
41
+ results = flattenChildren.filter((child: React.ReactElement) => {
42
+ if (validateType(child)) {
43
+ return child;
44
+ } else {
45
+ alertWrongType();
46
+ }
47
+ });
48
+ } else {
49
+ const singleChild: any = children;
50
+ if (validateType(singleChild)) {
51
+ results = [singleChild];
52
+ } else {
53
+ alertWrongType();
54
+ }
55
+ }
56
+
57
+ return results;
58
+ };
59
+
60
+ export {validateChildren};
@@ -0,0 +1,39 @@
1
+ import React, {FC} from 'react';
2
+ import {BottomTabProps} from './types';
3
+ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
4
+ import {Icon} from '../Icon';
5
+
6
+ const Tab = createBottomTabNavigator();
7
+
8
+ const BottomTab: FC<BottomTabProps> = ({tabs}) => {
9
+ return (
10
+ <Tab.Navigator>
11
+ {tabs.map((item, index) => {
12
+ return (
13
+ <Tab.Screen
14
+ key={`${item.label}-${index}`}
15
+ name={item.label}
16
+ component={item.screen}
17
+ options={{
18
+ tabBarLabel: item.label,
19
+ tabBarBadge: item?.badgeLabel,
20
+ tabBarBadgeStyle: {
21
+ borderColor: 'white',
22
+ borderWidth: 2,
23
+ fontSize: 10,
24
+ lineHeight: 14,
25
+ fontWeight: 'bold',
26
+ alignSelf: 'center',
27
+ },
28
+ tabBarIcon: ({color, size}) => (
29
+ <Icon source={item.icon} color={color} size={size} />
30
+ ),
31
+ }}
32
+ />
33
+ );
34
+ })}
35
+ </Tab.Navigator>
36
+ );
37
+ };
38
+
39
+ export default BottomTab;
@@ -0,0 +1,365 @@
1
+ import React, {useContext, useEffect, useState} from 'react';
2
+ import {
3
+ Animated,
4
+ DeviceEventEmitter,
5
+ StatusBar,
6
+ StyleSheet,
7
+ TouchableOpacity,
8
+ View,
9
+ } from 'react-native';
10
+ import {ApplicationContext, NavigationButton} from './index';
11
+ import {Colors, Radius, Spacing, Styles} from '../Consts';
12
+ import {Image} from '../Image';
13
+ import {
14
+ HeaderBackgroundProps,
15
+ HeaderBackProps,
16
+ HeaderToolkitProps,
17
+ TitleCustomProps,
18
+ } from './types';
19
+ import {Text} from '../Text';
20
+ import {Icon} from '../Icon';
21
+ import {PopupNotify} from '../Popup';
22
+
23
+ const styles = StyleSheet.create({
24
+ headerBackground: {
25
+ width: '100%',
26
+ height: undefined,
27
+ position: 'absolute',
28
+ aspectRatio: 375 / 154,
29
+ },
30
+ headerTitleContainer: {
31
+ alignItems: 'center',
32
+ justifyContent: 'center',
33
+ width: '100%',
34
+ },
35
+ circle: {width: 36, height: 36, borderRadius: 18},
36
+ square: {width: 36, height: 36, borderRadius: Radius.XS},
37
+ dotAvatar: {
38
+ position: 'absolute',
39
+ width: 12,
40
+ height: 12,
41
+ borderRadius: 6,
42
+ bottom: 0,
43
+ right: 0,
44
+ borderWidth: 1,
45
+ borderColor: Colors.black_01,
46
+ },
47
+ headerRightButton: {
48
+ flexDirection: 'row',
49
+ overflow: 'hidden',
50
+ justifyContent: 'center',
51
+ alignItems: 'center',
52
+ paddingRight: Spacing.M,
53
+ },
54
+ toolkitContainer: {
55
+ marginLeft: Spacing.S,
56
+ padding: Spacing.XS,
57
+ height: 28,
58
+ borderRadius: 14,
59
+ borderColor: '#00000066',
60
+ justifyContent: 'center',
61
+ alignItems: 'center',
62
+ flexDirection: 'row',
63
+ },
64
+ divider: {
65
+ width: 1,
66
+ height: 12,
67
+ marginHorizontal: 4,
68
+ },
69
+ headerLeft: {
70
+ marginLeft: 12,
71
+ },
72
+ title: {fontSize: 15, lineHeight: 22, fontWeight: 'bold'},
73
+ });
74
+
75
+ const HeaderTitle: React.FC<any> = props => {
76
+ const {theme} = useContext(ApplicationContext);
77
+ const opacity = props.animatedValue?.interpolate({
78
+ inputRange: [0, 200],
79
+ outputRange: [0, 1],
80
+ extrapolate: 'clamp',
81
+ });
82
+ return (
83
+ <Animated.Text
84
+ {...props}
85
+ accessibilityLabel={`HeaderTitle/${props.children}`}
86
+ style={[
87
+ styles.title,
88
+ {fontFamily: `${theme.font}-Bold`, opacity, color: props.tintColor},
89
+ ]}
90
+ />
91
+ );
92
+ };
93
+
94
+ const HeaderLeft: React.FC<HeaderBackProps> = ({
95
+ tintColor,
96
+ preventBack,
97
+ useBorder,
98
+ backgroundColor,
99
+ }) => {
100
+ const {navigator} = useContext(ApplicationContext);
101
+ const goBack = () => {
102
+ const canGoBack = navigator?.ref.current?.canGoBack();
103
+ if (canGoBack) {
104
+ if (preventBack) {
105
+ navigator?.showModal({
106
+ screen: () => (
107
+ <PopupNotify
108
+ {...preventBack}
109
+ primary={{
110
+ title: preventBack.primary.title,
111
+ onPress: () => {
112
+ preventBack?.primary.onPress();
113
+ navigator?.ref.current?.goBack();
114
+ },
115
+ }}
116
+ />
117
+ ),
118
+ });
119
+ } else {
120
+ navigator?.ref.current?.goBack();
121
+ }
122
+ } else {
123
+ const currentTime = new Date().getTime();
124
+ const requestId = `navigationBackPress#${currentTime}`;
125
+ DeviceEventEmitter.emit('dismiss', {requestId});
126
+ }
127
+ };
128
+
129
+ return (
130
+ <View style={styles.headerLeft}>
131
+ <NavigationButton
132
+ icon="ic_back"
133
+ tintColor={tintColor}
134
+ onPress={goBack}
135
+ accessibilityLabel={'Back'}
136
+ useBorder={useBorder}
137
+ backgroundColor={backgroundColor}
138
+ />
139
+ </View>
140
+ );
141
+ };
142
+
143
+ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
144
+ image,
145
+ backgroundColor,
146
+ animatedValue,
147
+ useBorder = false,
148
+ }) => {
149
+ const {theme} = useContext(ApplicationContext);
150
+ let headerImage = theme.assets?.headerBackground;
151
+ if (image === null) {
152
+ headerImage = undefined;
153
+ }
154
+ const opacity = animatedValue?.interpolate({
155
+ inputRange: [0, 200],
156
+ outputRange: [0, 1],
157
+ extrapolate: 'clamp',
158
+ });
159
+
160
+ return (
161
+ <Animated.View
162
+ style={[
163
+ Styles.flex,
164
+ {
165
+ backgroundColor: backgroundColor ?? theme.colors.background.default,
166
+ overflow: 'hidden',
167
+ borderBottomWidth: useBorder ? 1 : 0,
168
+ borderColor: theme.colors.border.default,
169
+ opacity,
170
+ },
171
+ ]}>
172
+ <StatusBar
173
+ barStyle={headerImage || theme.dark ? 'light-content' : 'dark-content'}
174
+ />
175
+ {!!headerImage && (
176
+ <Image style={styles.headerBackground} source={{uri: headerImage}} />
177
+ )}
178
+ </Animated.View>
179
+ );
180
+ };
181
+
182
+ const HeaderCustom: React.FC<TitleCustomProps> = ({
183
+ title,
184
+ subTitle,
185
+ image,
186
+ imageShape = 'circle',
187
+ content,
188
+ tintColor,
189
+ dotColor,
190
+ }) => {
191
+ const avatarStyle = imageShape == 'circle' ? styles.circle : styles.square;
192
+ const header = (
193
+ <View style={Styles.row}>
194
+ <View>
195
+ <Image source={{uri: image}} style={avatarStyle} />
196
+ {!!dotColor && (
197
+ <View style={[styles.dotAvatar, {backgroundColor: dotColor}]} />
198
+ )}
199
+ </View>
200
+ <View style={[Styles.flex, Styles.paddingHorizontal8]}>
201
+ <Text typography="title_xs" color={tintColor}>
202
+ {title}
203
+ </Text>
204
+ <Text typography="description_s" color={tintColor}>
205
+ {subTitle}
206
+ </Text>
207
+ </View>
208
+ </View>
209
+ );
210
+ return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
211
+ };
212
+
213
+ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
214
+ const validType = (item: any) => {
215
+ if (item.type !== NavigationButton) {
216
+ console.warn(
217
+ 'element type of NavigationButton, Please migrate to use NavigationButton of kits.',
218
+ );
219
+ return <View />;
220
+ }
221
+ };
222
+ const renderAction = () => {
223
+ if (Array.isArray(children)) {
224
+ return children.map((child, index) => {
225
+ if (__DEV__) {
226
+ validType(child);
227
+ }
228
+ return (
229
+ <React.Fragment key={index}>
230
+ {React.cloneElement(child, {...restProps})}
231
+ </React.Fragment>
232
+ );
233
+ });
234
+ }
235
+
236
+ validType(children);
237
+ return React.cloneElement(children, {...restProps});
238
+ };
239
+ return <View style={styles.headerRightButton}>{renderAction()}</View>;
240
+ };
241
+
242
+ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
243
+ const {theme, navigator} = useContext(ApplicationContext);
244
+ const [toolConfig, setToolConfig] = useState<HeaderToolkitProps>();
245
+ const {appCode, hidden, type, onAction} = toolConfig ?? {};
246
+
247
+ let backgroundColor;
248
+ if (tintColor != Colors.black_01) {
249
+ backgroundColor = theme.colors.background.surface;
250
+ }
251
+
252
+ useEffect(() => {
253
+ navigator?.getToolkit().then(toolConfig => {
254
+ setToolConfig(toolConfig);
255
+ });
256
+ }, []);
257
+
258
+ useEffect(() => {
259
+ let addFavorite: any;
260
+ let removeFavorite: any;
261
+ if (appCode) {
262
+ const addSchema = `observerToolkit_addFavorite_${appCode}`;
263
+ const removeSchema = `observerToolkit_removeFavorite_${appCode}`;
264
+ addFavorite = navigator?.requestApi(
265
+ 'observer',
266
+ [addSchema],
267
+ (data: any) => {
268
+ if (data?.status) {
269
+ setToolConfig({
270
+ ...(toolConfig as HeaderToolkitProps),
271
+ hidden: true,
272
+ });
273
+ }
274
+ },
275
+ );
276
+ addFavorite = navigator?.requestApi(
277
+ 'observer',
278
+ [removeSchema],
279
+ (data: any) => {
280
+ if (data?.status) {
281
+ setToolConfig({
282
+ ...(toolConfig as HeaderToolkitProps),
283
+ hidden: false,
284
+ });
285
+ }
286
+ },
287
+ );
288
+ }
289
+
290
+ return () => {
291
+ addFavorite?.();
292
+ removeFavorite?.();
293
+ };
294
+ }, [appCode]);
295
+
296
+ const onUtilityTool = () => {
297
+ onAction?.('onUtilityTool');
298
+ navigator?.requestApi(type, undefined, undefined);
299
+ };
300
+
301
+ const onMore = () => {
302
+ onAction?.('onMore');
303
+ navigator?.requestApi('showToolkit', [toolConfig], undefined);
304
+ };
305
+
306
+ const onClose = () => {
307
+ onAction?.('onClose');
308
+ navigator?.requestApi('dismiss', undefined, undefined);
309
+ };
310
+
311
+ const renderUtilityTool = () => {
312
+ if (toolConfig?.hidden === false) {
313
+ return (
314
+ <NavigationButton
315
+ icon={type as string}
316
+ tintColor={tintColor}
317
+ onPress={onUtilityTool}
318
+ />
319
+ );
320
+ }
321
+ };
322
+
323
+ if (toolConfig) {
324
+ return (
325
+ <View style={styles.headerRightButton}>
326
+ {renderUtilityTool()}
327
+ <View
328
+ style={[
329
+ styles.toolkitContainer,
330
+ {
331
+ backgroundColor: backgroundColor ?? '#00000066',
332
+ borderWidth: backgroundColor ? 0.5 : 0,
333
+ },
334
+ ]}>
335
+ <TouchableOpacity
336
+ accessibilityLabel={'Toolkit/More'}
337
+ onPress={onMore}>
338
+ <Icon color={tintColor} source="navigation_more_horiz" size={20} />
339
+ </TouchableOpacity>
340
+ <View style={[styles.divider, {backgroundColor: tintColor}]} />
341
+ <TouchableOpacity
342
+ accessibilityLabel={'Toolkit/Close'}
343
+ onPress={onClose}>
344
+ <Icon
345
+ color={tintColor}
346
+ source="16_navigation_close_circle"
347
+ size={20}
348
+ />
349
+ </TouchableOpacity>
350
+ </View>
351
+ </View>
352
+ );
353
+ }
354
+
355
+ return <View />;
356
+ };
357
+
358
+ export {
359
+ HeaderTitle,
360
+ HeaderLeft,
361
+ HeaderBackground,
362
+ HeaderRightAction,
363
+ HeaderToolkitAction,
364
+ HeaderCustom,
365
+ };