@transferwise/components 46.82.1 → 46.83.1

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 (100) hide show
  1. package/build/avatarLayout/AvatarLayout.js +115 -0
  2. package/build/avatarLayout/AvatarLayout.js.map +1 -0
  3. package/build/avatarLayout/AvatarLayout.mjs +113 -0
  4. package/build/avatarLayout/AvatarLayout.mjs.map +1 -0
  5. package/build/button/Button.js +1 -1
  6. package/build/button/Button.js.map +1 -1
  7. package/build/button/Button.mjs +1 -1
  8. package/build/button/Button.mjs.map +1 -1
  9. package/build/i18n/commonMessages/Button.messages.js.map +1 -0
  10. package/build/i18n/commonMessages/Button.messages.mjs.map +1 -0
  11. package/build/i18n/es.json +5 -0
  12. package/build/i18n/es.json.js +5 -0
  13. package/build/i18n/es.json.js.map +1 -1
  14. package/build/i18n/es.json.mjs +5 -0
  15. package/build/i18n/es.json.mjs.map +1 -1
  16. package/build/i18n/pl.json +5 -0
  17. package/build/i18n/pl.json.js +5 -0
  18. package/build/i18n/pl.json.js.map +1 -1
  19. package/build/i18n/pl.json.mjs +5 -0
  20. package/build/i18n/pl.json.mjs.map +1 -1
  21. package/build/i18n/ro.json +5 -0
  22. package/build/i18n/ro.json.js +5 -0
  23. package/build/i18n/ro.json.js.map +1 -1
  24. package/build/i18n/ro.json.mjs +5 -0
  25. package/build/i18n/ro.json.mjs.map +1 -1
  26. package/build/index.js +2 -0
  27. package/build/index.js.map +1 -1
  28. package/build/index.mjs +1 -0
  29. package/build/index.mjs.map +1 -1
  30. package/build/main.css +30 -0
  31. package/build/styles/avatarLayout/AvatarLayout.css +30 -0
  32. package/build/styles/main.css +30 -0
  33. package/build/types/avatarLayout/AvatarLayout.d.ts +11 -0
  34. package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -0
  35. package/build/types/avatarLayout/index.d.ts +3 -0
  36. package/build/types/avatarLayout/index.d.ts.map +1 -0
  37. package/build/types/i18n/commonMessages/Button.messages.d.ts.map +1 -0
  38. package/build/types/index.d.ts +2 -0
  39. package/build/types/index.d.ts.map +1 -1
  40. package/build/types/primitives/PrimitiveAnchor/index.d.ts +3 -0
  41. package/build/types/primitives/PrimitiveAnchor/index.d.ts.map +1 -0
  42. package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.d.ts +14 -0
  43. package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.d.ts.map +1 -0
  44. package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts +21 -0
  45. package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts.map +1 -0
  46. package/build/types/primitives/PrimitiveAnchor/src/index.d.ts +3 -0
  47. package/build/types/primitives/PrimitiveAnchor/src/index.d.ts.map +1 -0
  48. package/build/types/primitives/PrimitiveButton/index.d.ts +3 -0
  49. package/build/types/primitives/PrimitiveButton/index.d.ts.map +1 -0
  50. package/build/types/primitives/PrimitiveButton/src/PrimitiveButton.d.ts +14 -0
  51. package/build/types/primitives/PrimitiveButton/src/PrimitiveButton.d.ts.map +1 -0
  52. package/build/types/primitives/PrimitiveButton/src/PrimitiveButton.types.d.ts +21 -0
  53. package/build/types/primitives/PrimitiveButton/src/PrimitiveButton.types.d.ts.map +1 -0
  54. package/build/types/primitives/PrimitiveButton/src/index.d.ts +3 -0
  55. package/build/types/primitives/PrimitiveButton/src/index.d.ts.map +1 -0
  56. package/build/types/primitives/index.d.ts +6 -0
  57. package/build/types/primitives/index.d.ts.map +1 -0
  58. package/build/types/primitives/types.d.ts +34 -0
  59. package/build/types/primitives/types.d.ts.map +1 -0
  60. package/build/types/table/Table.d.ts.map +1 -1
  61. package/build/types/test-utils/index.d.ts.map +1 -1
  62. package/package.json +3 -3
  63. package/src/avatarLayout/AvatarLayout.css +30 -0
  64. package/src/avatarLayout/AvatarLayout.less +39 -0
  65. package/src/avatarLayout/AvatarLayout.story.tsx +285 -0
  66. package/src/avatarLayout/AvatarLayout.tsx +93 -0
  67. package/src/avatarLayout/index.ts +2 -0
  68. package/src/button/Button.spec.tsx +1 -1
  69. package/src/button/Button.tsx +1 -1
  70. package/src/i18n/es.json +5 -0
  71. package/src/i18n/pl.json +5 -0
  72. package/src/i18n/ro.json +5 -0
  73. package/src/index.ts +2 -0
  74. package/src/main.css +30 -0
  75. package/src/main.less +1 -0
  76. package/src/primitives/PrimitiveAnchor/index.ts +2 -0
  77. package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.tsx +122 -0
  78. package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.ts +28 -0
  79. package/src/primitives/PrimitiveAnchor/src/index.ts +6 -0
  80. package/src/primitives/PrimitiveAnchor/stories/PrimitiveAnchor.story.tsx +77 -0
  81. package/src/primitives/PrimitiveAnchor/stories/PrimitiveAnchor.tests.story.tsx +169 -0
  82. package/src/primitives/PrimitiveAnchor/test/PrimitiveAnchor.spec.tsx +95 -0
  83. package/src/primitives/PrimitiveButton/index.ts +2 -0
  84. package/src/primitives/PrimitiveButton/src/PrimitiveButton.tsx +131 -0
  85. package/src/primitives/PrimitiveButton/src/PrimitiveButton.types.ts +28 -0
  86. package/src/primitives/PrimitiveButton/src/index.ts +6 -0
  87. package/src/primitives/PrimitiveButton/stories/PrimitiveButton.story.tsx +73 -0
  88. package/src/primitives/PrimitiveButton/stories/PrimitiveButton.tests.story.tsx +230 -0
  89. package/src/primitives/PrimitiveButton/test/PrimitiveButton.spec.tsx +114 -0
  90. package/src/primitives/index.ts +14 -0
  91. package/src/primitives/types.ts +40 -0
  92. package/src/table/Table.tsx +3 -2
  93. package/src/test-utils/index.tsx +1 -0
  94. package/build/button/Button.messages.js.map +0 -1
  95. package/build/button/Button.messages.mjs.map +0 -1
  96. package/build/types/button/Button.messages.d.ts.map +0 -1
  97. /package/build/{button → i18n/commonMessages}/Button.messages.js +0 -0
  98. /package/build/{button → i18n/commonMessages}/Button.messages.mjs +0 -0
  99. /package/build/types/{button → i18n/commonMessages}/Button.messages.d.ts +0 -0
  100. /package/src/{button → i18n/commonMessages}/Button.messages.ts +0 -0
