@hero-design/rn 8.70.0 → 8.72.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.
Files changed (76) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/CHANGELOG.md +29 -0
  3. package/es/index.js +402 -219
  4. package/lib/index.js +402 -219
  5. package/package.json +1 -1
  6. package/src/components/Accordion/AccordionItem.tsx +1 -1
  7. package/src/components/Accordion/__tests__/__snapshots__/AccordionItem.spec.tsx.snap +8 -8
  8. package/src/components/Accordion/__tests__/__snapshots__/index.spec.tsx.snap +12 -12
  9. package/src/components/Badge/StyledBadge.tsx +17 -2
  10. package/src/components/Badge/__tests__/Badge.spec.tsx +15 -0
  11. package/src/components/Badge/__tests__/__snapshots__/Badge.spec.tsx.snap +187 -0
  12. package/src/components/Badge/index.tsx +20 -36
  13. package/src/components/Badge/types.ts +55 -0
  14. package/src/components/Button/LoadingIndicator/__tests__/__snapshots__/StyledLoadingIndicator.spec.tsx.snap +3 -3
  15. package/src/components/Button/LoadingIndicator/__tests__/__snapshots__/index.spec.tsx.snap +9 -9
  16. package/src/components/Button/__tests__/__snapshots__/Button.spec.tsx.snap +7 -7
  17. package/src/components/Button/__tests__/__snapshots__/StyledButton.spec.tsx.snap +6 -6
  18. package/src/components/Chip/StyledChip.tsx +44 -8
  19. package/src/components/Chip/__tests__/__snapshots__/index.spec.tsx.snap +212 -2
  20. package/src/components/Chip/__tests__/index.spec.tsx +2 -0
  21. package/src/components/Chip/index.tsx +1 -1
  22. package/src/components/FAB/FAB.tsx +6 -1
  23. package/src/components/FAB/Pair/StyledFAB.tsx +19 -0
  24. package/src/components/FAB/Pair/__tests__/__snapshots__/index.spec.tsx.snap +276 -0
  25. package/src/components/FAB/Pair/__tests__/index.spec.tsx +39 -0
  26. package/src/components/FAB/Pair/index.tsx +46 -0
  27. package/src/components/FAB/__tests__/__snapshots__/index.spec.tsx.snap +31 -14
  28. package/src/components/FAB/index.tsx +3 -1
  29. package/src/components/Progress/ProgressStep.tsx +3 -1
  30. package/src/components/Progress/StyledStep.tsx +13 -11
  31. package/src/components/Progress/__tests__/__snapshots__/index.spec.js.snap +215 -4
  32. package/src/components/Progress/__tests__/index.spec.js +16 -4
  33. package/src/components/Search/SearchOneLine.tsx +7 -1
  34. package/src/components/Search/SearchSuffixIcon.tsx +12 -1
  35. package/src/components/Search/SearchTwoLine.tsx +7 -1
  36. package/src/components/Search/StyledSearch.tsx +42 -16
  37. package/src/components/Search/__tests__/SearchOneLine.spec.tsx +30 -0
  38. package/src/components/Search/__tests__/SearchTwoLine.spec.tsx +15 -0
  39. package/src/components/Search/__tests__/__snapshots__/SearchOneLine.spec.tsx.snap +166 -10
  40. package/src/components/Search/__tests__/__snapshots__/SearchSuffixIcon.spec.tsx.snap +3 -0
  41. package/src/components/Search/__tests__/__snapshots__/SearchTwoLine.spec.tsx.snap +182 -2
  42. package/src/components/Switch/__tests__/__snapshots__/StyledSwitch.spec.tsx.snap +1 -1
  43. package/src/components/Tabs/__tests__/__snapshots__/ScrollableTabs.spec.tsx.snap +9 -0
  44. package/src/components/Tabs/__tests__/__snapshots__/ScrollableTabsHeader.spec.tsx.snap +6 -0
  45. package/src/components/Tabs/__tests__/__snapshots__/TabWithBadge.spec.tsx.snap +3 -0
  46. package/src/components/Tabs/__tests__/__snapshots__/index.spec.tsx.snap +9 -0
  47. package/src/components/Toolbar/StyledToolbar.tsx +11 -0
  48. package/src/components/Toolbar/ToolbarItem.tsx +3 -3
  49. package/src/components/Toolbar/__tests__/__snapshots__/ToolbarItem.spec.tsx.snap +24 -4
  50. package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +50 -9
  51. package/src/theme/components/badge.ts +10 -1
  52. package/src/theme/components/button.ts +2 -2
  53. package/src/theme/components/chip.ts +4 -0
  54. package/src/theme/components/fab.ts +3 -0
  55. package/src/theme/components/search.ts +30 -5
  56. package/src/theme/components/switch.ts +2 -2
  57. package/src/theme/components/toolbar.ts +1 -1
  58. package/stats/8.71.0/rn-stats.html +4842 -0
  59. package/stats/8.72.0/rn-stats.html +4844 -0
  60. package/types/components/Badge/StyledBadge.d.ts +9 -1
  61. package/types/components/Badge/index.d.ts +3 -34
  62. package/types/components/Badge/types.d.ts +53 -0
  63. package/types/components/Chip/StyledChip.d.ts +1 -1
  64. package/types/components/Chip/index.d.ts +1 -1
  65. package/types/components/FAB/Pair/StyledFAB.d.ts +12 -0
  66. package/types/components/FAB/Pair/index.d.ts +16 -0
  67. package/types/components/FAB/index.d.ts +1 -0
  68. package/types/components/Progress/StyledStep.d.ts +2 -0
  69. package/types/components/Search/SearchOneLine.d.ts +5 -0
  70. package/types/components/Search/SearchTwoLine.d.ts +5 -0
  71. package/types/components/Search/StyledSearch.d.ts +7 -2
  72. package/types/components/Toolbar/StyledToolbar.d.ts +9 -2
  73. package/types/theme/components/badge.d.ts +8 -0
  74. package/types/theme/components/chip.d.ts +4 -0
  75. package/types/theme/components/fab.d.ts +3 -0
  76. package/types/theme/components/search.d.ts +31 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.70.0",
