@transferwise/components 46.80.0 → 46.81.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 (92) hide show
  1. package/build/avatar/Avatar.js +3 -0
  2. package/build/avatar/Avatar.js.map +1 -1
  3. package/build/avatar/Avatar.mjs +3 -0
  4. package/build/avatar/Avatar.mjs.map +1 -1
  5. package/build/avatarView/AvatarView.js +175 -0
  6. package/build/avatarView/AvatarView.js.map +1 -0
  7. package/build/avatarView/AvatarView.mjs +173 -0
  8. package/build/avatarView/AvatarView.mjs.map +1 -0
  9. package/build/avatarView/NotificationDot.js +59 -0
  10. package/build/avatarView/NotificationDot.js.map +1 -0
  11. package/build/avatarView/NotificationDot.mjs +57 -0
  12. package/build/avatarView/NotificationDot.mjs.map +1 -0
  13. package/build/avatarWrapper/AvatarWrapper.js +10 -4
  14. package/build/avatarWrapper/AvatarWrapper.js.map +1 -1
  15. package/build/avatarWrapper/AvatarWrapper.mjs +10 -4
  16. package/build/avatarWrapper/AvatarWrapper.mjs.map +1 -1
  17. package/build/badge/Badge.js +16 -4
  18. package/build/badge/Badge.js.map +1 -1
  19. package/build/badge/Badge.mjs +15 -3
  20. package/build/badge/Badge.mjs.map +1 -1
  21. package/build/badge/BadgeAssets.js +60 -0
  22. package/build/badge/BadgeAssets.js.map +1 -0
  23. package/build/badge/BadgeAssets.mjs +58 -0
  24. package/build/badge/BadgeAssets.mjs.map +1 -0
  25. package/build/common/circle/Circle.js +19 -1
  26. package/build/common/circle/Circle.js.map +1 -1
  27. package/build/common/circle/Circle.mjs +19 -1
  28. package/build/common/circle/Circle.mjs.map +1 -1
  29. package/build/i18n/zh-HK.json +5 -0
  30. package/build/i18n/zh-HK.json.js +5 -0
  31. package/build/i18n/zh-HK.json.js.map +1 -1
  32. package/build/i18n/zh-HK.json.mjs +5 -0
  33. package/build/i18n/zh-HK.json.mjs.map +1 -1
  34. package/build/index.js +18 -13
  35. package/build/index.js.map +1 -1
  36. package/build/index.mjs +10 -7
  37. package/build/index.mjs.map +1 -1
  38. package/build/main.css +74 -5
  39. package/build/styles/avatarView/AvatarView.css +36 -0
  40. package/build/styles/avatarView/NotificationDot.css +20 -0
  41. package/build/styles/badge/Badge.css +6 -5
  42. package/build/styles/common/circle/Circle.css +32 -0
  43. package/build/styles/main.css +74 -5
  44. package/build/types/avatar/Avatar.d.ts +3 -0
  45. package/build/types/avatar/Avatar.d.ts.map +1 -1
  46. package/build/types/avatarView/AvatarView.d.ts +26 -0
  47. package/build/types/avatarView/AvatarView.d.ts.map +1 -0
  48. package/build/types/avatarView/NotificationDot.d.ts +8 -0
  49. package/build/types/avatarView/NotificationDot.d.ts.map +1 -0
  50. package/build/types/avatarView/index.d.ts +3 -0
  51. package/build/types/avatarView/index.d.ts.map +1 -0
  52. package/build/types/avatarWrapper/AvatarWrapper.d.ts +3 -0
  53. package/build/types/avatarWrapper/AvatarWrapper.d.ts.map +1 -1
  54. package/build/types/badge/Badge.d.ts +9 -4
  55. package/build/types/badge/Badge.d.ts.map +1 -1
  56. package/build/types/badge/BadgeAssets.d.ts +14 -0
  57. package/build/types/badge/BadgeAssets.d.ts.map +1 -0
  58. package/build/types/badge/index.d.ts +2 -0
  59. package/build/types/badge/index.d.ts.map +1 -1
  60. package/build/types/common/circle/Circle.d.ts +2 -0
  61. package/build/types/common/circle/Circle.d.ts.map +1 -1
  62. package/build/types/index.d.ts +3 -1
  63. package/build/types/index.d.ts.map +1 -1
  64. package/package.json +1 -1
  65. package/src/avatar/Avatar.tsx +3 -0
  66. package/src/avatarView/AvatarView.css +36 -0
  67. package/src/avatarView/AvatarView.less +27 -0
  68. package/src/avatarView/AvatarView.story.tsx +467 -0
  69. package/src/avatarView/AvatarView.tsx +171 -0
  70. package/src/avatarView/NotificationDot.css +20 -0
  71. package/src/avatarView/NotificationDot.less +24 -0
  72. package/src/avatarView/NotificationDot.tsx +35 -0
  73. package/src/avatarView/index.ts +2 -0
  74. package/src/avatarWrapper/AvatarWrapper.story.tsx +19 -0
  75. package/src/avatarWrapper/AvatarWrapper.tsx +3 -0
  76. package/src/badge/Badge.css +6 -5
  77. package/src/badge/Badge.less +4 -3
  78. package/src/badge/Badge.tsx +20 -6
  79. package/src/badge/BadgeAssets.tsx +61 -0
  80. package/src/badge/index.ts +3 -0
  81. package/src/circularButton/CircularButton.spec.tsx +0 -36
  82. package/src/common/circle/Circle.css +32 -0
  83. package/src/common/circle/Circle.less +35 -0
  84. package/src/common/circle/Circle.tsx +24 -1
  85. package/src/flowNavigation/FlowNavigation.story.tsx +19 -52
  86. package/src/i18n/zh-HK.json +5 -0
  87. package/src/index.ts +3 -0
  88. package/src/listItem/ListItem.story.tsx +5 -47
  89. package/src/main.css +74 -5
  90. package/src/main.less +1 -0
  91. package/src/overlayHeader/OverlayHeader.story.tsx +6 -14
  92. package/src/circularButton/__snapshots__/CircularButton.spec.tsx.snap +0 -381