@@ -0,0 +1,285 @@
1
+ /* eslint-disable react/jsx-key */
2
+ import { Meta, StoryObj } from '@storybook/react';
3
+ import AvatarLayout, { AvatarLayoutProps } from '.';
4
+ import { Freeze, Graph, Plane, Rewards } from '@transferwise/icons';
5
+ import { Flag } from '@wise/art';
6
+ import Body from '../body';
7
+
8
+ export default {
9
+ title: 'Content/AvatarLayout',
10
+ } satisfies Meta<typeof AvatarLayout>;
11
+
12
+ type Story = StoryObj<typeof AvatarLayout>;
13
+
14
+ const sizes: AvatarLayoutProps['size'][] = [16, 24, 32, 40, 48, 56, 72];
15
+
16
+ export const Diagonal: Story = {
17
+ tags: ['autodocs'],
18
+ render: () => (
19
+ <div
20
+ style={{
21
+ gap: '1em',
22
+ display: 'grid',
23
+ justifyContent: 'center',
24
+ textAlign: 'center',
25
+ gridTemplate: `auto auto / repeat(${sizes.length}, min-content)`,
26
+ }}
27
+ >
28
+ {sizes.map((size) => (
29
+ <Body type="body-large-bold">{size}</Body>
30
+ ))}
31
+
32
+ {sizes.map((size) => (
33
+ <AvatarLayout
34
+ key={size}
35
+ size={size}
36
+ orientation="diagonal"
37
+ avatars={[{ asset: <Freeze /> }, { asset: <Freeze /> }]}
38
+ />
39
+ ))}
40
+
41
+ {sizes.map((size) => (
42
+ <AvatarLayout
43
+ key={size}
44
+ size={size}
45
+ orientation="diagonal"
46
+ interactive
47
+ avatars={[{ asset: <Freeze /> }, { asset: <Freeze /> }]}
48
+ />
49
+ ))}
50
+
51
+ {sizes.map((size) => (
52
+ <AvatarLayout
53
+ key={size}
54
+ size={size}
55
+ orientation="diagonal"
56
+ avatars={[{ profileName: 'Jay Jay' }, { profileName: 'Amy Amy' }]}
57
+ />
58
+ ))}
59
+
60
+ {sizes.map((size) => (
61
+ <AvatarLayout
62
+ key={size}
63
+ size={size}
64
+ orientation="diagonal"
65
+ interactive
66
+ avatars={[{ profileName: 'Jay Jay' }, { profileName: 'Amy Amy' }]}
67
+ />
68
+ ))}
69
+
70
+ {sizes.map((size) => (
71
+ <AvatarLayout
72
+ key={size}
73
+ size={size}
74
+ orientation="diagonal"
75
+ avatars={[{ asset: <Flag code="br" /> }, { asset: <Flag code="jp" /> }]}
76
+ />
77
+ ))}
78
+
79
+ {sizes.map((size) => (
80
+ <AvatarLayout
81
+ key={size}
82
+ size={size}
83
+ orientation="diagonal"
84
+ avatars={[{ asset: <Flag code="eu" /> }, { asset: <Flag code="eu" /> }]}
85
+ />
86
+ ))}
87
+
88
+ {sizes.map((size) => (
89
+ <AvatarLayout
90
+ key={size}
91
+ size={size}
92
+ orientation="diagonal"
93
+ avatars={[{ imgSrc: '../tapestry-01.png' }, { imgSrc: '../tapestry-01.png' }]}
94
+ />
95
+ ))}
96
+ </div>
97
+ ),
98
+ };
99
+
100
+ export const Horizontal: Story = {
101
+ tags: ['autodocs'],
102
+ render: () => (
103
+ <div
104
+ style={{
105
+ gap: '1em',
106
+ display: 'grid',
107
+ justifyContent: 'center',
108
+ textAlign: 'center',
109
+ gridTemplate: `auto auto / repeat(${sizes.length}, min-content)`,
110
+ }}
111
+ >
112
+ {sizes.map((size) => (
113
+ <Body type="body-large-bold">{size}</Body>
114
+ ))}
115
+
116
+ {sizes.map((size) => (
117
+ <AvatarLayout
118
+ key={size}
119
+ size={size}
120
+ orientation="horizontal"
121
+ avatars={[{ asset: <Freeze /> }, { asset: <Freeze /> }]}
122
+ />
123
+ ))}
124
+
125
+ {sizes.map((size) => (
126
+ <AvatarLayout
127
+ key={size}
128
+ size={size}
129
+ orientation="horizontal"
130
+ interactive
131
+ avatars={[{ asset: <Freeze /> }, { asset: <Freeze /> }]}
132
+ />
133
+ ))}
134
+
135
+ {sizes.map((size) => (
136
+ <AvatarLayout
137
+ key={size}
138
+ size={size}
139
+ orientation="horizontal"
140
+ avatars={[{ profileName: 'Jay Jay' }, { profileName: 'Amy Amy' }]}
141
+ />
142
+ ))}
143
+
144
+ {sizes.map((size) => (
145
+ <AvatarLayout
146
+ key={size}
147
+ size={size}
148
+ orientation="horizontal"
149
+ interactive
150
+ avatars={[{ profileName: 'Jay Jay' }, { profileName: 'Amy Amy' }]}
151
+ />
152
+ ))}
153
+
154
+ {sizes.map((size) => (
155
+ <AvatarLayout
156
+ key={size}
157
+ size={size}
158
+ orientation="horizontal"
159
+ avatars={[{ asset: <Flag code="br" /> }, { asset: <Flag code="jp" /> }]}
160
+ />
161
+ ))}
162
+
163
+ {sizes.map((size) => (
164
+ <AvatarLayout
165
+ key={size}
166
+ size={size}
167
+ orientation="horizontal"
168
+ avatars={[{ asset: <Flag code="eu" /> }, { asset: <Flag code="eu" /> }]}
169
+ />
170
+ ))}
171
+
172
+ {sizes.map((size) => (
173
+ <AvatarLayout
174
+ key={size}
175
+ size={size}
176
+ orientation="horizontal"
177
+ avatars={[{ imgSrc: '../tapestry-01.png' }, { imgSrc: '../tapestry-01.png' }]}
178
+ />
179
+ ))}
180
+ </div>
181
+ ),
182
+ };
183
+
184
+ export const EdgeInstances: Story = {
185
+ tags: ['autodocs'],
186
+ render: () => (
187
+ <div
188
+ style={{
189
+ gap: '1em',
190
+ display: 'grid',
191
+ justifyContent: 'space-between',
192
+ gridTemplate: `auto auto / repeat(2, min-content)`,
193
+ }}
194
+ >
195
+ <AvatarLayout orientation="diagonal" avatars={[]} />
196
+
197
+ <AvatarLayout orientation="diagonal" avatars={[{}]} />
198
+
199
+ <AvatarLayout orientation="diagonal" avatars={[{ profileName: 'Jay Jay' }]} />
200
+
201
+ <AvatarLayout orientation="diagonal" avatars={[{ asset: <Flag code="gb" /> }]} />
202
+
203
+ <AvatarLayout
204
+ orientation="diagonal"
205
+ avatars={[{ asset: <Flag code="gb" /> }, { asset: <Flag code="jp" /> }]}
206
+ />
207
+
208
+ <AvatarLayout
209
+ orientation="horizontal"
210
+ interactive
211
+ avatars={[
212
+ { imgSrc: '../avatar-squere-dude.webp' },
213
+ { asset: null, style: { border: '1px dashed var(--color-border-neutral)' } },
214
+ ]}
215
+ />
216
+
217
+ <AvatarLayout
218
+ orientation="horizontal"
219
+ interactive
220
+ avatars={[
221
+ { imgSrc: '../avatar-square-dude.webp' },
222
+ {
223
+ asset: <Plane />,
224
+ style: { backgroundColor: 'var(--color-bright-pink)' },
225
+ },
226
+ ]}
227
+ />
228
+
229
+ <AvatarLayout
230
+ orientation="horizontal"
231
+ interactive
232
+ avatars={[
233
+ {
234
+ asset: <Graph />,
235
+ style: { color: 'rgb(22, 51, 0)', backgroundColor: 'rgb(203, 217, 195)' },
236
+ },
237
+ {
238
+ asset: <Rewards />,
239
+ style: { color: 'rgb(203, 217, 195)', backgroundColor: 'rgb(22, 51, 0)' },
240
+ },
241
+ ]}
242
+ />
243
+
244
+ <AvatarLayout
245
+ orientation="horizontal"
246
+ interactive
247
+ avatars={[
248
+ { asset: <Flag code="gb" /> },
249
+ { asset: '3+', style: { border: '1px dashed var(--color-border-neutral)' } },
250
+ ]}
251
+ />
252
+
253
+ <AvatarLayout
254
+ orientation="horizontal"
255
+ avatars={[{ imgSrc: '../avatar-rectangle-fox.webp' }, { profileName: 'Jay Jay' }]}
256
+ />
257
+
258
+ <AvatarLayout
259
+ interactive
260
+ orientation="horizontal"
261
+ avatars={[
262
+ { imgSrc: '../avatar-rectangle-fox.webp' },
263
+ { imgSrc: '../avatar-square-dude.webp' },
264
+ { asset: '7+' },
265
+ ]}
266
+ />
267
+
268
+ <AvatarLayout
269
+ interactive
270
+ orientation="horizontal"
271
+ avatars={[{ asset: <Flag code="gb" /> }, { asset: <Flag code="br" /> }, { asset: '3+' }]}
272
+ />
273
+
274
+ <AvatarLayout
275
+ orientation="horizontal"
276
+ avatars={[
277
+ { asset: <Flag code="gb" /> },
278
+ { asset: <Flag code="br" /> },
279
+ { asset: <Flag code="jp" /> },
280
+ { asset: '3+' },
281
+ ]}
282
+ />
283
+ </div>
284
+ ),
285
+ };
@@ -0,0 +1,93 @@
1
+ import { clsx } from 'clsx';
2
+ import AvatarView, { AvatarViewProps } from '../avatarView';
3
+
4
+ type SingleAvatarType = { asset?: AvatarViewProps['children'] } & Omit<
5
+ AvatarViewProps,
6
+ 'notification' | 'selected' | 'size' | 'badge' | 'children' | 'interactive'
7
+ >;
8
+
9
+ export type Props = {
10
+ avatars: SingleAvatarType[];
11
+ orientation?: 'horizontal' | 'diagonal';
12
+ } & Pick<
13
+ AvatarViewProps,
14
+ 'size' | 'interactive' | 'className' | 'role' | 'aria-label' | 'aria-labelledby' | 'aria-hidden'
15
+ >;
16
+
17
+ export default function AvatarLayout({
18
+ avatars = [],
19
+ orientation: orientationProp = 'horizontal',
20
+ size = 48,
21
+ className,
22
+ interactive,
23
+ ...restProps
24
+ }: Props) {
25
+ const orientation =
26
+ size === 16 && orientationProp === 'diagonal' ? 'horizontal' : orientationProp;
27
+ const isDiagonal = orientation === 'diagonal';
28
+ const avatarSize = isDiagonal ? DIAGONAL_LAYOUT_STYLE_CONFIG[size]?.avatarSize : size;
29
+ return avatars.length < 1 ? null : avatars.length === 1 ? (
30
+ <AvatarView {...avatars[0]}>{avatars[0].asset}</AvatarView>
31
+ ) : (
32
+ <div
33
+ className={clsx('np-avatar-layout', `np-avatar-layout-${orientation}`, className)}
34
+ style={{
35
+ // @ts-expect-error CSS custom props allowed
36
+ '--np-avatar-layout-size': `${size}px`,
37
+ '--np-avatar-size': `${avatarSize}px`,
38
+ '--np-avatar-offset': `${isDiagonal ? DIAGONAL_LAYOUT_STYLE_CONFIG[size].offset : HORIZONTAL_LAYOUT_OFFSET[size]}px`,
39
+ }}
40
+ {...restProps}
41
+ >
42
+ {avatars.map(({ asset, style, ...avatar }, index) => (
43
+ <div
44
+ // eslint-disable-next-line react/no-array-index-key
45
+ key={index}
46
+ className={clsx(
47
+ { [`np-avatar-layout-${orientation}-child`]: index !== 0 },
48
+ { [`np-avatar-layout-${orientation}-mask`]: index !== avatars.length - 1 },
49
+ )}
50
+ >
51
+ <AvatarView
52
+ {...avatar}
53
+ size={avatarSize as Props['size']}
54
+ style={{
55
+ ...(isDiagonal && {
56
+ '--circle-size': `${avatarSize}px`,
57
+ '--circle-icon-size': `${DIAGONAL_LAYOUT_STYLE_CONFIG[size].iconSize}px`,
58
+ '--circle-font-size': `${DIAGONAL_LAYOUT_STYLE_CONFIG[size].fontSize}px`,
59
+ }),
60
+ ...style,
61
+ }}
62
+ interactive={interactive}
63
+ >
64
+ {asset}
65
+ </AvatarView>
66
+ </div>
67
+ ))}
68
+ </div>
69
+ );
70
+ }
71
+
72
+ /** Diagonal layout have custom sizes for avatar, font and icon */
73
+ const DIAGONAL_LAYOUT_STYLE_CONFIG = {
74
+ // Diagonal layout doesn't support 16 size
75
+ 16: { avatarSize: undefined, offset: undefined, fontSize: undefined, iconSize: undefined },
76
+ 24: { avatarSize: 15, offset: 2.5, fontSize: 8, iconSize: 11.25 },
77
+ 32: { avatarSize: 20, offset: 2.5, fontSize: 12, iconSize: 15 },
78
+ 40: { avatarSize: 24, offset: 4.5, fontSize: 12, iconSize: 18 },
79
+ 48: { avatarSize: 30, offset: 3.5, fontSize: 14, iconSize: 16.87 },
80
+ 56: { avatarSize: 34, offset: 5, fontSize: 14, iconSize: 19.12 },
81
+ 72: { avatarSize: 44, offset: 6, fontSize: 22, iconSize: 22 },
82
+ };
83
+
84
+ /** Horizontal layout have custom offset between avatars */
85
+ const HORIZONTAL_LAYOUT_OFFSET = {
86
+ 16: 2,
87
+ 24: 2,
88
+ 32: 4,
89
+ 40: 4,
90
+ 48: 4,
91
+ 56: 5,
92
+ 72: 5,
93
+ };
@@ -0,0 +1,2 @@
1
+ export type { Props as AvatarLayoutProps } from './AvatarLayout';
2
+ export { default } from './AvatarLayout';
@@ -4,7 +4,7 @@ import { ControlType, Type, Priority, Size } from '../common';
4
4
  import { render, screen, userEvent } from '../test-utils';