3
+ "version": "8.72.0",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -38,7 +38,7 @@ const AccordionItem = ({
38
38
  )}
39
39
  <Icon
40
40
  icon={open ? 'arrow-up' : 'arrow-down'}
41
- intent="secondary"
41
+ intent="primary"
42
42
  size="small"
43
43
  />
44
44
  </StyledHeaderWrapper>
@@ -82,13 +82,13 @@ exports[`AccordionItem renders correctly when header is an element 1`] = `
82
82
  style={
83
83
  [
84
84
  {
85
- "color": "#795e90",
85
+ "color": "#401960",
86
86
  "fontSize": 20,
87
87
  },
88
88
  undefined,
89
89
  ]
90
90
  }
91
- themeIntent="secondary"
91
+ themeIntent="primary"
92
92
  themeSize="small"
93
93
  />
94
94
  </View>
@@ -260,13 +260,13 @@ exports[`AccordionItem renders correctly when header is string 1`] = `
260
260
  style={
261
261
  [
262
262
  {
263
- "color": "#795e90",
263
+ "color": "#401960",
264
264
  "fontSize": 20,
265
265
  },
266
266
  undefined,
267
267
  ]
268
268
  }
269
- themeIntent="secondary"
269
+ themeIntent="primary"
270
270
  themeSize="small"
271
271
  />
272
272
  </View>
@@ -438,13 +438,13 @@ exports[`AccordionItem renders correctly when open 1`] = `
438
438
  style={
439
439
  [
440
440
  {
441
- "color": "#795e90",
441
+ "color": "#401960",
442
442
  "fontSize": 20,
443
443
  },
444
444
  undefined,
445
445
  ]
446
446
  }
447
- themeIntent="secondary"
447
+ themeIntent="primary"
448
448
  themeSize="small"
449
449
  />
450
450
  </View>
@@ -616,13 +616,13 @@ exports[`AccordionItem renders correctly when variant is card 1`] = `
616
616
  style={
617
617
  [
618
618
  {
619
- "color": "#795e90",
619
+ "color": "#401960",
620
620
  "fontSize": 20,
621
621
  },
622
622
  undefined,
623
623
  ]
624
624
  }
625
- themeIntent="secondary"
625
+ themeIntent="primary"
626
626
  themeSize="small"
627
627
  />
628
628
  </View>
