@transferwise/components 0.0.0-experimental-76bb7cd → 0.0.0-experimental-9f17c52

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 (96) 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 +17 -1
  26. package/build/common/circle/Circle.js.map +1 -1
  27. package/build/common/circle/Circle.mjs +17 -1
  28. package/build/common/circle/Circle.mjs.map +1 -1
  29. package/build/index.js +20 -13
  30. package/build/index.js.map +1 -1
  31. package/build/index.mjs +11 -7
  32. package/build/index.mjs.map +1 -1
  33. package/build/main.css +109 -5
  34. package/build/styles/avatarGroup/AvatarGroup.css +29 -0
  35. package/build/styles/avatarView/AvatarView.css +42 -0
  36. package/build/styles/avatarView/NotificationDot.css +20 -0
  37. package/build/styles/badge/Badge.css +6 -5
  38. package/build/styles/common/circle/Circle.css +32 -0
  39. package/build/styles/main.css +109 -5
  40. package/build/types/avatar/Avatar.d.ts +3 -0
  41. package/build/types/avatar/Avatar.d.ts.map +1 -1
  42. package/build/types/avatarGroup/AvatarGroup.d.ts +18 -0
  43. package/build/types/avatarGroup/AvatarGroup.d.ts.map +1 -0
  44. package/build/types/avatarGroup/index.d.ts +3 -0
  45. package/build/types/avatarGroup/index.d.ts.map +1 -0
  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 +3 -3
  65. package/src/avatar/Avatar.tsx +3 -0
  66. package/src/avatarGroup/AvatarGroup.css +29 -0
  67. package/src/avatarGroup/AvatarGroup.less +42 -0
  68. package/src/avatarGroup/AvatarGroup.story.tsx +284 -0
  69. package/src/avatarGroup/AvatarGroup.tsx +117 -0
  70. package/src/avatarGroup/index.ts +2 -0
  71. package/src/avatarView/AvatarView.css +42 -0
  72. package/src/avatarView/AvatarView.less +33 -0
  73. package/src/avatarView/AvatarView.story.tsx +480 -0
  74. package/src/avatarView/AvatarView.tsx +171 -0
  75. package/src/avatarView/NotificationDot.css +20 -0
  76. package/src/avatarView/NotificationDot.less +24 -0
  77. package/src/avatarView/NotificationDot.tsx +35 -0
  78. package/src/avatarView/index.ts +2 -0
  79. package/src/avatarWrapper/AvatarWrapper.tsx +3 -0
  80. package/src/badge/Badge.css +6 -5
  81. package/src/badge/Badge.less +4 -3
  82. package/src/badge/Badge.tsx +20 -6
  83. package/src/badge/BadgeAssets.tsx +61 -0
  84. package/src/badge/index.ts +3 -0
  85. package/src/common/circle/Circle.css +32 -0
  86. package/src/common/circle/Circle.less +35 -0
  87. package/src/common/circle/Circle.tsx +22 -1
  88. package/src/flowNavigation/FlowNavigation.story.tsx +10 -48
  89. package/src/index.ts +4 -0
  90. package/src/listItem/ListItem.story.tsx +5 -47
  91. package/src/main.css +109 -5
  92. package/src/main.less +2 -0
  93. package/src/overlayHeader/OverlayHeader.story.tsx +5 -10
  94. package/src/radio/Radio.story.tsx +5 -5
  95. package/src/radioGroup/RadioGroup.story.tsx +3 -3
  96. package/src/selectOption/SelectOption.story.tsx +31 -30
@@ -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,28 +17,14 @@ 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 showAvatar = select('avatar', ['', ProfileType.PERSONAL, ProfileType.BUSINESS], 'Profile');
36
25
  const showCloseButton = boolean('show closeButton', true);
37
26
  const showMobileBackButton = boolean('show mobile backButton', true);
38
27
  const done = boolean('done', false);
