@momo-kits/foundation 0.89.5 → 0.89.6-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/Application/BottomSheet.tsx +216 -0
  2. package/Application/BottomTab/BottomTabBar.tsx +278 -0
  3. package/Application/{BottomTab.tsx → BottomTab/index.tsx} +42 -18
  4. package/Application/Components.tsx +350 -86
  5. package/Application/Localize.ts +44 -0
  6. package/Application/ModalScreen.tsx +14 -185
  7. package/Application/Navigation.ts +5 -19
  8. package/Application/NavigationContainer.tsx +62 -72
  9. package/Application/Navigator.ts +53 -35
  10. package/Application/StackScreen.tsx +289 -32
  11. package/Application/index.ts +13 -15
  12. package/Application/types.ts +64 -35
  13. package/Application/utils.tsx +76 -30
  14. package/Assets/icon_bank.json +1 -1
  15. package/Badge/Badge.tsx +1 -1
  16. package/Badge/BadgeDotAnimation.tsx +95 -0
  17. package/Badge/index.tsx +2 -1
  18. package/Badge/styles.ts +50 -6
  19. package/Button/index.tsx +44 -26
  20. package/CheckBox/index.tsx +37 -26
  21. package/CheckBox/types.ts +5 -3
  22. package/Consts/colors+spacing+radius.ts +14 -0
  23. package/Icon/index.tsx +9 -8
  24. package/Icon/types.ts +2 -2
  25. package/IconButton/index.tsx +24 -14
  26. package/Image/index.tsx +23 -8
  27. package/Image/types.ts +2 -0
  28. package/Input/Input.tsx +116 -26
  29. package/Input/InputDropDown.tsx +66 -51
  30. package/Input/InputMoney.tsx +106 -15
  31. package/Input/InputOTP.tsx +49 -26
  32. package/Input/InputSearch.tsx +252 -99
  33. package/Input/InputTextArea.tsx +26 -6
  34. package/Input/TextTyping.tsx +113 -0
  35. package/Input/common.tsx +48 -22
  36. package/Input/index.tsx +112 -77
  37. package/Input/styles.ts +48 -11
  38. package/Input/utils.ts +1 -1
  39. package/Layout/Card.tsx +4 -3
  40. package/Layout/FloatingButton.tsx +168 -0
  41. package/Layout/GridSystem.tsx +1 -1
  42. package/Layout/ItemList.tsx +3 -2
  43. package/Layout/Screen.tsx +242 -121
  44. package/Layout/Section.tsx +4 -3
  45. package/Layout/styles.ts +11 -13
  46. package/Layout/types.ts +1 -1
  47. package/Layout/utils.ts +4 -4
  48. package/Loader/index.tsx +2 -0
  49. package/Pagination/PaginationScroll.tsx +2 -2
  50. package/Pagination/styles.ts +1 -1
  51. package/Popup/PopupNotify.tsx +56 -45
  52. package/Popup/PopupPromotion.tsx +5 -7
  53. package/Popup/types.ts +1 -7
  54. package/Radio/index.tsx +35 -20
  55. package/Radio/types.ts +5 -3
  56. package/Switch/index.tsx +32 -18
  57. package/Switch/types.ts +5 -3
  58. package/Tag/index.tsx +9 -2
  59. package/Tag/styles.ts +3 -2
  60. package/Tag/types.ts +12 -0
  61. package/Text/index.tsx +24 -5
  62. package/Text/styles.ts +8 -8
  63. package/Text/types.ts +19 -1
  64. package/Title/index.tsx +170 -103
  65. package/Title/styles.ts +36 -9
  66. package/Title/types.ts +16 -48
  67. package/code-scanner.js +125 -16
  68. package/index.ts +7 -0
  69. package/migrate_typo.js +56 -0
  70. package/package.json +11 -10
  71. package/publish.sh +16 -21
  72. package/tsconfig.json +1 -1
  73. package/verify.js +37 -40
@@ -1,14 +1,17 @@
1
1
  import React, {
2
- Fragment,
2
+ Ref,
3
3
  useCallback,
4
4
  useContext,
5
5
  useEffect,
6
+ useRef,
6
7
  useState,
7
8
  } from 'react';