@@ -90,13 +90,13 @@ exports[`Accordion allows fully controlled 1`] = `
90
90
  style={
91
91
  [
92
92
  {
93
- "color": "#795e90",
93
+ "color": "#401960",
94
94
  "fontSize": 20,
95
95
  },
96
96
  undefined,
97
97
  ]
98
98
  }
99
- themeIntent="secondary"
99
+ themeIntent="primary"
100
100
  themeSize="small"
101
101
  />
102
102
  </View>
@@ -237,13 +237,13 @@ exports[`Accordion allows fully controlled 1`] = `
237
237
  style={
238
238
  [
239
239
  {
240
- "color": "#795e90",
240
+ "color": "#401960",
241
241
  "fontSize": 20,
242
242
  },
243
243
  undefined,
244
244
  ]
245
245
  }
246
- themeIntent="secondary"
246
+ themeIntent="primary"
247
247
  themeSize="small"
248
248
  />
249
249
  </View>
@@ -424,13 +424,13 @@ exports[`Accordion renders correctly 1`] = `
424
424
  style={
425
425
  [
426
426
  {
427
- "color": "#795e90",
427
+ "color": "#401960",
428
428
  "fontSize": 20,
429
429
  },
430
430
  undefined,
431
431
  ]
432
432
  }
433
- themeIntent="secondary"
433
+ themeIntent="primary"
434
434
  themeSize="small"
435
435
  />
436
436
  </View>
@@ -571,13 +571,13 @@ exports[`Accordion renders correctly 1`] = `
571
571
  style={
572
572
  [
573
573
  {
574
- "color": "#795e90",
574
+ "color": "#401960",
575
575
  "fontSize": 20,
576
576
  },
577
577
  undefined,
578
578
  ]
579
579
  }
580
- themeIntent="secondary"
580
+ themeIntent="primary"
581
581
  themeSize="small"
582
582
  />
583
583
  </View>
@@ -758,13 +758,13 @@ exports[`Accordion renders correctly when variant is card 1`] = `
758
758
  style={
759
759
  [
760
760
  {
761
- "color": "#795e90",
761
+ "color": "#401960",
762
762
  "fontSize": 20,
763
763
  },
764
764
  undefined,
765
765
  ]
766
766
  }
767
- themeIntent="secondary"
767
+ themeIntent="primary"
768
768
  themeSize="small"
769
769
  />
770
770
  </View>
@@ -916,13 +916,13 @@ exports[`Accordion renders correctly when variant is card 1`] = `
916
916
  style={
917
917
  [
918
918
  {
919
- "color": "#795e90",
919
+ "color": "#401960",
920
920
  "fontSize": 20,
921
921
  },
922
922
  undefined,
923
923
  ]
924
924
  }
925
- themeIntent="secondary"
925
+ themeIntent="primary"
926
926
  themeSize="small"
927
927
  />
928
928
  </View>
@@ -1,6 +1,7 @@
1
1
  import { Animated } from 'react-native';
2
2
  import styled from '@emotion/native';
3
3
  import Typography from '../Typography';
4
+ import Icon from '../Icon';
4
5
 
5
6
  type ThemeIntent =
6
7
  | 'primary'
@@ -14,11 +15,14 @@ type ThemePadding = 'narrowContent' | 'wideContent';
14
15
 
15
16
  type ThemeSize = 'medium' | 'small';
16
17
 