5
5
 
6
6
  import Button from '.';
7
- import messages from './Button.messages';
7
+ import messages from '../i18n/commonMessages/Button.messages';
8
8
  import { ButtonReferenceType } from './Button';
9
9
 
10
10
  const { ACCENT, POSITIVE, NEGATIVE } = ControlType;
@@ -19,7 +19,7 @@ import {
19
19
  } from '../common';
20
20
  import ProcessIndicator from '../processIndicator';
21
21
 
22
- import messages from './Button.messages';
22
+ import messages from '../i18n/commonMessages/Button.messages';
23
23
  import { typeClassMap, priorityClassMap } from './classMap';
24
24
  import { establishNewPriority, establishNewType, logDeprecationNotices } from './legacyUtils';
25
25
 
package/src/i18n/es.json CHANGED
@@ -35,6 +35,11 @@
35
35
  "neptune.Summary.statusDone": "Apartado listo",
36
36
  "neptune.Summary.statusNotDone": "Apartado a completar",
37
37
  "neptune.Summary.statusPending": "Apartado pendiente",
38
+ "neptune.Table.actionHeader": "Acción",
39
+ "neptune.Table.emptyData": "No se han encontrado resultados",
40
+ "neptune.Table.loaded": "Los datos de la tabla se han cargado",
41
+ "neptune.Table.loading": "Los datos de la tabla se están cargando",
42
+ "neptune.Table.refreshPage": "Actualizar página",
38
43
  "neptune.Upload.csButtonText": "¿Quieres subir otro archivo?",