@@ -0,0 +1,35 @@
1
+ import { HTMLAttributes } from 'react';
2
+ import { Props as AvatarViewProps } from './AvatarView';
3
+
4
+ type Props = Pick<HTMLAttributes<HTMLDivElement>, 'children'> & {
5
+ avatarSize?: AvatarViewProps['size'];
6
+ };
7
+
8
+ /**
9
+ * Depending on avatar size, notifcation dot size and offset are different
10
+ */
11
+ const MAP_STYLE_CONFIG = {
12
+ 16: { size: 6, offset: 1 },
13
+ 24: { size: 8, offset: 2 },
14
+ 32: { size: 10, offset: 2 },
15
+ 40: { size: 10, offset: 2 },
16
+ 48: { size: 14, offset: 2 },
17
+ 56: { size: 16, offset: 3 },
18
+ 72: { size: 20, offset: 3 },
19
+ };
20
+
21
+ export default function NotificationDot({ children, avatarSize = 48 }: Props) {
22
+ return (
23
+ <div
24
+ className="np-notification-dot"
25
+ style={{
26
+ // @ts-expect-error CSS custom props allowed
27
+ '--np-notification-dot-size': `${MAP_STYLE_CONFIG[avatarSize].size}px`,
28
+ '--np-notification-dot-offset': `${MAP_STYLE_CONFIG[avatarSize].offset}px`,
29
+ }}
30
+ >
31
+ <div className="np-notification-dot-badge" />
32
+ <div className="np-notification-dot-mask">{children}</div>
33
+ </div>
34
+ );
35
+ }
@@ -0,0 +1,2 @@
1
+ export type { Props as AvatarViewProps } from './AvatarView';
2
+ export { default } from './AvatarView';
@@ -99,3 +99,22 @@ export const All: Story = {
99
99
  );
100
100
  },
101
101
  };
102
+
103
+ export const ProfileBrokenImageFallback: Story = {
104
+ parameters: {
105
+ chromatic: {
106
+ delay: 5000,
107
+ },
108
+ },
109
+ render: () => {
110
+ const assetUrl = 'https://test.com/img-wrong-url.test';
111
+ return (
112
+ <>
113
+ <AvatarWrapper />
114
+ <AvatarWrapper url={assetUrl} />
115
+ <AvatarWrapper url={assetUrl} profileType={ProfileType.BUSINESS} />
116
+ <AvatarWrapper url={assetUrl} profileType={ProfileType.BUSINESS} name="Test Name" />
117
+ </>
118
+ );
119
+ },
120
+ };
@@ -75,6 +75,9 @@ export type AvatarWrapperProps = {
75
75
  }