18
+ type ThemeVariant = 'filled' | 'outlined';
19
+
17
20
  const StyledView = styled(Animated.View)<{
18
21
  themeIntent: ThemeIntent;
19
22
  themePadding: ThemePadding;
20
23
  themeSize: ThemeSize;
21
- }>(({ themeIntent, themePadding, themeSize, theme }) => ({
24
+ themeVariant: ThemeVariant;
25
+ }>(({ themeIntent, themePadding, themeSize, themeVariant, theme }) => ({
22
26
  height: theme.__hd__.badge.sizes[themeSize].height,
23
27
  minWidth: theme.__hd__.badge.sizes[themeSize].minWidth,
24
28
  alignItems: 'center',
@@ -29,6 +33,11 @@ const StyledView = styled(Animated.View)<{
29
33
  themePadding === 'wideContent'
30
34
  ? theme.__hd__.badge.space[themeSize].horizontalPadding
31
35
  : undefined,
36
+ borderWidth: theme.__hd__.badge.borderWidths.default,
37
+ borderColor:
38
+ themeVariant === 'outlined'
39
+ ? theme.__hd__.badge.colors.border
40
+ : theme.__hd__.badge.colors[themeIntent],
32
41
  }));
33
42
 
34
43
  const StyledText = styled(Typography.Caption)<{
@@ -55,4 +64,10 @@ const StyledStatus = styled(Animated.View)<{
55
64
  borderRadius: theme.radii.rounded,
56
65
  }));
57
66
 
58
- export { StyledView, StyledText, StyledStatus };
67
+ const StyledIcon = styled(Icon)<{
68
+ themeSize: ThemeSize;
69
+ }>(({ themeSize, theme }) => ({
70
+ fontSize: theme.__hd__.badge.fontSizes[themeSize],
71
+ }));
72
+
73
+ export { StyledView, StyledText, StyledStatus, StyledIcon };
@@ -72,4 +72,19 @@ describe('Badge', () => {
72
72
  expect(toJSON()).toMatchSnapshot();
73
73
  expect(getByText('SMALL')).toBeDefined();
74
74
  });
75
+
76
+ it('has outlined style when variant is outlined', () => {
77
+ const { getByText, toJSON } = renderWithTheme(
78
+ <Badge content="OUTLINED" variant="outlined" />
79
+ );
80
+
81
+ expect(toJSON()).toMatchSnapshot();
82
+ expect(getByText('OUTLINED')).toBeDefined();
83
+ });
84
+
85
+ it('render icon correctly', () => {
86
+ const { toJSON } = renderWithTheme(<Badge icon="checkmark" />);
87
+
88
+ expect(toJSON()).toMatchSnapshot();
89
+ });
75
90
  });
@@ -14,7 +14,9 @@ exports[`Badge has danger style when intent is danger 1`] = `
14
14
  {
15
15
  "alignItems": "center",
16
16
  "backgroundColor": "#cb300a",
17
+ "borderColor": "#cb300a",
17
18
  "borderRadius": 999,
19
+ "borderWidth": 2,
18
20
  "height": 24,
19
21
  "justifyContent": "center",
20
22
  "minWidth": 24,
@@ -30,6 +32,7 @@ exports[`Badge has danger style when intent is danger 1`] = `
30
32
  themeIntent="danger"
31
33
  themePadding="wideContent"
32
34
  themeSize="medium"
35
+ themeVariant="filled"
33
36
  >
34
37
  <Text
35
38
  allowFontScaling={false}
@@ -100,7 +103,9 @@ exports[`Badge has info style when intent is info 1`] = `
100
103
  {
101
104
  "alignItems": "center",
102
105
  "backgroundColor": "#355bfb",
106
+ "borderColor": "#355bfb",
103
107
  "borderRadius": 999,
108
+ "borderWidth": 2,
104
109
  "height": 24,
105
110
  "justifyContent": "center",
106
111
  "minWidth": 24,
@@ -116,6 +121,7 @@ exports[`Badge has info style when intent is info 1`] = `
116
121
  themeIntent="info"
117
122
  themePadding="wideContent"
118
123
  themeSize="medium"
124
+ themeVariant="filled"
119
125
  >
120
126
  <Text
121
127
  allowFontScaling={false}
@@ -186,7 +192,9 @@ exports[`Badge has info style when intent is primary 1`] = `
186
192
  {
187
193
  "alignItems": "center",
188
194
  "backgroundColor": "#401960",
195
+ "borderColor": "#401960",
189
196
  "borderRadius": 999,
197
+ "borderWidth": 2,
190
198
  "height": 24,
191
199
  "justifyContent": "center",
192
200
  "minWidth": 24,
@@ -202,6 +210,7 @@ exports[`Badge has info style when intent is primary 1`] = `
202
210
  themeIntent="primary"
203
211
  themePadding="wideContent"
204
212
  themeSize="medium"
213
+ themeVariant="filled"
205
214
  >
206
215
  <Text
207
216
  allowFontScaling={false}
@@ -258,6 +267,95 @@ exports[`Badge has info style when intent is primary 1`] = `
258
267
  </View>
259
268
  `;
260
269
 