39
44
  "neptune.Upload.csFailureText": "La carga del archivo ha fallado. Por favor, inténtalo de nuevo",
40
45
  "neptune.Upload.csSuccessText": "¡Se ha subido el archivo!",
package/src/i18n/pl.json CHANGED
@@ -35,6 +35,11 @@
35
35
  "neptune.Summary.statusDone": "Czynność wykonana",
36
36
  "neptune.Summary.statusNotDone": "Czynność do wykonania",
37
37
  "neptune.Summary.statusPending": "Czynność oczekująca",
38
+ "neptune.Table.actionHeader": "Akcja",
39
+ "neptune.Table.emptyData": "Nie znaleziono wyników",
40
+ "neptune.Table.loaded": "Wczytano dane tabeli",
41
+ "neptune.Table.loading": "Wczytywanie danych tabeli",
42
+ "neptune.Table.refreshPage": "Odśwież stronę",
38
43
  "neptune.Upload.csButtonText": "Prześlij kolejny plik?",
39
44
  "neptune.Upload.csFailureText": "Przesyłanie nie powiodło się. Proszę spróbować ponownie",
40
45
  "neptune.Upload.csSuccessText": "Przesyłanie zakończone!",
package/src/i18n/ro.json CHANGED
@@ -35,6 +35,11 @@
35
35
  "neptune.Summary.statusDone": "Finalizat",