76
76
  );
77
77
 
78
+ /**
79
+ * @deprecated Use `AvatarView` component instead
80
+ */
78
81
  const AvatarWrapper = ({
79
82
  url,
80
83
  'aria-label': ariaLabel,
@@ -5,6 +5,7 @@
5
5
  --badge-mask: 2px;
6
6
  --badge-mask-offset: calc(var(--badge-size) / 2);
7
7
  --badge-border-color: rgba(255, 255, 255, 0.08);
8
+ --badge-content-position: 0px;
8
9
  }
9
10
  .tw-badge.tw-badge-lg {
10
11
  --badge-size: 24px;
@@ -14,8 +15,8 @@
14
15
  --badge-border-color: rgba(0, 0, 0, 0.08);
15
16
  }
16
17
  .tw-badge > .tw-badge__children {
17
- -webkit-mask-image: radial-gradient(circle at top calc(100% - var(--badge-mask-offset)) left calc(100% - var(--badge-mask-offset)), transparent 0, transparent calc(var(--badge-size) / 2 + var(--badge-mask)), black calc(var(--badge-size) / 2 + var(--badge-mask) + 0.5px));
18
- mask-image: radial-gradient(circle at top calc(100% - var(--badge-mask-offset)) left calc(100% - var(--badge-mask-offset)), transparent 0, transparent calc(var(--badge-size) / 2 + var(--badge-mask)), black calc(var(--badge-size) / 2 + var(--badge-mask) + 0.5px));
18
+ -webkit-mask-image: radial-gradient(circle at top calc(100% - var(--badge-mask-offset) - var(--badge-content-position)) left calc(100% - var(--badge-mask-offset) - var(--badge-content-position)), transparent 0, transparent calc(var(--badge-size) / 2 + var(--badge-mask)), black calc(var(--badge-size) / 2 + var(--badge-mask) + 0.5px));
19
+ mask-image: radial-gradient(circle at top calc(100% - var(--badge-mask-offset) - var(--badge-content-position)) left calc(100% - var(--badge-mask-offset) - var(--badge-content-position)), transparent 0, transparent calc(var(--badge-size) / 2 + var(--badge-mask)), black calc(var(--badge-size) / 2 + var(--badge-mask) + 0.5px));
19
20
  }
20
21
  [dir="rtl"] .tw-badge > .tw-badge__children {
21
22
  -webkit-mask-image: radial-gradient(circle at top calc(100% - var(--badge-mask-offset)) right calc(100% - var(--badge-mask-offset)), transparent 0, transparent calc(var(--badge-size) / 2 + var(--badge-mask)), black calc(var(--badge-size) / 2 + var(--badge-mask) + 0.5px));
@@ -25,8 +26,8 @@
25
26
  position: absolute;
26
27
  width: var(--badge-size);
27
28
  height: var(--badge-size);
28
- bottom: 0;
29
- right: 0;
29
+ bottom: var(--badge-content-position);
30
+ right: var(--badge-content-position);
30
31
  box-sizing: border-box;
31
32
  border-radius: 50%;
32
33
  text-align: center;
@@ -39,7 +40,7 @@
39
40
  user-select: none;
40
41
  }
41
42
  [dir="rtl"] .tw-badge > .tw-badge__content {
42
- left: 0;
43
+ left: var(--badge-content-position);
43
44
  right: auto;
44
45
  right: initial;
45
46
  }
@@ -17,6 +17,7 @@
17
17
  --badge-mask: @badge-mask-sm;
18
18
  --badge-mask-offset: calc(var(--badge-size) / 2);
19
19
  --badge-border-color: @badge-border-light;
20
+ --badge-content-position: 0px;
20
21
 
21
22
  &.tw-badge-lg {
22
23
  --badge-size: @badge-size-lg;
@@ -33,7 +34,7 @@
33
34
 
34
35
  mask-image:
35
36
  radial-gradient(
36
- circle at top calc(100% - var(--badge-mask-offset)) left calc(100% - var(--badge-mask-offset)),
37
+ circle at top calc(100% - var(--badge-mask-offset) - var(--badge-content-position)) left calc(100% - var(--badge-mask-offset) - var(--badge-content-position)),
37
38
  transparent 0,
38
39
  transparent calc(var(--badge-size) / 2 + var(--badge-mask)),
39
40
  black calc(var(--badge-size) / 2 + var(--badge-mask) + 0.5px)
@@ -54,8 +55,8 @@
54
55
  position: absolute;
55
56
  width: var(--badge-size);
56
57
  height: var(--badge-size);
57
- bottom: 0;
58
- .right(0);
58
+ bottom: var(--badge-content-position);
59
+ .right(var(--badge-content-position));
59
60
 
60
61
  box-sizing: border-box;
61
62
  border-radius: 50%;
@@ -11,11 +11,12 @@ import {
11
11
  ThemeLight,
12
12
  CommonProps,
13
13
  } from '../common';
14
+ import { BadgeAssetsProps } from '.';
14
15
 
15
16
  /**
16
- * @deprecated Use `SizeSmall` or `SizeLarge` instead.
17
+ * @deprecated Use `16` or `24` instead.
17
18
  */
18
- type DeprecatedSizes = SizeMedium;
19
+ type DeprecatedSizes = SizeSmall | SizeMedium | SizeLarge;
19
20
 
20
21
  export type BadgeProps = {
21
22
  badge: ReactNode;
@@ -23,11 +24,24 @@ export type BadgeProps = {
23
24
  /**
24
25
  * `md` is deprecated, it will fallback to `sm` instead.
25
26
  */
26
- size?: SizeSmall | DeprecatedSizes | SizeLarge;
27
+ size?: DeprecatedSizes | BadgeAssetsProps['size'];
27
28
  border?: ThemeDark | ThemeLight;
28
29
  'aria-label'?: string;
30
+ style?: React.CSSProperties;
29
31
  } & CommonProps;
30
32
 
33
+ const mapLegacySize = {
34
+ 16: Size.SMALL,
35
+ 24: Size.LARGE,
36
+ // medium is no longer exists, so we map it to small
37
+ [String(Size.MEDIUM)]: Size.SMALL,
38
+ };
39
+
40
+ // Note: Badge component is not deprecated, we want stop it's direct usage on consumer side.
41
+ // Deprecation notice will hint consumers to migrate. Eventually the component will become internal.
42
+ /**
43
+ * @deprecated Use `<AvatarView badge={..} />` instead.
44
+ */
31
45
  const Badge = ({
32
46
  badge,
33
47
  className = undefined,
@@ -35,9 +49,9 @@ const Badge = ({
35
49
  border = Theme.LIGHT,
36
50
  'aria-label': ariaLabel,
37
51
  children,
52
+ style,
38
53
  }: BadgeProps) => {
39
- // medium is deprecated, so we map it to small
40
- const size = sizeProp === Size.MEDIUM ? Size.SMALL : sizeProp;
54
+ const size = mapLegacySize[sizeProp] ?? sizeProp;
41
55
  const classes: string = clsx(
42
56
  'tw-badge',
43
57
  {
@@ -48,7 +62,7 @@ const Badge = ({
48
62
  );
49
63
 
50
64
  return (
51
- <div aria-label={ariaLabel} className={classes}>
65
+ <div aria-label={ariaLabel} className={classes} style={style}>
52
66
  <div className="tw-badge__children">{children}</div>
53
67
  <div className="tw-badge__content">{badge}</div>
54
68
  </div>
@@ -0,0 +1,61 @@
1
+ import StatusIcon, { StatusIconProps } from '../statusIcon';
2
+ import { Flag } from '@wise/art';
3
+ import Circle from '../common/circle';
4
+ import Image from '../image';
5
+ import { Plus } from '@transferwise/icons';
6
+
7
+ export type Props = {
8
+ status?: StatusIconProps['sentiment'];
9
+ flagCode?: string;
10
+ imgSrc?: string;
11
+ icon?: React.ReactNode;
12
+ type?: 'action' | 'reference';
13
+ size?: 16 | 24;
14
+ };
15
+
16
+ /**
17
+ * Common pre-built badge variants.
18
+ */
19
+ export default function BadgeAssets({
20
+ status,
21
+ flagCode,
22
+ imgSrc,
23
+ icon = null,
24
+ type = 'action',
25
+ size,
26
+ }: Props) {
27
+ if (status) {
28
+ return <StatusIcon sentiment={status} size={size} />;
29
+ }
30
+ if (flagCode) {
31
+ return (
32
+ <Circle size={size} fixedSize enableBorder>
33
+ <Flag code={flagCode} intrinsicSize={size} />
34
+ </Circle>
35
+ );
36
+ }
37
+ if (imgSrc) {
38
+ return (
39
+ <Circle size={size} fixedSize enableBorder>
40
+ <Image src={imgSrc} alt="" />
41
+ </Circle>
42
+ );
43
+ }
44
+ if (['action', 'reference'].includes(type)) {
45
+ return (
46
+ <Circle
47
+ size={size}
48
+ fixedSize
49
+ style={{
50
+ backgroundColor:
51
+ type === 'action'
52
+ ? 'var(--color-interactive-accent)'
53
+ : 'var(--color-background-neutral)',
54
+ }}
55
+ >
56
+ {icon ?? <Plus />}
57
+ </Circle>
58
+ );
59
+ }
60
+ return null;
61
+ }
@@ -1,2 +1,5 @@
1
1
  export { default } from './Badge';
2
2
  export type { BadgeProps } from './Badge';
3
+
4
+ export { default as BadgeAssets } from './BadgeAssets';
5
+ export type { Props as BadgeAssetsProps } from './BadgeAssets';
@@ -34,10 +34,6 @@ describe('CircularButton', () => {
34
34
  it('is not disabled', () => {
35
35
  expect(screen.getByRole('button')).toBeEnabled();
36
36
  });
37
-
38
- it('renders a button of type accent and priority primary', () => {
39
- expect(render(<CircularButton {...props} />).container).toMatchSnapshot();
40
- });
41
37
  });
42
38
 
43
39
  describe('button attributes', () => {
@@ -69,36 +65,4 @@ describe('CircularButton', () => {
69
65
  expect(onClick).toHaveBeenCalledTimes(0);
70
66
  });
71
67
  });
72
-
73
- describe('types', () => {
74
- it('renders accent buttons', () => {
75
- expect(render(<CircularButton {...props} type={ACCENT} />).container).toMatchSnapshot();
76
- });
77
-
78
- it('renders positive buttons', () => {
79
- expect(render(<CircularButton {...props} type={POSITIVE} />).container).toMatchSnapshot();
80
- });
81
-
82
- it('renders negative buttons', () => {
83
- expect(render(<CircularButton {...props} type={NEGATIVE} />).container).toMatchSnapshot();
84
- });
85
- });
86
-
87
- describe('priorities', () => {
88
- it('renders primary buttons', () => {
89
- [ACCENT, POSITIVE, NEGATIVE].forEach((type) =>
90
- expect(
91
- render(<CircularButton {...props} priority={PRIMARY} type={type} />).container,
92
- ).toMatchSnapshot(),
93
- );
94
- });
95
-
96
- it('renders secondary buttons', () => {
97
- [ACCENT, POSITIVE, NEGATIVE].forEach((type) =>
98
- expect(
99
- render(<CircularButton {...props} priority={SECONDARY} type={type} />).container,
100
- ).toMatchSnapshot(),
101
- );
102
- });
103
- });
104
68
  });
@@ -4,8 +4,40 @@
4
4
  width: var(--circle-size);
5
5
  height: var(--circle-size);
6
6
  flex-shrink: 0;
7
+ --circle-border-color: var(--color-border-neutral);
8
+ --circle-border-width: 1px;
9
+ font-size: var(--circle-font-size);
10
+ font-weight: 600;
11
+ font-weight: var(--font-weight-semi-bold);
12
+ line-height: 1;
13
+ }
14
+ .np-circle .np-display {
15
+ font-size: var(--circle-font-size);
7
16
  }
8
17
  .np-circle .tw-icon > svg {
9
18
  height: var(--circle-icon-size);
10
19
  width: var(--circle-icon-size);
11
20
  }
21
+ .np-circle img,
22
+ .np-circle .wds-flag {
23
+ border-radius: 9999px;
24
+ border-radius: var(--radius-full);
25
+ width: 100%;
26
+ height: 100%;
27
+ -o-object-fit: cover;
28
+ object-fit: cover;
29
+ }
30
+ .np-circle-border {
31
+ position: relative;
32
+ }
33
+ .np-circle-border::after {
34
+ content: "";
35
+ position: absolute;
36
+ top: 0;
37
+ left: 0;
38
+ width: 100%;
39
+ height: 100%;
40
+ border-radius: 9999px;
41
+ border-radius: var(--radius-full);
42
+ box-shadow: inset 0 0 0 var(--circle-border-width) var(--circle-border-color);
43
+ }
@@ -4,9 +4,44 @@
4
4
  height: var(--circle-size);
5
5
  flex-shrink: 0;
6
6
 
7
+ --circle-border-color: var(--color-border-neutral);
8
+ --circle-border-width: 1px;
9
+
10
+ // circle like components have custom typography styles for for default (Inter) font
11
+ font-size: var(--circle-font-size);
12
+ font-weight: var(--font-weight-semi-bold);
13
+ line-height: 1;
14
+
15
+ // circle like components have custom typography styles for Wise Sand font
16
+ .np-display {
17
+ font-size: var(--circle-font-size);
18
+ }
19
+
7
20
  // circle like components has custom icon sizes
8
21
  .tw-icon > svg {
9
22
  height: var(--circle-icon-size);
10
23
  width: var(--circle-icon-size);
11
24
  }
25
+
26
+ img,
27
+ .wds-flag {
28
+ border-radius: var(--radius-full);
29
+ width: 100%;
30
+ height: 100%;
31
+ object-fit: cover;
32
+ }
33
+
34
+ &-border {
35
+ position: relative;
36
+ &::after {
37
+ content: "";
38
+ position: absolute;
39
+ top: 0;
40
+ left: 0;
41
+ width: 100%;
42
+ height: 100%;
43
+ border-radius: var(--radius-full);
44
+ box-shadow: inset 0 0 0 var(--circle-border-width) var(--circle-border-color);
45
+ }
46
+ }
12
47
  }
@@ -19,6 +19,7 @@ export type Props = {
19
19
  * as those can be dynamic a at certain viewport sizes
20
20
  */
21
21
  fixedSize?: boolean;
22
+ enableBorder?: boolean;
22
23
  } & HTMLAttributes<HTMLDivElement>;
23
24
 
24
25
  /**
@@ -34,12 +35,28 @@ const MAP_ICON_SIZE = {
34
35
  72: 36,
35
36
  };
36
37
 
38
+ /**
39
+ * circle like components have custom typography styles for for default (Inter) font
40
+ *
41
+ * circle size : font size (px)
42
+ */
43
+ const MAP_FONT_SIZE = {
44
+ 16: 8,
45
+ 24: 12,
46
+ 32: 14,
47
+ 40: 18,
48
+ 48: 22,
49
+ 56: 26,
50
+ 72: 30,
51
+ };
52
+
37
53
  const Circle = forwardRef(function Circle(
38
54
  {
39
55
  as: Element = 'div',
40
56
  children,
41
57
  size = 48,
42
58
  fixedSize = false,
59
+ enableBorder = false,
43
60
  className,
44
61
  style,
45
62
  ...props
@@ -57,9 +74,15 @@ const Circle = forwardRef(function Circle(
57
74
  isTinyViewport && !fixedSize
58
75
  ? `${MAP_ICON_SIZE[size] / 2}px`
59
76
  : `${MAP_ICON_SIZE[size]}px`,
77
+ '--circle-font-size': `${MAP_FONT_SIZE[size]}px`,
60
78
  ...style,
61
79
  }}
62
- className={clsx('np-circle', 'd-flex align-items-center justify-content-center', className)}
80
+ className={clsx(
81
+ 'np-circle',
82
+ { 'np-circle-border': enableBorder },
83
+ 'd-flex align-items-center justify-content-center',
84
+ className,
85
+ )}
63
86
  >
64
87
  {children}
65
88
  </Element>
@@ -1,12 +1,10 @@
1
1
  import { boolean, select, text } from '@storybook/addon-knobs';
2
- import { Person as ProfileIcon, Briefcase as BriefcaseIcon } from '@transferwise/icons';
3
2
  import { useState } from 'react';
4
3
 
5
- import Avatar, { AvatarType } from '../avatar';
6
- import AvatarWrapper from '../avatarWrapper';
4
+ import AvatarView from '../avatarView';
7
5
  import Body from '../body';
8
6
  import Button from '../button';
9
- import { ProfileType, Size, Typography } from '../common';
7
+ import { ProfileType, Typography } from '../common';
10
8
  import Logo from '../logo';
11
9
  import OverlayHeader from '../overlayHeader';
12
10
 
@@ -19,43 +17,24 @@ export default {
19
17
  component: FlowNavigation,
20
18
  title: 'Navigation/FlowNavigation',
21
19
  };
22
- const avatarProfiles = {
23
- '': null,
24
- Business: <BriefcaseIcon />,
25
- Profile: <ProfileIcon />,
26
- };
27
- type ProfileTypeKeys = keyof typeof ProfileType;
28
-
29
- const getAvatarProfile = (showAvatar: string) =>
30
- showAvatar in avatarProfiles ? avatarProfiles[showAvatar as keyof typeof avatarProfiles] : null;
31
20
 
32
21
  export const Variants = () => {
33
22
  const [activeStep, setActiveStep] = useState(2);
34
23
  const [closed, setClosed] = useState(false);
35
- const showAvatar = select('avatar', Object.keys(avatarProfiles), 'Profile');
24
+ const profileType = select(
25
+ 'avatar',
26
+ [ProfileType.PERSONAL, ProfileType.BUSINESS],
27
+ ProfileType.PERSONAL,
28
+ );
36
29
  const showCloseButton = boolean('show closeButton', true);
37
30
  const showMobileBackButton = boolean('show mobile backButton', true);
38
31
  const done = boolean('done', false);
39
- const profileType: ProfileTypeKeys | undefined = select(
40
- 'profileType',
41
- Object.keys(ProfileType) as ProfileTypeKeys[],
42
- undefined,
43
- );
44
- const avatarURL = text(
45
- 'avatarURL',
46
- 'https://wise.com/web-art/assets/illustrations/heart-small@2x.webp',
47
- );
32
+ const avatarURL = text('avatarURL', '../tapestry-01.png');
48
33
 
49
34
  return !closed ? (
50
35
  <>
51
36
  <FlowNavigation
52
- avatar={
53
- !showAvatar ? null : (
54
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
55
- {getAvatarProfile(showAvatar)}
56
- </Avatar>
57
- )
58
- }
37
+ avatar={!profileType ? null : <AvatarView profileType={profileType} />}
59
38
  logo={<Logo />}
60
39
  activeStep={activeStep}
61
40
  done={done}
@@ -132,7 +111,7 @@ export const Variants = () => {
132
111
 
133
112
  <FlowNavigation
134
113
  done={done}
135
- avatar={<AvatarWrapper url={avatarURL} profileType={profileType} />}
114
+ avatar={<AvatarView imgSrc={avatarURL} profileType={profileType} />}
136
115
  activeStep={activeStep}
137
116
  steps={[
138
117
  {
@@ -178,7 +157,7 @@ export const Variants = () => {
178
157
  {/* Instance of always `done` FlowNav for visual testing */}
179
158
  <FlowNavigation
180
159
  done
181
- avatar={<AvatarWrapper url={avatarURL} profileType={profileType} />}
160
+ avatar={<AvatarView imgSrc={avatarURL} profileType={profileType} />}
182
161
  activeStep={activeStep}
183
162
  steps={[
184
163
  { label: 'Recipient', hoverLabel: 'Daniele Tomboro', onClick: () => setActiveStep(0) },
@@ -240,11 +219,7 @@ export const SendFlow = () => {
240
219
  return (
241
220
  <>
242
221
  <FlowNavigation
243
- avatar={
244
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
245
- <ProfileIcon />
246
- </Avatar>
247
- }
222
+ avatar={<AvatarView />}
248
223
  logo={<Logo />}
249
224
  activeStep={activeStep}
250
225
  steps={steps}
@@ -272,7 +247,11 @@ export const SendFlow = () => {
272
247
  export const WithOverlayHeaderComparison = () => {
273
248
  const [activeStep, setActiveStep] = useState(4);
274
249
  const [closed, setClosed] = useState(false);
275
- const showAvatar = select('avatar', Object.keys(avatarProfiles), 'Profile');
250
+ const profileType = select(
251
+ 'avatar',
252
+ [ProfileType.PERSONAL, ProfileType.BUSINESS],
253
+ ProfileType.PERSONAL,
254
+ );
276
255
  const showCloseButton = boolean('show closeButton', true);
277
256
  const showMobileBackButton = boolean('show mobile backButton', true);
278
257
  const done = boolean('done', false);
@@ -281,13 +260,7 @@ export const WithOverlayHeaderComparison = () => {
281
260
  <>
282
261
  <div style={{ border: '1px solid #e8e8e8' }}>
283
262
  <FlowNavigation
284
- avatar={
285
- showAvatar ? (
286
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
287
- {getAvatarProfile(showAvatar)}
288
- </Avatar>
289
- ) : null
290
- }
263
+ avatar={profileType ? <AvatarView profileType={profileType} /> : null}
291
264
  activeStep={activeStep}
292
265
  done={done}
293
266
  steps={[]}
@@ -301,13 +274,7 @@ export const WithOverlayHeaderComparison = () => {
301
274
  </div>
302
275
  <div style={{ border: '1px solid #e8e8e8' }}>
303
276
  <OverlayHeader
304
- avatar={
305
- showAvatar ? (
306
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
307
- {getAvatarProfile(showAvatar)}
308
- </Avatar>
309
- ) : null
310
- }
277
+ avatar={profileType ? <AvatarView profileType={profileType} /> : null}
311
278
  onClose={showCloseButton ? () => setClosed(true) : undefined}
312
279
  />
313
280
  </div>
@@ -27,6 +27,11 @@
27
27
  "neptune.SelectInput.noResultsFound": "找不到任何結果",
28
28
  "neptune.SelectOption.action.label": "選擇",
29
29
  "neptune.SelectOption.selected.action.label": "更改已選選項",
30
+ "neptune.StatusIcon.iconLabel.error": "錯誤:",
31
+ "neptune.StatusIcon.iconLabel.information": "資訊:",
32
+ "neptune.StatusIcon.iconLabel.pending": "處理中:",
33
+ "neptune.StatusIcon.iconLabel.success": "成功:",
34
+ "neptune.StatusIcon.iconLabel.warning": "警告:",
30
35
  "neptune.Summary.statusDone": "已完成事項",
31
36
  "neptune.Summary.statusNotDone": "未完成事項",
32
37
  "neptune.Summary.statusPending": "待處理事項",
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export type { ActionOptionProps } from './actionOption';
8
8
  export type { SelectOptionProps, SelectOptionValue, SelectOptiopsSection } from './selectOption';
9
9
  export type { AlertAction, AlertProps, AlertType } from './alert';
10
10
  export type { AvatarProps } from './avatar';
11
+ export type { AvatarViewProps } from './avatarView';
11
12
  export type { BadgeProps } from './badge';
12
13
  export type { CardProps } from './card';
13
14
  export type { CarouselProps } from './carousel';
@@ -103,6 +104,7 @@ export { default as ActionOption } from './actionOption';
103
104
  export { default as SelectOption } from './selectOption';
104
105
  export { default as Alert } from './alert';
105
106
  export { default as Avatar } from './avatar';
107
+ export { default as AvatarView } from './avatarView';
106
108
  export { default as AvatarWrapper } from './avatarWrapper';
107
109
  export { default as Badge } from './badge';
108
110
  export { default as Body } from './body';
@@ -244,6 +246,7 @@ export {
244
246
  getLangFromLocale,
245
247
  isBrowser,
246
248
  isServerSide,
249
+ getBrandColorFromSeed,
247
250
  } from './common';
248
251
 
249
252
  /**