270
+ exports[`Badge has outlined style when variant is outlined 1`] = `
271
+ <View
272
+ style={
273
+ {
274
+ "flex": 1,
275
+ }
276
+ }
277
+ >
278
+ <View
279
+ collapsable={false}
280
+ style={
281
+ {
282
+ "alignItems": "center",
283
+ "backgroundColor": "#cb300a",
284
+ "borderColor": "#ffffff",
285
+ "borderRadius": 999,
286
+ "borderWidth": 2,
287
+ "height": 24,
288
+ "justifyContent": "center",
289
+ "minWidth": 24,
290
+ "opacity": 1,
291
+ "paddingHorizontal": 8,
292
+ "transform": [
293
+ {
294
+ "scale": 1,
295
+ },
296
+ ],
297
+ }
298
+ }
299
+ themeIntent="danger"
300
+ themePadding="wideContent"
301
+ themeSize="medium"
302
+ themeVariant="outlined"
303
+ >
304
+ <Text
305
+ allowFontScaling={false}
306
+ style={
307
+ [
308
+ {
309
+ "color": "#001f23",
310
+ "fontFamily": "BeVietnamPro-Regular",
311
+ "fontSize": 12,
312
+ "letterSpacing": 0.36,
313
+ "lineHeight": 16,
314
+ },
315
+ [
316
+ {
317
+ "color": "#ffffff",
318
+ "fontFamily": "BeVietnamPro-Regular",
319
+ "fontSize": 12,
320
+ "includeFontPadding": false,
321
+ "lineHeight": 16,
322
+ "textAlign": "center",
323
+ "textAlignVertical": "center",
324
+ },
325
+ undefined,
326
+ ],
327
+ ]
328
+ }
329
+ themeFontWeight="regular"
330
+ themeIntent="body"
331
+ themeSize="medium"
332
+ >
333
+ OUTLINED
334
+ </Text>
335
+ </View>
336
+ <View
337
+ pointerEvents="box-none"
338
+ position="bottom"
339
+ style={
340
+ [
341
+ {
342
+ "bottom": 0,
343
+ "elevation": 9999,
344
+ "flexDirection": "column-reverse",
345
+ "left": 0,
346
+ "paddingHorizontal": 24,
347
+ "paddingVertical": 16,
348
+ "position": "absolute",
349
+ "right": 0,
350
+ "top": 0,
351
+ },
352
+ undefined,
353
+ ]
354
+ }
355
+ />
356
+ </View>
357
+ `;
358
+
261
359
  exports[`Badge has small style when size is small 1`] = `
262
360
  <View
263
361
  style={
@@ -272,7 +370,9 @@ exports[`Badge has small style when size is small 1`] = `
272
370
  {
273
371
  "alignItems": "center",
274
372
  "backgroundColor": "#cb300a",
373
+ "borderColor": "#cb300a",
275
374
  "borderRadius": 999,
375
+ "borderWidth": 2,
276
376
  "height": 16,
277
377
  "justifyContent": "center",
278
378
  "minWidth": 16,
@@ -288,6 +388,7 @@ exports[`Badge has small style when size is small 1`] = `
288
388
  themeIntent="danger"
289
389
  themePadding="wideContent"
290
390
  themeSize="small"
391
+ themeVariant="filled"
291
392
  >
292
393
  <Text
293
394
  allowFontScaling={false}
@@ -358,7 +459,9 @@ exports[`Badge has success style when intent is success 1`] = `
358
459
  {
359
460
  "alignItems": "center",
360
461
  "backgroundColor": "#017d6d",
462
+ "borderColor": "#017d6d",
361
463
  "borderRadius": 999,
464
+ "borderWidth": 2,
362
465
  "height": 24,
363
466
  "justifyContent": "center",
364
467
  "minWidth": 24,
@@ -374,6 +477,7 @@ exports[`Badge has success style when intent is success 1`] = `
374
477
  themeIntent="success"
375
478
  themePadding="wideContent"
376
479
  themeSize="medium"
480
+ themeVariant="filled"
377
481
  >
378
482
  <Text
379
483
  allowFontScaling={false}
@@ -444,7 +548,9 @@ exports[`Badge has warning style when intent is warning 1`] = `
444
548
  {
445
549
  "alignItems": "center",
446
550
  "backgroundColor": "#ac5d00",
551
+ "borderColor": "#ac5d00",
447
552
  "borderRadius": 999,
553
+ "borderWidth": 2,
448
554
  "height": 24,
449
555
  "justifyContent": "center",
450
556
  "minWidth": 24,
@@ -460,6 +566,7 @@ exports[`Badge has warning style when intent is warning 1`] = `
460
566
  themeIntent="warning"
461
567
  themePadding="wideContent"
462
568
  themeSize="medium"
569
+ themeVariant="filled"
463
570
  >
464
571
  <Text
465
572
  allowFontScaling={false}
@@ -516,6 +623,83 @@ exports[`Badge has warning style when intent is warning 1`] = `
516
623
  </View>
517
624
  `;
518
625
 
626
+ exports[`Badge render icon correctly 1`] = `
627
+ <View
628
+ style={
629
+ {
630
+ "flex": 1,
631
+ }
632
+ }
633
+ >
634
+ <View
635
+ collapsable={false}
636
+ style={
637
+ {
638
+ "alignItems": "center",
639
+ "backgroundColor": "#cb300a",
640
+ "borderColor": "#cb300a",
641
+ "borderRadius": 999,
642
+ "borderWidth": 2,
643
+ "height": 24,
644
+ "justifyContent": "center",
645
+ "minWidth": 24,
646
+ "opacity": 1,
647
+ "paddingHorizontal": undefined,
648
+ "transform": [
649
+ {
650
+ "scale": 1,
651
+ },
652
+ ],
653
+ }
654
+ }
655
+ themeIntent="danger"
656
+ themePadding="narrowContent"
657
+ themeSize="medium"
658
+ themeVariant="filled"
659
+ >
660
+ <HeroIcon
661
+ name="checkmark"
662
+ style={
663
+ [
664
+ {
665
+ "color": "#ffffff",
666
+ "fontSize": 24,
667
+ },
668
+ [
669
+ {
670
+ "fontSize": 12,
671
+ },
672
+ undefined,
673
+ ],
674
+ ]
675
+ }
676
+ themeIntent="text-inverted"
677
+ themeSize="medium"
678
+ />
679
+ </View>
680
+ <View
681
+ pointerEvents="box-none"
682
+ position="bottom"
683
+ style={
684
+ [
685
+ {
686
+ "bottom": 0,
687
+ "elevation": 9999,
688
+ "flexDirection": "column-reverse",
689
+ "left": 0,
690
+ "paddingHorizontal": 24,
691
+ "paddingVertical": 16,
692
+ "position": "absolute",
693
+ "right": 0,
694
+ "top": 0,
695
+ },
696
+ undefined,
697
+ ]
698
+ }
699
+ />
700
+ </View>
701
+ `;
702
+
519
703
  exports[`Badge renders correctly with custom props 1`] = `
520
704
  <View
521
705
  style={
@@ -530,7 +714,9 @@ exports[`Badge renders correctly with custom props 1`] = `
530
714
  {
531
715
  "alignItems": "center",
532
716
  "backgroundColor": "#017d6d",
717
+ "borderColor": "#017d6d",
533
718
  "borderRadius": 999,
719
+ "borderWidth": 2,
534
720
  "height": 24,
535
721
  "justifyContent": "center",
536
722
  "minWidth": 24,
@@ -547,6 +733,7 @@ exports[`Badge renders correctly with custom props 1`] = `
547
733
  themeIntent="success"
548
734
  themePadding="wideContent"
549
735
  themeSize="medium"
736
+ themeVariant="filled"
550
737
  >
551
738
  <Text
552
739
  allowFontScaling={false}
@@ -1,39 +1,10 @@
1
1
  import { Animated } from 'react-native';
2
- import React from 'react';
3
- import type { StyleProp, ViewStyle } from 'react-native';
4
- import { StyledView, StyledText } from './StyledBadge';
2
+ import React, { useMemo } from 'react';
3
+ import { StyledView, StyledText, StyledIcon } from './StyledBadge';
5
4
  import BadgeStatus from './Status';
5
+ import { BasicBadgeProps, IconBadgeProps } from './types';
6
6
 
7
- export interface BadgeProps extends React.ComponentProps<typeof Animated.View> {
8
- /**
9
- * Content of the Badge.
10
- */
11
- content: string | number;
12
- /**
13
- * Whether the Badge is visible.
14
- */
15
- visible?: boolean;
16
- /**
17
- * The maximum number displayed on the badge. If number exceeds this value, `${max}+` are displayed instead. (Only applied when content is number.)
18
- */
19
- max?: number;
20
- /**
21
- * Visual intent color to apply to Badge.
22
- */
23
- intent?: 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'archived';
24
- /**
25
- * Additional style.
26
- */
27
- style?: StyleProp<ViewStyle>;
28
- /**
29
- * Testing id of the component.
30
- */
31
- testID?: string;
32
- /**
33
- * Size of the badge
34
- */
35
- size?: 'medium' | 'small';
36
- }
7
+ export type BadgeProps = BasicBadgeProps | IconBadgeProps;
37
8
 
38
9
  const DEFAULT_MAX_NUMBER = 99;
39
10
 
@@ -48,6 +19,8 @@ const Badge = ({
48
19
  style,
49
20
  testID,
50
21
  size = 'medium',
22
+ variant = 'filled',
23
+ icon,
51
24
  ...nativeProps
52
25
  }: BadgeProps): JSX.Element => {
53
26
  const { current: opacity } = React.useRef<Animated.Value>(
@@ -69,10 +42,16 @@ const Badge = ({
69
42
  }).start();
70
43
  }, [visible, opacity]);
71
44
 
72
- const content =
73
- typeof originalContent === 'number' && originalContent > max
45
+ const isIconBadge = !!icon;
46
+
47
+ const content = useMemo(() => {
48
+ if (isIconBadge) {
49
+ return '';
50
+ }
51
+ return typeof originalContent === 'number' && originalContent > max
74
52
  ? `${max}+`
75
53
  : String(originalContent);
54
+ }, [isIconBadge, originalContent, max]);
76
55
 
77
56
  return (
78
57
  <StyledView
@@ -80,6 +59,7 @@ const Badge = ({
80
59
  themeIntent={intent}
81
60
  themePadding={getPaddingState(content)}
82
61
  themeSize={size}
62
+ themeVariant={variant}
83
63
  style={[
84
64
  {
85
65
  opacity,
@@ -96,7 +76,11 @@ const Badge = ({
96
76
  ]}
97
77
  testID={testID}
98
78
  >
99
- <StyledText themeSize={size}>{content}</StyledText>
79
+ {isIconBadge ? (
80
+ <StyledIcon icon={icon} themeSize={size} intent="text-inverted" />
81
+ ) : (
82
+ <StyledText themeSize={size}>{content}</StyledText>
83
+ )}
100
84
  </StyledView>
101
85
  );
102
86
  };
@@ -0,0 +1,55 @@
1
+ import { Animated, StyleProp, ViewStyle } from 'react-native';
2
+ import { IconName } from '../Icon';
3
+
4
+ interface BaseBadgeProps extends React.ComponentProps<typeof Animated.View> {
5
+ /**
6
+ * Whether the Badge is visible.
7
+ */
8
+ visible?: boolean;
9
+ /**
10
+ * The maximum number displayed on the badge. If number exceeds this value, `${max}+` are displayed instead. (Only applied when content is number.)
11
+ */
12
+ max?: number;
13
+ /**
14
+ * Visual intent color to apply to Badge.
15
+ */
16
+ intent?: 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'archived';
17
+ /**
18
+ * Additional style.
19
+ */
20
+ style?: StyleProp<ViewStyle>;
21
+ /**
22
+ * Testing id of the component.
23
+ */
24
+ testID?: string;
25
+ /**
26
+ * Size of the badge
27
+ */
28
+ size?: 'medium' | 'small';
29
+ /**
30
+ * Variant of the badge
31
+ */
32
+ variant?: 'filled' | 'outlined';
33
+ }
34
+
35
+ export interface BasicBadgeProps extends BaseBadgeProps {
36
+ /**
37
+ * Content of the Badge.
38
+ */
39
+ content: string | number;
40
+ /**
41
+ * Use Icon as the content of the Badge.
42
+ */
43
+ icon?: never;
44
+ }
45
+
46
+ export interface IconBadgeProps extends BaseBadgeProps {
47
+ /**
48
+ * Content of the Badge.
49
+ */
50
+ content?: never;
51
+ /**
52
+ * Use Icon as the content of the Badge.
53
+ */
54
+ icon: IconName;
55
+ }