36
36
  "neptune.Summary.statusNotDone": "De făcut",
37
37
  "neptune.Summary.statusPending": "În așteptare",
38
+ "neptune.Table.actionHeader": "Acțiune",
39
+ "neptune.Table.emptyData": "Nu s-a găsit niciun rezultat",
40
+ "neptune.Table.loaded": "Datele din tabel au fost încărcate",
41
+ "neptune.Table.loading": "Datele din tabel se încarcă",
42
+ "neptune.Table.refreshPage": "Reîncarcă pagina",
38
43
  "neptune.Upload.csButtonText": "Încarci un alt fișier?",
39
44
  "neptune.Upload.csFailureText": "Încărcare eșuată. Te rugăm să încerci din nou",
40
45
  "neptune.Upload.csSuccessText": "Încărcare completă!",
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export type { SelectOptionProps, SelectOptionValue, SelectOptiopsSection } from
9
9
  export type { AlertAction, AlertProps, AlertType } from './alert';
10
10
  export type { AvatarProps } from './avatar';
11
11
  export type { AvatarViewProps } from './avatarView';
12
+ export type { AvatarLayoutProps } from './avatarLayout';
12
13
  export type { BadgeProps } from './badge';
13
14
  export type { CardProps } from './card';
14
15
  export type { CarouselProps } from './carousel';