39
- const profileType: ProfileTypeKeys | undefined = select(
40
- 'profileType',
41
- Object.keys(ProfileType) as ProfileTypeKeys[],
42
- undefined,
43
- );
44
28
  const avatarURL = text(
45
29
  'avatarURL',
46
30
  'https://wise.com/web-art/assets/illustrations/heart-small@2x.webp',
@@ -49,13 +33,7 @@ export const Variants = () => {
49
33
  return !closed ? (
50
34
  <>
51
35
  <FlowNavigation
52
- avatar={
53
- !showAvatar ? null : (
54
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
55
- {getAvatarProfile(showAvatar)}
56
- </Avatar>
57
- )
58
- }
36
+ avatar={!showAvatar ? null : <AvatarView profileType={showAvatar.toLowerCase()} />}
59
37
  logo={<Logo />}
60
38
  activeStep={activeStep}
61
39
  done={done}
@@ -132,7 +110,7 @@ export const Variants = () => {
132
110
 
133
111
  <FlowNavigation
134
112
  done={done}
135
- avatar={<AvatarWrapper url={avatarURL} profileType={profileType} />}
113
+ avatar={<AvatarView imgSrc={avatarURL} profileType={showAvatar?.toLowerCase()} />}
136
114
  activeStep={activeStep}
137
115
  steps={[
138
116
  {
@@ -178,7 +156,7 @@ export const Variants = () => {
178
156
  {/* Instance of always `done` FlowNav for visual testing */}
179
157
  <FlowNavigation
180
158
  done
181
- avatar={<AvatarWrapper url={avatarURL} profileType={profileType} />}
159
+ avatar={<AvatarView imgSrc={avatarURL} profileType={showAvatar.toLowerCase()} />}
182
160
  activeStep={activeStep}
183
161
  steps={[
184
162
  { label: 'Recipient', hoverLabel: 'Daniele Tomboro', onClick: () => setActiveStep(0) },
@@ -240,11 +218,7 @@ export const SendFlow = () => {
240
218
  return (
241
219
  <>
242
220
  <FlowNavigation
243
- avatar={
244
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
245
- <ProfileIcon />
246
- </Avatar>
247
- }
221
+ avatar={<AvatarView />}
248
222
  logo={<Logo />}
249
223
  activeStep={activeStep}
250
224
  steps={steps}
@@ -272,7 +246,7 @@ export const SendFlow = () => {
272
246
  export const WithOverlayHeaderComparison = () => {
273
247
  const [activeStep, setActiveStep] = useState(4);
274
248
  const [closed, setClosed] = useState(false);
275
- const showAvatar = select('avatar', Object.keys(avatarProfiles), 'Profile');
249
+ const showAvatar = select('avatar', ['', ProfileType.PERSONAL, ProfileType.BUSINESS], 'Profile');
276
250
  const showCloseButton = boolean('show closeButton', true);
277
251
  const showMobileBackButton = boolean('show mobile backButton', true);
278
252
  const done = boolean('done', false);
@@ -281,13 +255,7 @@ export const WithOverlayHeaderComparison = () => {
281
255
  <>
282
256
  <div style={{ border: '1px solid #e8e8e8' }}>
283
257
  <FlowNavigation
284
- avatar={
285
- showAvatar ? (
286
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
287
- {getAvatarProfile(showAvatar)}
288
- </Avatar>
289
- ) : null
290
- }
258
+ avatar={showAvatar ? <AvatarView profileType={showAvatar.toLowerCase()} /> : null}
291
259
  activeStep={activeStep}
292
260
  done={done}
293
261
  steps={[]}
@@ -301,13 +269,7 @@ export const WithOverlayHeaderComparison = () => {
301
269
  </div>
302
270
  <div style={{ border: '1px solid #e8e8e8' }}>
303
271
  <OverlayHeader
304
- avatar={
305
- showAvatar ? (
306
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
307
- {getAvatarProfile(showAvatar)}
308
- </Avatar>
309
- ) : null
310
- }
272
+ avatar={showAvatar ? <AvatarView profileType={showAvatar.toLowerCase()} /> : null}
311
273
  onClose={showCloseButton ? () => setClosed(true) : undefined}
312
274
  />
313
275
  </div>
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,8 @@ export {
244
246
  getLangFromLocale,
245
247
  isBrowser,
246
248
  isServerSide,
249
+ getInitials,
250
+ getBrandColorFromSeed,
247
251
  } from './common';
248
252
 
249
253
  /**
@@ -1,15 +1,13 @@
1
1
  /* eslint-disable react/jsx-child-element-spacing */
2
2
 
3
3
  import { action } from '@storybook/addon-actions';
4
- import { Documents } from '@transferwise/icons';
4
+ import { Documents, FastFlag } from '@transferwise/icons';
5
5
  import { ComponentProps } from 'react';
6
6
 
7
7
  import ActionButton from '../actionButton/ActionButton';
8
- import Avatar from '../avatar';
9
- import Badge from '../badge';
8
+ import AvatarView from '../avatarView';
10
9
  import Info from '../info';
11
10
  import Title from '../title/Title';
12
-
13
11
  import ListItem, { List } from '.';
14
12
 
15
13
  export default {
@@ -40,17 +38,7 @@ export const Variants = () => {
40
38
  <div className="m-t-4 m-b-2">
41
39
  <Title type="title-body">With Icon Avatar</Title>
42
40
  <List>
43
- <Template
44
- media={
45
- <Avatar>
46
- <img
47
- style={{ width: 32, height: 32 }}
48
- src="https://wise.com/public-resources/assets/balances/savings-emoji/google/✈️.png"
49
- alt=""
50
- />
51
- </Avatar>
52
- }
53
- />
41
+ <Template media={<AvatarView imgSrc="../tapestry-01.png" />} />
54
42
  </List>
55
43
  </div>
56
44
  <div className="m-t-4 m-b-2">
@@ -59,22 +47,7 @@ export const Variants = () => {
59
47
  <Template
60
48
  title="Sandra Pepper"
61
49
  value="Personal account"
62
- media={
63
- <Badge
64
- badge={
65
- <img
66
- src="https://wise.com/public-resources/assets/brand/fast_flag_badge_personal.svg"
67
- alt=""
68
- height="24px"
69
- width="24px"
70
- />
71
- }
72
- >
73
- <Avatar type="initials" size="md">
74
- <span aria-hidden>SP</span>
75
- </Avatar>
76
- </Badge>
77
- }
50
+ media={<AvatarView profileName="Super Pepa" badge={{ icon: <FastFlag /> }} />}
78
51
  />
79
52
  </List>
80
53
  </div>
@@ -84,22 +57,7 @@ export const Variants = () => {
84
57
  <Template
85
58
  title="Account holder"
86
59
  value="Sandra Pepper"
87
- media={
88
- <Badge
89
- badge={
90
- <img
91
- src="https://wise.com/public-resources/assets/brand/fast_flag_badge_personal.svg"
92
- alt=""
93
- height="24px"
94
- width="24px"
95
- />
96
- }
97
- >
98
- <Avatar type="initials" size="md">
99
- <span aria-hidden>SP</span>
100
- </Avatar>
101
- </Badge>
102
- }
60
+ media={<AvatarView profileName="Super Pepa" badge={{ icon: <FastFlag /> }} />}
103
61
  action={<ActionButton>Share details</ActionButton>}
104
62
  />
105
63
  </List>
package/src/main.css CHANGED
@@ -469,6 +469,77 @@ div.critical-comms .critical-comms-body {
469
469
  .np-theme-personal .tw-avatar--outlined:not(.disabled):not(:disabled):hover {
470
470
  border-color: var(--color-interactive-primary-hover);
471
471
  }
472
+ .np-notification-dot {
473
+ --np-notification-dot-size: 14px;
474
+ position: relative;
475
+ display: inline-block;
476
+ }
477
+ .np-notification-dot-mask {
478
+ -webkit-mask-image: radial-gradient(circle at bottom calc(100% - (var(--np-notification-dot-size) / 2)) left calc(100% - (var(--np-notification-dot-size) / 2)), transparent 0, transparent calc(var(--np-notification-dot-size) / 2 + var(--np-notification-dot-offset)), black 0);
479
+ mask-image: radial-gradient(circle at bottom calc(100% - (var(--np-notification-dot-size) / 2)) left calc(100% - (var(--np-notification-dot-size) / 2)), transparent 0, transparent calc(var(--np-notification-dot-size) / 2 + var(--np-notification-dot-offset)), black 0);
480
+ -webkit-mask-image: radial-gradient(circle at bottom calc(100% - calc(var(--np-notification-dot-size) / 2)) left calc(100% - calc(var(--np-notification-dot-size) / 2)), transparent 0, transparent calc(var(--np-notification-dot-size) / 2 + var(--np-notification-dot-offset)), black 0);
481
+ mask-image: radial-gradient(circle at bottom calc(100% - calc(var(--np-notification-dot-size) / 2)) left calc(100% - calc(var(--np-notification-dot-size) / 2)), transparent 0, transparent calc(var(--np-notification-dot-size) / 2 + var(--np-notification-dot-offset)), black 0);
482
+ }
483
+ .np-notification-dot-badge {
484
+ position: absolute;
485
+ width: var(--np-notification-dot-size);
486
+ height: var(--np-notification-dot-size);
487
+ background-color: var(--color-sentiment-negative);
488
+ border-radius: 9999px;
489
+ border-radius: var(--radius-full);
490
+ right: 0;
491
+ }
492
+ .np-avatar-view .np-avatar-view-content {
493
+ color: var(--color-interactive-primary);
494
+ }
495
+ .np-avatar-view-interactive {
496
+ cursor: pointer;
497
+ }
498
+ .np-avatar-view-interactive .np-circle {
499
+ background-color: rgba(134,167,189,0.10196);
500
+ background-color: var(--color-background-neutral);
501
+ }
502
+ .np-avatar-view-interactive:hover {
503
+ background-color: var(--color-background-neutral-hover);
504
+ }
505
+ .np-avatar-view-interactive:active {
506
+ background-color: var(--color-background-neutral-active);
507
+ }
508
+ .np-avatar-view-non-interactive .np-circle {
509
+ background-color: transparent;
510
+ }
511
+ .np-avatar-view-non-interactive .np-avatar-view-content .wds-flag {
512
+ box-shadow: none;
513
+ }
514
+ .np-avatar-group {
515
+ display: inline-flex;
516
+ position: relative;
517
+ }
518
+ .np-avatar-group-diagonal {
519
+ width: var(--np-avatar-group-size);
520
+ height: var(--np-avatar-group-size);
521
+ }
522
+ .np-avatar-group-diagonal-mask {
523
+ -webkit-mask-image: radial-gradient(circle at bottom calc(100% - var(--np-avatar-group-size) / 1.5) right calc(100% - var(--np-avatar-group-size) / 1.5), transparent 0, transparent calc(var(--np-avatar-group-single-size) / 2 + 0.5px), black 0);
524
+ mask-image: radial-gradient(circle at bottom calc(100% - var(--np-avatar-group-size) / 1.5) right calc(100% - var(--np-avatar-group-size) / 1.5), transparent 0, transparent calc(var(--np-avatar-group-single-size) / 2 + 0.5px), black 0);
525
+ }
526
+ .np-avatar-group-diagonal-child {
527
+ position: absolute;
528
+ top: var(--np-avatar-group-diagonal-child-position);
529
+ right: 0;
530
+ }
531
+ .np-avatar-group-horizontal {
532
+ height: var(--np-avatar-group-size);
533
+ }
534
+ .np-avatar-group-horizontal-mask {
535
+ -webkit-mask-image: radial-gradient(circle at top calc(100% - var(--np-avatar-group-single-size) / 2) right calc((100% - var(--np-avatar-group-single-size) / 1.5) * -1), transparent 0, transparent calc((var(--np-avatar-group-single-size) / 2.5) + var(--np-avatar-group-horizontal-child-position)), black 0);
536
+ mask-image: radial-gradient(circle at top calc(100% - var(--np-avatar-group-single-size) / 2) right calc((100% - var(--np-avatar-group-single-size) / 1.5) * -1), transparent 0, transparent calc((var(--np-avatar-group-single-size) / 2.5) + var(--np-avatar-group-horizontal-child-position)), black 0);
537
+ -webkit-mask-image: radial-gradient(circle at top calc(100% - var(--np-avatar-group-single-size) / 2) right calc(calc(100% - var(--np-avatar-group-single-size) / 1.5) * -1), transparent 0, transparent calc(calc(var(--np-avatar-group-single-size) / 2.5) + var(--np-avatar-group-horizontal-child-position)), black 0);
538
+ mask-image: radial-gradient(circle at top calc(100% - var(--np-avatar-group-single-size) / 2) right calc(calc(100% - var(--np-avatar-group-single-size) / 1.5) * -1), transparent 0, transparent calc(calc(var(--np-avatar-group-single-size) / 2.5) + var(--np-avatar-group-horizontal-child-position)), black 0);
539
+ }
540
+ .np-avatar-group-horizontal-child {
541
+ margin-left: calc(var(--np-avatar-group-horizontal-child-position) * -1);
542
+ }
472
543
  .tw-badge {
473
544
  position: relative;
474
545
  display: inline-block;
@@ -476,6 +547,7 @@ div.critical-comms .critical-comms-body {
476
547
  --badge-mask: 2px;
477
548
  --badge-mask-offset: calc(var(--badge-size) / 2);
478
549
  --badge-border-color: rgba(255, 255, 255, 0.08);
550
+ --badge-content-position: 0px;
479
551
  }
480
552
  .tw-badge.tw-badge-lg {
481
553
  --badge-size: 24px;
@@ -485,8 +557,8 @@ div.critical-comms .critical-comms-body {
485
557
  --badge-border-color: rgba(0, 0, 0, 0.08);
486
558
  }
487
559
  .tw-badge > .tw-badge__children {
488
- -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));
489
- 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));
560
+ -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));
561
+ 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));
490
562
  }
491
563
  [dir="rtl"] .tw-badge > .tw-badge__children {
492
564
  -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));
@@ -496,8 +568,8 @@ div.critical-comms .critical-comms-body {
496
568
  position: absolute;
497
569
  width: var(--badge-size);
498
570
  height: var(--badge-size);
499
- bottom: 0;
500
- right: 0;
571
+ bottom: var(--badge-content-position);
572
+ right: var(--badge-content-position);
501
573
  box-sizing: border-box;
502
574
  border-radius: 50%;
503
575
  text-align: center;
@@ -510,7 +582,7 @@ div.critical-comms .critical-comms-body {
510
582
  user-select: none;
511
583
  }
512
584
  [dir="rtl"] .tw-badge > .tw-badge__content {
513
- left: 0;
585
+ left: var(--badge-content-position);
514
586
  right: auto;
515
587
  right: initial;
516
588
  }
@@ -1211,11 +1283,43 @@ div.critical-comms .critical-comms-body {
1211
1283
  width: var(--circle-size);
1212
1284
  height: var(--circle-size);
1213
1285
  flex-shrink: 0;
1286
+ --circle-border-color: var(--color-border-neutral);
1287
+ --circle-border-width: 1px;
1288
+ font-size: var(--circle-font-size);
1289
+ font-weight: 600;
1290
+ font-weight: var(--font-weight-semi-bold);
1291
+ line-height: 1;
1292
+ }
1293
+ .np-circle .np-display {
1294
+ font-size: var(--circle-font-size);
1214
1295
  }
1215
1296
  .np-circle .tw-icon > svg {
1216
1297
  height: var(--circle-icon-size);
1217
1298
  width: var(--circle-icon-size);
1218
1299
  }
1300
+ .np-circle img,
1301
+ .np-circle .wds-flag {
1302
+ border-radius: 9999px;
1303
+ border-radius: var(--radius-full);
1304
+ width: 100%;
1305
+ height: 100%;
1306
+ -o-object-fit: cover;
1307
+ object-fit: cover;
1308
+ }
1309
+ .np-circle-border {
1310
+ position: relative;
1311
+ }
1312
+ .np-circle-border::after {
1313
+ content: "";
1314
+ position: absolute;
1315
+ top: 0;
1316
+ left: 0;
1317
+ width: 100%;
1318
+ height: 100%;
1319
+ border-radius: 9999px;
1320
+ border-radius: var(--radius-full);
1321
+ box-shadow: inset 0 0 0 var(--circle-border-width) var(--circle-border-color);
1322
+ }
1219
1323
  .np-bottom-sheet {
1220
1324
  border-radius: 10px 10px 0 0;
1221
1325
  }
package/src/main.less CHANGED
@@ -3,6 +3,8 @@
3
3
  @import "./actionButton/ActionButton.less";
4
4
  @import "./alert/Alert.less";
5
5
  @import "./avatar/Avatar.less";
6
+ @import "./avatarView/AvatarView.less";
7
+ @import "./avatarGroup/AvatarGroup.less";
6
8
  @import "./badge/Badge.less";
7
9
  @import "./button/Button.less";
8
10
  @import "./card/Card.less";
@@ -2,9 +2,8 @@ import { action } from '@storybook/addon-actions';
2
2
  import { select, text } from '@storybook/addon-knobs';
3
3
  import { Person as ProfileIcon, Briefcase as BriefcaseIcon } from '@transferwise/icons';
4
4
 
5
- import Avatar, { AvatarType } from '../avatar';
6
- import AvatarWrapper from '../avatarWrapper';
7
- import { ProfileType, Size } from '../common';
5
+ import AvatarView from '../avatarView';
6
+ import { ProfileType } from '../common';
8
7
  import Logo from '../logo';
9
8
 
10
9
  import OverlayHeader from './OverlayHeader';
@@ -29,11 +28,7 @@ export const Basic = () => {
29
28
  return (
30
29
  <OverlayHeader
31
30
  logo={<Logo />}
32
- avatar={
33
- <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
34
- {avatarProfiles[showAvatar]}
35
- </Avatar>
36
- }
31
+ avatar={<AvatarView>{avatarProfiles[showAvatar]}</AvatarView>}
37
32
  onClose={action('Close clicked')}
38
33
  />
39
34
  );
@@ -46,13 +41,13 @@ export const WithAvatarWrapper = () => {
46
41
  );
47
42
  const profileType = select(
48
43
  'profileType',
49
- Object.keys(ProfileType) as `${ProfileType}`[],
44
+ [ProfileType.PERSONAL, ProfileType.BUSINESS],
50
45
  undefined,
51
46
  );
52
47
  return (
53
48
  <OverlayHeader
54
49
  logo={<Logo />}
55
- avatar={<AvatarWrapper url={avatarURL} profileType={profileType} />}
50
+ avatar={<AvatarView imgSrc={avatarURL} profileType={profileType?.toLowerCase()} />}
56
51
  onClose={action('Close clicked')}
57
52
  />
58
53
  );
@@ -2,7 +2,7 @@ import { boolean, text } from '@storybook/addon-knobs';
2
2
  import { Flag } from '@wise/art';
3
3
  import { useState } from 'react';
4
4
 
5
- import Avatar, { AvatarType } from '../avatar';
5
+ import AvatarView from '../avatarView';
6
6
  import Checkbox from '../checkbox';
7
7
 
8
8
  import Radio from './Radio';
@@ -32,9 +32,9 @@ export const Basic = () => {
32
32
  disabled={disabled}
33
33
  avatar={
34
34
  showAvatar ? (
35
- <Avatar type={AvatarType.THUMBNAIL}>
35
+ <AvatarView>
36
36
  <Flag code="IMP" />
37
- </Avatar>
37
+ </AvatarView>
38
38
  ) : null
39
39
  }
40
40
  onChange={() => setChecked(!checked)}
@@ -50,9 +50,9 @@ export const Basic = () => {
50
50
  secondary={secondary}
51
51
  avatar={
52
52
  showAvatar ? (
53
- <Avatar type={AvatarType.THUMBNAIL}>
53
+ <AvatarView>
54
54
  <Flag code="KES" />
55
- </Avatar>
55
+ </AvatarView>
56
56
  ) : null
57
57
  }
58
58
  onChange={() => setChecked(!checked)}
@@ -1,6 +1,6 @@
1
1
  import { Flag } from '@wise/art';
2
2
 
3
- import Avatar, { AvatarType } from '../avatar';
3
+ import AvatarView from '../avatarView';
4
4
 
5
5
  import RadioGroup, { RadioGroupProps, RadioGroupRadio } from './RadioGroup';
6
6
  import { Field } from '../field/Field';
@@ -52,9 +52,9 @@ export const WithAvatars = {
52
52
  ({
53
53
  ...radio,
54
54
  avatar: (
55
- <Avatar type={AvatarType.THUMBNAIL}>
55
+ <AvatarView>
56
56
  <Flag code="NZD" />
57
- </Avatar>
57
+ </AvatarView>
58
58
  ),
59
59
  }) satisfies RadioGroupRadio,
60
60
  ),
@@ -8,8 +8,7 @@ import SelectOption, {
8
8
  import { Bank, BankTransfer, Beach, Briefcase, Card, Plane } from '@transferwise/icons';
9
9
  import { Field } from '../field/Field';
10
10
  import { lorem10 } from '../test-utils';
11
- import Badge from '../badge';
12
- import Avatar from '../avatar';
11
+ import AvatarView from '../avatarView';
13
12
  import { Sentiment } from '../common';
14
13
  import { useState } from 'react';
15
14
 
@@ -116,57 +115,59 @@ const paymentMethods: SelectOptiopsSection<CustomData>[] = [
116
115
  ];
117
116
 
118
117
  const balances: SelectOptiopsSection[] = [
119
- {
120
- title: 'Balances',
121
- options: [
122
- {
123
- media: <Flag code="gbp" />,
124
- title: 'Wise GBP balance',
125
- },
126
- {
127
- media: <Flag code="eur" />,
128
- title: 'Wise EUR balance',
129
- },
130
- ],
131
- },
132
118
  {
133
119
  title: 'Jars',
134
120
  options: [
135
121
  {
136
122
  media: (
137
- <Badge badge={<Flag code="usd" />} size="md">
138
- <Avatar type="icon" size="md" backgroundColor="var(--color-bright-pink)">
139
- <Beach size="24" />
140
- </Avatar>
141
- </Badge>
123
+ <AvatarView
124
+ badge={{ flagCode: 'usd' }}
125
+ style={{ backgroundColor: 'var(--color-bright-pink)' }}
126
+ profileName="Tim Cook"
127
+ />
142
128
  ),
143
129
  title: 'Hawaii Holiday',
144
130
  content: 'Wise USD jar',
145
131
  },
146
132
  {
147
133
  media: (
148
- <Badge badge={<Flag code="aed" />} size="md">
149
- <Avatar type="icon" size="md" backgroundColor="var(--color-bright-yellow)">
150
- <Briefcase size="24" />
151
- </Avatar>
152
- </Badge>
134
+ <AvatarView
135
+ badge={{ flagCode: 'aed' }}
136
+ style={{ backgroundColor: 'var(--color-bright-yellow)' }}
137
+ >
138
+ <Briefcase />
139
+ </AvatarView>
153
140
  ),
154
141
  title: 'Emirates Business Trip',
155
142
  content: 'Wise AED jar',
156
143
  },
157
144
  {
158
145
  media: (
159
- <Badge badge={<Flag code="jpy" />} size="md">
160
- <Avatar type="icon" size="md" backgroundColor="var(--color-bright-blue)">
161
- <Plane size="24" />
162
- </Avatar>
163
- </Badge>
146
+ <AvatarView
147
+ badge={{ flagCode: 'jpy' }}
148
+ style={{ backgroundColor: 'var(--color-bright-blue)' }}
149
+ >
150
+ <Plane />
151
+ </AvatarView>
164
152
  ),
165
153
  title: 'Trip to Mars',
166
154
  content: 'Wise Jpy jar',
167
155
  },
168
156
  ],
169
157
  },
158
+ {
159
+ title: 'Balances',
160
+ options: [
161
+ {
162
+ media: <Flag code="gbp" />,
163
+ title: 'Wise GBP balance',
164
+ },
165
+ {
166
+ media: <Flag code="eur" />,
167
+ title: 'Wise EUR balance',
168
+ },
169
+ ],
170
+ },
170
171
  ];
171
172
 
172
173
  export const Basic: Story = {