8
9
  import {
10
+ Alert,
9
11
  Animated,
10
12
  BackHandler,
11
13
  DeviceEventEmitter,
14
+ Dimensions,
12
15
  StatusBar,
13
16
  StyleSheet,
14
17
  TouchableOpacity,
@@ -29,7 +32,18 @@ import {scaleSize, Text} from '../Text';
29
32
  import {Icon} from '../Icon';
30
33
  import {PopupNotify} from '../Popup';
31
34
  import {Badge, BadgeDot} from '../Badge';
32
-
35
+ import {HeaderType} from '../Layout/types';
36
+ import Navigation from './Navigation';
37
+ import {InputRef, InputSearch, InputSearchProps} from '../Input';
38
+ import {BadgeDotAnimation} from '../Badge';
39
+
40
+ const SCREEN_PADDING = 12;
41
+ const BACK_WIDTH = 28;
42
+ const {width: screenWidth} = Dimensions.get('window');
43
+
44
+ /**
45
+ * default navigation button used header nav
46
+ */
33
47
  const NavigationButton: React.FC<NavigationButtonProps> = ({
34
48
  icon,
35
49
  tintColor,
@@ -37,10 +51,11 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
37
51
  useBorder = true,
38
52
  badgeType,
39
53
  badgeValue,
54
+ accessibilityLabel = '',
40
55
  }) => {
41
56
  const {theme} = useContext(ApplicationContext);
42
57
  let buttonStyle: ViewStyle = {backgroundColor: '#00000066'};
43
- if (tintColor != Colors.black_01) {
58
+ if (tintColor !== Colors.black_01) {
44
59
  buttonStyle = {
45
60
  backgroundColor: 'transparent',
46
61
  borderColor: '#00000066',
@@ -57,6 +72,11 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
57
72
  if (badgeType === 'dot') {
58
73
  return <BadgeDot size="small" style={styles.badgeDot} />;
59
74
  }
75
+ if (badgeType === 'dot-animation') {
76
+ return (
77
+ <BadgeDotAnimation size="small" style={styles.badgeDotAnimation} />
78
+ );
79
+ }
60
80
 
61
81
  if (isNumber(badgeValue)) {
62
82
  return <Badge label={badgeValue} style={styles.badge} />;
@@ -64,8 +84,9 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
64
84
  }, [badgeType, badgeValue]);
65
85
 
66
86
  return (
67
- <View style={{width: scaleSize(28)}}>
87
+ <View style={{width: 28}}>
68
88
  <TouchableOpacity
89
+ accessibilityLabel={accessibilityLabel}
69
90
  style={[styles.navigationButton, buttonStyle]}
70
91
  onPress={onPress}>
71
92
  <Icon
@@ -79,17 +100,23 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
79
100
  );
80
101
  };
81
102
 
103
+ /**
104
+ * default header title used for nav
105
+ */
82
106
  const HeaderTitle: React.FC<any> = props => {
83
107
  const {theme} = useContext(ApplicationContext);
84
- const opacity = props.animatedValue?.interpolate({
85
- inputRange: [0, 200],
86
- outputRange: [0, 1],
87
- extrapolate: 'clamp',
88
- });
108
+ const opacity = props.animatedValue?.interpolate(
109
+ props.interpolate ?? {
110
+ inputRange: [0, 200],
111
+ outputRange: [0, 1],
112
+ extrapolate: 'clamp',
113
+ }
114
+ );
89
115
 
90
116
  return (
91
117
  <Animated.Text
92
118
  {...props}
119
+ accessibilityLabel={'title_navigation_header'}
93
120
  style={[
94
121
  styles.title,
95
122
  {fontFamily: `${theme.font}-Bold`, opacity, color: props.tintColor},
@@ -98,19 +125,22 @@ const HeaderTitle: React.FC<any> = props => {
98
125
  );
99
126
  };
100
127
 
128
+ /**
129
+ * default header left used for nav
130
+ */
101
131
  const HeaderLeft: React.FC<HeaderBackProps> = ({
102
132
  tintColor,
103
133
  preventBack,
104
134
  onPressLeftHeader,
105
135
  useBorder,
106
136
  }) => {
107
- const context = useContext(MiniAppContext);
137
+ const context = useContext<any>(MiniAppContext);
108
138
  const {navigator} = useContext(ApplicationContext);
109
139
 
110
140
  useEffect(() => {
111
141
  const backHandler = BackHandler.addEventListener(
112
142
  'hardwareBackPress',
113
- goBackSafe,
143
+ goBackSafe
114
144
  );
115
145
 
116
146
  return () => backHandler.remove();
@@ -118,20 +148,25 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
118
148
 
119
149
  const goBackSafe = () => {
120
150
  const goBack = () => {
121
- const canGoBack = navigator?.ref.current?.canGoBack();
122
- if (!canGoBack) {
123
- const currentRoute = navigator?.ref?.current.getCurrentRoute();
124
- navigator?.maxApi?.trackEvent?.('service_icon_clicked', {
125
- ...context,
126
- screen_name: currentRoute?.params?.screen?.name ?? currentRoute?.name,
127
- trigger_id: '111154000000000000',
128
- icon_name: 'back',
129
- });
130
- }
151
+ const canGoBack = navigator?.ref?.current?.canGoBack?.();
152
+ const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
153
+ const params = {
154
+ appId: context.appId,
155
+ code: context.code,
156
+ screen_name: currentRoute?.params?.screen?.name ?? currentRoute?.name,
157
+ trigger_id: '111154000000000000',
158
+ icon_name: 'back',
159
+ };
160
+ navigator?.maxApi?.showToastDebug?.({
161
+ appId: `auto - ${context.appId}`,
162
+ message: 'service_icon_clicked',
163
+ params,
164
+ });
165
+ navigator?.maxApi?.trackEvent?.('service_icon_clicked', params);
131
166
  if (canGoBack) {
132
- navigator?.ref.current?.goBack();
167
+ navigator?.ref?.current?.goBack?.();
133
168
  } else if (navigator?.maxApi) {
134
- navigator?.maxApi?.dismiss(navigator.dismissData);
169
+ navigator?.maxApi?.dismiss?.(navigator?.dismissData);
135
170
  } else {
136
171
  const currentTime = new Date().getTime();
137
172
  const requestId = `navigationBackPress#${currentTime}`;
@@ -164,6 +199,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
164
199
  return (
165
200
  <View style={styles.headerLeft}>
166
201
  <NavigationButton
202
+ accessibilityLabel="btn_navigation_back"
167
203
  icon="ic_back"
168
204
  tintColor={tintColor}
169
205
  onPress={goBackSafe}
@@ -173,17 +209,23 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
173
209
  );
174
210
  };
175
211
 
212
+ /**
213
+ * header background for default
214
+ */
176
215
  const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
177
216
  image,
178
- backgroundColor,
179
217
  animatedValue,
180
- useBorder = false,
218
+ useSurface = false,
181
219
  }) => {
182
220
  const {theme} = useContext(ApplicationContext);
183
221
  let headerImage = theme.assets?.headerBackground;
222
+ let backgroundColor;
184
223
  if (image === null) {
185
224
  headerImage = undefined;
186
225
  }
226
+ if (useSurface) {
227
+ backgroundColor = theme.colors.background.surface;
228
+ }
187
229
  const opacity = animatedValue?.interpolate({
188
230
  inputRange: [0, 114],
189
231
  outputRange: [0, 1],
@@ -195,9 +237,9 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
195
237
  style={[
196
238
  Styles.flex,
197
239
  {
198
- backgroundColor: backgroundColor ?? theme.colors.background.default,
240
+ backgroundColor,
199
241
  overflow: 'hidden',
200
- borderBottomWidth: useBorder ? 1 : 0,
242
+ borderBottomWidth: useSurface ? 1 : 0,
201
243
  borderColor: theme.colors.border.default,
202
244
  opacity,
203
245
  },
@@ -218,6 +260,10 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
218
260
  );
219
261
  };
220
262
 
263
+ /**
264
+ * Header custom with image, title, subtitle
265
+ * @constructor
266
+ */
221
267
  const HeaderCustom: React.FC<TitleCustomProps> = ({
222
268
  title,
223
269
  subTitle,
@@ -227,7 +273,7 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
227
273
  tintColor,
228
274
  dotColor,
229
275
  }) => {
230
- const avatarStyle = imageShape == 'circle' ? styles.circle : styles.square;
276
+ const avatarStyle = imageShape === 'circle' ? styles.circle : styles.square;
231
277
  const header = (
232
278
  <View style={Styles.row}>
233
279
  <View>
@@ -237,7 +283,10 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
237
283
  )}
238
284
  </View>
239
285
  <View style={[Styles.flex, {paddingHorizontal: 8}]}>
240
- <Text typography="header_default_bold" color={tintColor}>
286
+ <Text
287
+ accessibilityLabel={'title_navigation_header'}
288
+ typography="header_default_bold"
289
+ color={tintColor}>
241
290
  {title}
242
291
  </Text>
243
292
  <Text typography="description_default_regular" color={tintColor}>
@@ -249,51 +298,56 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
249
298
  return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
250
299
  };
251
300
 
252
- const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
253
- const validateType = (child: React.ReactElement) => {
254
- const valid = child?.type === NavigationButton || child?.type == Fragment;
255
- if (__DEV__ && !valid) {
256
- console.warn(
257
- 'HeaderRightAction contains element type of NavigationButton, Please check again.',
258
- );
301
+ /**
302
+ * main component for header right
303
+ */
304
+ const HeaderRight: React.FC<any> = ({type, children, onLayout, ...props}) => {
305
+ if (type === 'icon') {
306
+ let buttons = props?.buttons || [];
307
+ if (buttons?.length > 3) {
308
+ buttons = buttons.slice(0, 3);
259
309
  }
260
- return child;
261
- };
262
-
263
- const renderAction = () => {
264
- if (Array.isArray(children)) {
265
- return children.map((child, index) => {
266
- return (
267
- <View key={`HeaderRightAction ${index}`} style={styles.headerButton}>
268
- {React.cloneElement(validateType(child), {...restProps})}
269
- </View>
270
- );
271
- });
272
- }
273
-
274
310
  return (
275
- <View style={styles.headerButton}>
276
- {React.cloneElement(validateType(children), {...restProps})}
311
+ <View style={styles.headerRightButton} onLayout={onLayout}>
312
+ {buttons?.map?.((item: NavigationButtonProps, index: number) => {
313
+ return (
314
+ <View
315
+ key={`HeaderRightAction ${index}`}
316
+ style={{
317
+ marginLeft: index !== 0 ? Spacing.S : 0,
318
+ }}>
319
+ <NavigationButton {...item} tintColor={props?.tintColor} />
320
+ </View>
321
+ );
322
+ })}
277
323
  </View>
278
324
  );
279
- };
280
- return <View style={styles.headerRightButton}>{renderAction()}</View>;
325
+ }
326
+
327
+ return (
328
+ <View style={styles.headerRightButton} onLayout={onLayout}>
329
+ {children ?? <HeaderToolkitAction {...props} />}
330
+ </View>
331
+ );
281
332
  };
282
333
 
334
+ /**
335
+ * Header toolkit action
336
+ */
283
337
  const HeaderToolkitAction: React.FC<any> = ({
284
338
  tintColor,
285
339
  pinnedTool,
286
340
  runtimeTools = [],
287
- preventBack,
341
+ preventClose,
288
342
  }) => {
289
- const {theme, navigator} = useContext(ApplicationContext);
290
- const miniContext = useContext(MiniAppContext);
343
+ const {navigator} = useContext(ApplicationContext);
344
+ const miniContext = useContext<any>(MiniAppContext);
291
345
  const [toolConfig, setToolConfig] = useState<any>();
292
346
  const {onAction} = toolConfig ?? {};
293
347
 
294
348
  let backgroundColor;
295
- if (tintColor != Colors.black_01) {
296
- backgroundColor = theme.colors.background.surface;
349
+ if (tintColor !== Colors.black_01) {
350
+ backgroundColor = 'transparent';
297
351
  }
298
352
 
299
353
  useEffect(() => {
@@ -313,7 +367,7 @@ const HeaderToolkitAction: React.FC<any> = ({
313
367
  (config: any) => {
314
368
  navigator.toolkitConfig = config;
315
369
  setToolConfig(navigator?.toolkitConfig);
316
- },
370
+ }
317
371
  );
318
372
  };
319
373
 
@@ -324,26 +378,26 @@ const HeaderToolkitAction: React.FC<any> = ({
324
378
  {runtimeTools},
325
379
  (res: {item: {action?: string; key: string}}) => {
326
380
  const {item} = res;
327
- navigator?.toolkitCallback?.(item);
381
+ navigator?.toolkitCallback?.(item.key);
328
382
  getToolkitConfig();
329
- },
383
+ }
330
384
  );
331
385
  };
332
386
 
333
387
  const onClose = () => {
334
- if (preventBack) {
388
+ if (preventClose) {
335
389
  navigator?.showModal({
336
390
  screen: () => (
337
391
  <PopupNotify
338
- {...preventBack}
392
+ {...preventClose}
339
393
  primary={{
340
- title: preventBack.primary.title,
394
+ title: preventClose.primary.title,
341
395
  onPress: () => {
342
- preventBack?.primary.onPress();
396
+ preventClose?.primary.onPress();
343
397
  navigator?.maxApi?.dispatchFunction?.(
344
398
  'dismiss',
345
399
  undefined,
346
- undefined,
400
+ undefined
347
401
  );
348
402
  },
349
403
  }}
@@ -363,6 +417,7 @@ const HeaderToolkitAction: React.FC<any> = ({
363
417
  if (pinTool)
364
418
  return (
365
419
  <NavigationButton
420
+ accessibilityLabel="btn_navigation_pin"
366
421
  icon={pinTool.icon as string}
367
422
  tintColor={tintColor}
368
423
  badgeValue={badgeValue}
@@ -370,20 +425,19 @@ const HeaderToolkitAction: React.FC<any> = ({
370
425
  onPress={() => {
371
426
  navigator?.maxApi?.dispatchFunction?.(
372
427
  'onToolAction',
373
- [pinTool?.key],
428
+ {item: pinTool},
374
429
  () => {
375
430
  getToolkitConfig();
376
- },
431
+ }
377
432
  );
378
433
  navigator?.toolkitCallback?.(pinTool.key);
379
434
  }}
380
435
  />
381
436
  );
382
437
  };
383
-
384
438
  if (toolConfig) {
385
439
  return (
386
- <View style={styles.headerRightButton}>
440
+ <View style={Styles.row}>
387
441
  {renderPinnedTool()}
388
442
  <View
389
443
  style={[
@@ -391,13 +445,18 @@ const HeaderToolkitAction: React.FC<any> = ({
391
445
  {
392
446
  backgroundColor: backgroundColor ?? '#00000066',
393
447
  borderWidth: backgroundColor ? 0.5 : 0,
448
+ marginLeft: renderPinnedTool() ? Spacing.S : 0,
394
449
  },
395
450
  ]}>
396
- <TouchableOpacity onPress={onMore}>
451
+ <TouchableOpacity
452
+ accessibilityLabel={'btn_navigation_more'}
453
+ onPress={onMore}>
397
454
  <Icon color={tintColor} source="navigation_more_horiz" size={20} />
398
455
  </TouchableOpacity>
399
456
  <View style={[styles.divider, {backgroundColor: tintColor}]} />
400
- <TouchableOpacity onPress={onClose}>
457
+ <TouchableOpacity
458
+ accessibilityLabel={'btn_navigation_close'}
459
+ onPress={onClose}>
401
460
  <Icon
402
461
  color={tintColor}
403
462
  source="16_navigation_close_circle"
@@ -412,10 +471,13 @@ const HeaderToolkitAction: React.FC<any> = ({
412
471
  return <View />;
413
472
  };
414
473
 
474
+ /**
475
+ * default header banner for header animated
476
+ */
415
477
  const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
416
478
  animatedValue,
417
479
  image,
418
- onPress,
480
+ children,
419
481
  }) => {
420
482
  const scale = animatedValue.interpolate({
421
483
  inputRange: [-300, 0, 300],
@@ -434,24 +496,209 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
434
496
  });
435
497
 
436
498
  return (
437
- <TouchableOpacity onPress={onPress}>
438
- <Animated.View
439
- style={{
440
- height: 210,
441
- opacity: opacity,
442
- transform: [{scale}, {translateY}],
443
- }}>
499
+ <Animated.View
500
+ style={{
501
+ height: 210,
502
+ opacity: opacity,
503
+ transform: [{scale}, {translateY}],
504
+ }}>
505
+ {children ?? (
444
506
  <Image
445
507
  source={{
446
508
  uri: image,
447
509
  }}
448
510
  style={{width: '100%', height: '100%'}}
449
511
  />
450
- </Animated.View>
451
- </TouchableOpacity>
512
+ )}
513
+ </Animated.View>
452
514
  );
453
515
  };
454
516
 
517
+ /**
518
+ * Header extended with background image
519
+ * @constructor
520
+ */
521
+ const HeaderExtendHeader: React.FC<{
522
+ headerType?: HeaderType;
523
+ animatedValue: Animated.Value;
524
+ heightHeader: number;
525
+ inputSearchProps?: InputSearchProps;
526
+ inputSearchRef?: Ref<InputRef>;
527
+ navigation?: Navigation;
528
+ }> = ({
529
+ headerType = 'default',
530
+ animatedValue,
531
+ heightHeader,
532
+ inputSearchProps,
533
+ inputSearchRef,
534
+ navigation,
535
+ }) => {
536
+ const {theme} = useContext(ApplicationContext);
537
+ const [rightSpace, setRightSpace] = useState(0);
538
+ const animated = useRef(new Animated.Value(0));
539
+
540
+ useEffect(() => {
541
+ const listener = animatedValue.addListener(({value}) => {
542
+ animated.current.setValue(value);
543
+ });
544
+ return () => {
545
+ animatedValue?.removeListener(listener);
546
+ };
547
+ }, []);
548
+
549
+ const height = animated.current.interpolate({
550
+ inputRange: [0, 100],
551
+ outputRange: [heightHeader + 52, heightHeader],
552
+ extrapolate: 'clamp',
553
+ });
554
+
555
+ const translateX = animated.current.interpolate({
556
+ inputRange: [0, 100],
557
+ outputRange: [SCREEN_PADDING, BACK_WIDTH + SCREEN_PADDING * 2],
558
+ extrapolate: 'clamp',
559
+ });
560
+
561
+ if (navigation) {
562
+ navigation.onHeaderRightChange = (width: number) => {
563
+ setRightSpace(width);
564
+ };
565
+ }
566
+
567
+ const renderInputView = (hasColorBG: boolean = false) => {
568
+ return (
569
+ <Animated.View
570
+ style={{
571
+ justifyContent: 'flex-end',
572
+ height,
573
+ }}>
574
+ <Animated.View
575
+ style={{
576
+ transform: [{translateX}],
577
+ marginVertical: Spacing.S,
578
+ width: animated.current.interpolate({
579
+ inputRange: [0, 100],
580
+ outputRange: [
581
+ screenWidth - SCREEN_PADDING * 2,
582
+ screenWidth - SCREEN_PADDING * 3 - BACK_WIDTH - rightSpace,
583
+ ],
584
+ extrapolate: 'clamp',
585
+ }),
586
+ }}>
587
+ <InputSearch
588
+ {...inputSearchProps}
589
+ ref={inputSearchRef}
590
+ hasColorBG={hasColorBG}
591
+ showButtonText={false}
592
+ />
593
+ </Animated.View>
594
+ </Animated.View>
595
+ );
596
+ };
597
+
598
+ if (inputSearchProps) {
599
+ if (headerType === 'surface') {
600
+ return (
601
+ <>
602
+ <Animated.View
603
+ style={[
604
+ styles.headerBox,
605
+ {
606
+ backgroundColor: theme.colors.background.surface,
607
+ borderBottomWidth: 1,
608
+ borderColor: theme.colors.border.default,
609
+ height,
610
+ },
611
+ ]}
612
+ />
613
+ {renderInputView(true)}
614
+ </>
615
+ );
616
+ }
617
+
618
+ if (headerType === 'extended') {
619
+ return (
620
+ <>
621
+ <Animated.View
622
+ style={[
623
+ styles.headerBox,
624
+ {
625
+ height,
626
+ },
627
+ ]}>
628
+ <Image
629
+ source={{
630
+ uri: theme.assets?.headerBackground,
631
+ }}
632
+ style={styles.headerBackground}
633
+ />
634
+ </Animated.View>
635
+ {renderInputView()}
636
+ </>
637
+ );
638
+ }
639
+
640
+ return (
641
+ <>
642
+ <View style={[styles.headerBox, {height: heightHeader}]}>
643
+ <Image
644
+ source={{
645
+ uri: theme.assets?.headerBackground,
646
+ }}
647
+ style={styles.headerBackground}
648
+ />
649
+ </View>
650
+ {renderInputView()}
651
+ </>
652
+ );
653
+ }
654
+
655
+ if (headerType === 'extended') {
656
+ return (
657
+ <View style={{minHeight: heightHeader}}>
658
+ <Image
659
+ source={{
660
+ uri: theme.assets?.headerBackground,
661
+ }}
662
+ style={styles.extendedHeader}
663
+ />
664
+ </View>
665
+ );
666
+ }
667
+
668
+ return <View />;
669
+ };
670
+
671
+ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
672
+ if (__DEV__) {
673
+ Alert.alert(
674
+ 'HeaderRightAction',
675
+ 'This component is deprecated and will removed 10/2024, please use new type headerRight specs instead v0.92.34'
676
+ );
677
+ }
678
+ const validateType = (child: React.ReactElement) => {
679
+ return child;
680
+ };
681
+
682
+ const renderAction = () => {
683
+ if (Array.isArray(children)) {
684
+ return children.map((child, index) => {
685
+ return (
686
+ <View key={`HeaderRightAction ${index}`} style={styles.headerButton}>
687
+ {React.cloneElement(validateType(child), {...restProps})}
688
+ </View>
689
+ );
690
+ });
691
+ }
692
+
693
+ return (
694
+ <View style={styles.headerButton}>
695
+ {React.cloneElement(validateType(children), {...restProps})}
696
+ </View>
697
+ );
698
+ };
699
+ return <View style={styles.headerRightButton}>{renderAction()}</View>;
700
+ };
701
+
455
702
  const styles = StyleSheet.create({
456
703
  navigationButton: {
457
704
  height: 28,
@@ -488,10 +735,9 @@ const styles = StyleSheet.create({
488
735
  flexDirection: 'row',
489
736
  justifyContent: 'center',
490
737
  alignItems: 'center',
491
- paddingRight: Spacing.S,
738
+ paddingRight: Spacing.M,
492
739
  },
493
740
  toolkitContainer: {
494
- marginLeft: Spacing.S,
495
741
  padding: Spacing.XS,
496
742
  height: 28,
497
743
  borderRadius: 14,
@@ -523,6 +769,22 @@ const styles = StyleSheet.create({
523
769
  top: -Spacing.XS,
524
770
  right: -Spacing.XS,
525
771
  },
772
+ badgeDotAnimation: {
773
+ position: 'absolute',
774
+ top: -Spacing.XS,
775
+ right: -Spacing.XS,
776
+ },
777
+ extendedHeader: {
778
+ aspectRatio: 1.75,
779
+ position: 'absolute',
780
+ width: '100%',
781
+ height: 210,
782
+ },
783
+ headerBox: {
784
+ width: '100%',
785
+ position: 'absolute',
786
+ overflow: 'hidden',
787
+ },
526
788
  });
527
789
 
528
790
  export {
@@ -530,8 +792,10 @@ export {
530
792
  HeaderTitle,
531
793
  HeaderLeft,
532
794
  HeaderBackground,
533
- HeaderRightAction,
534
795
  HeaderToolkitAction,
535
796
  HeaderCustom,
536
797
  HeaderAnimated,
798
+ HeaderRight,
799
+ HeaderExtendHeader,
800
+ HeaderRightAction,
537
801
  };