@@ -105,6 +106,7 @@ export { default as SelectOption } from './selectOption';
105
106
  export { default as Alert } from './alert';
106
107
  export { default as Avatar } from './avatar';
107
108
  export { default as AvatarView } from './avatarView';
109
+ export { default as avatarLayout } from './avatarLayout';
108
110
  export { default as AvatarWrapper } from './avatarWrapper';
109
111
  export { default as Badge } from './badge';
110
112
  export { default as Body } from './body';
package/src/main.css CHANGED
@@ -505,6 +505,36 @@ div.critical-comms .critical-comms-body {
505
505
  .np-avatar-view-non-interactive .np-avatar-view-content .wds-flag {
506
506
  box-shadow: none;
507
507
  }
508
+ .np-avatar-layout {
509
+ display: inline-flex;
510
+ --np-avatar-layout-size: 48px;
511
+ --np-avatar-size: 32px;
512
+ }
513
+ .np-avatar-layout-diagonal {
514
+ width: var(--np-avatar-layout-size);
515
+ height: var(--np-avatar-layout-size);
516
+ }
517
+ .np-avatar-layout-diagonal-mask {
518
+ -webkit-mask-image: radial-gradient(circle at bottom calc(100% - var(--np-avatar-size) - var(--np-avatar-offset)) right calc(100% - var(--np-avatar-size) - var(--np-avatar-offset)), transparent 0, transparent calc(var(--np-avatar-size) / 2 + 2px), black 0);
519
+ mask-image: radial-gradient(circle at bottom calc(100% - var(--np-avatar-size) - var(--np-avatar-offset)) right calc(100% - var(--np-avatar-size) - var(--np-avatar-offset)), transparent 0, transparent calc(var(--np-avatar-size) / 2 + 2px), black 0);
520
+ }
521
+ .np-avatar-layout-diagonal-child {
522
+ margin-left: calc(var(--np-avatar-layout-size) - var(--np-avatar-size) * 2);
523
+ margin-top: calc(var(--np-avatar-layout-size) - var(--np-avatar-size));
524
+ }
525
+ .np-avatar-layout-horizontal {
526
+ width: calc(var(--np-avatar-size) * 2 - var(--np-avatar-offset) - 2px);
527
+ height: var(--np-avatar-layout-size);
528
+ }
529
+ .np-avatar-layout-horizontal-mask {
530
+ -webkit-mask-image: radial-gradient(circle at top calc(100% - (var(--np-avatar-size) / 2)) left calc(100% + (var(--np-avatar-size) / 2) - var(--np-avatar-offset)), transparent, transparent calc(var(--np-avatar-size) / 2 + 2px), black 0);
531
+ mask-image: radial-gradient(circle at top calc(100% - (var(--np-avatar-size) / 2)) left calc(100% + (var(--np-avatar-size) / 2) - var(--np-avatar-offset)), transparent, transparent calc(var(--np-avatar-size) / 2 + 2px), black 0);
532
+ -webkit-mask-image: radial-gradient(circle at top calc(100% - calc(var(--np-avatar-size) / 2)) left calc(100% + calc(var(--np-avatar-size) / 2) - var(--np-avatar-offset)), transparent, transparent calc(var(--np-avatar-size) / 2 + 2px), black 0);
533
+ mask-image: radial-gradient(circle at top calc(100% - calc(var(--np-avatar-size) / 2)) left calc(100% + calc(var(--np-avatar-size) / 2) - var(--np-avatar-offset)), transparent, transparent calc(var(--np-avatar-size) / 2 + 2px), black 0);
534
+ }
535
+ .np-avatar-layout-horizontal-child {
536
+ margin-left: calc(var(--np-avatar-offset) * -1);
537
+ }
508
538
  .tw-badge {
509
539
  position: relative;
510
540
  display: inline-block;
package/src/main.less CHANGED
@@ -4,6 +4,7 @@
4
4
  @import "./alert/Alert.less";
5
5
  @import "./avatar/Avatar.less";
6
6
  @import "./avatarView/AvatarView.less";
7
+ @import "./avatarLayout/AvatarLayout.less";
7
8
  @import "./badge/Badge.less";
8
9
  @import "./button/Button.less";
9
10
  @import "./card/Card.less";
@@ -0,0 +1,2 @@
1
+ export { default } from './src';
2
+ export * from './src';
@@ -0,0 +1,122 @@
1
+ import React, { forwardRef, useCallback } from 'react';
2
+ import { clsx } from 'clsx';
3
+ import type { PrimitiveAnchorProps } from '..';
4
+
5
+ /**
6
+ * The Primitive `PrimitiveAnchor` component is customisable link element that can be
7
+ * used in various parts of the Wise Design System internally. It supports
8
+ * different states such as disabled and provides event handlers for common
9
+ * interactions like click, focus, blur, mouse enter, mouse leave, and key down.
10
+ *
11
+ * @see {@link PrimitiveAnchor} for further information.
12
+ * @see {@link https://storybook.wise.design/?path=/docs/primitive-anchor--docs|Storybook Wise Design}
13
+ */
14
+ const PrimitiveAnchor = forwardRef<HTMLAnchorElement, PrimitiveAnchorProps>(
15
+ (
16
+ {
17
+ children,
18
+ className,
19
+ href,
20
+ id,
21
+ disabled = false,
22
+ testId,
23
+ onClick,
24
+ onFocus,
25
+ onBlur,
26
+ onMouseEnter,
27
+ onMouseLeave,
28
+ onKeyDown,
29
+ ...props
30
+ },
31
+ ref,
32
+ ) => {
33
+ const anchorClasses = clsx(
34
+ 'wds-Anchor',
35
+ {
36
+ 'wds-Anchor--disabled': disabled,
37
+ },
38
+ className,
39
+ );
40
+
41
+ const handleClick = useCallback(
42
+ (event: React.MouseEvent<HTMLAnchorElement>) => {
43
+ if (disabled) {
44
+ event.preventDefault();
45
+ } else {
46
+ onClick?.(event);
47
+ }
48
+ },
49
+ [disabled, onClick],
50
+ );
51
+
52
+ const handleFocus = useCallback(
53
+ (event: React.FocusEvent<HTMLAnchorElement>) => {
54
+ onFocus?.(event);
55
+ },
56
+ [onFocus],
57
+ );
58
+
59
+ const handleBlur = useCallback(
60
+ (event: React.FocusEvent<HTMLAnchorElement>) => {
61
+ onBlur?.(event);
62
+ },
63
+ [onBlur],
64
+ );
65
+
66
+ const handleMouseEnter = useCallback(
67
+ (event: React.MouseEvent<HTMLAnchorElement>) => {
68
+ onMouseEnter?.(event);
69
+ },
70
+ [onMouseEnter],
71
+ );
72
+
73
+ const handleMouseLeave = useCallback(
74
+ (event: React.MouseEvent<HTMLAnchorElement>) => {
75
+ onMouseLeave?.(event);
76
+ },
77
+ [onMouseLeave],
78
+ );
79
+
80
+ const handleKeyDown = useCallback(
81
+ (event: React.KeyboardEvent<HTMLAnchorElement>) => {
82
+ onKeyDown?.(event);
83
+ },
84
+ [onKeyDown],
85
+ );
86
+
87
+ /**
88
+ * The following props are set to handle the `disabled` state for the link:
89
+ *
90
+ * - `aria-disabled`: Exposes the link as disabled to assistive technologies.
91
+ * - `href`: Removed when `disabled` is true to prevent navigation.
92
+ * - `role`: Set to 'link' when `disabled` is true to ensure the element
93
+ * is still exposed as a link.
94
+ *
95
+ * For more details, refer to Scott O'Hara's article on disabling links:
96
+ * https://www.scottohara.me/blog/2021/05/28/disabled-links.html
97
+ */
98
+ const anchorProps = {
99
+ 'aria-disabled': disabled,
100
+ className: anchorClasses,
101
+ 'data-testid': testId,
102
+ href: disabled ? undefined : href,
103
+ id,
104
+ ref,
105
+ role: disabled ? 'link' : undefined,
106
+ rel: props.target === '_blank' ? 'noopener noreferrer' : undefined,
107
+ onClick: handleClick,
108
+ onFocus: handleFocus,
109
+ onBlur: handleBlur,
110
+ onMouseEnter: handleMouseEnter,
111
+ onMouseLeave: handleMouseLeave,
112
+ onKeyDown: handleKeyDown,
113
+ ...props,
114
+ };
115
+
116
+ return <a {...anchorProps}>{children}</a>;
117
+ },
118
+ );
119
+
120
+ PrimitiveAnchor.displayName = 'PrimitiveAnchor';
121
+
122
+ export default PrimitiveAnchor;
@@ -0,0 +1,28 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { BasePrimitiveProps, StyleProp } from '../..';
3
+
4
+ /**
5
+ * Type aliases for an anchor component.
6
+ */
7
+ export type PrimitiveAnchorAttributes = React.AnchorHTMLAttributes<HTMLAnchorElement>;
8
+ export type PrimitiveAnchorElementRef = React.Ref<HTMLAnchorElement>;
9
+
10
+ /**
11
+ * Properties for the anchor component.
12
+ */
13
+ export interface PrimitiveAnchorProps
14
+ extends BasePrimitiveProps,
15
+ StyleProp,
16
+ Omit<PrimitiveAnchorAttributes, 'role'> {
17
+ /** Content of the anchor */
18
+ children?: ReactNode;
19
+
20
+ /** The URL to navigate to when the anchor is clicked */
21
+ href: string;
22
+
23
+ /** Disable the anchor */
24
+ disabled?: boolean;
25
+
26
+ /** Reference to the anchor element */
27
+ ref?: PrimitiveAnchorElementRef;
28
+ }
@@ -0,0 +1,6 @@
1
+ export { default } from './PrimitiveAnchor';
2
+ export type {
3
+ PrimitiveAnchorProps,
4
+ PrimitiveAnchorAttributes,
5
+ PrimitiveAnchorElementRef,
6
+ } from './PrimitiveAnchor.types';