@transferwise/components 46.71.3 → 46.71.4
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.
- package/build/avatar/Avatar.js +7 -2
- package/build/avatar/Avatar.js.map +1 -1
- package/build/avatar/Avatar.mjs +7 -2
- package/build/avatar/Avatar.mjs.map +1 -1
- package/build/badge/Badge.js +13 -2
- package/build/badge/Badge.js.map +1 -1
- package/build/badge/Badge.mjs +13 -2
- package/build/badge/Badge.mjs.map +1 -1
- package/build/circularButton/CircularButton.js +10 -2
- package/build/circularButton/CircularButton.js.map +1 -1
- package/build/circularButton/CircularButton.mjs +10 -2
- package/build/circularButton/CircularButton.mjs.map +1 -1
- package/build/common/circle/Circle.js +29 -0
- package/build/common/circle/Circle.js.map +1 -0
- package/build/common/circle/Circle.mjs +27 -0
- package/build/common/circle/Circle.mjs.map +1 -0
- package/build/inputs/SelectInput.js +5 -1
- package/build/inputs/SelectInput.js.map +1 -1
- package/build/inputs/SelectInput.mjs +5 -1
- package/build/inputs/SelectInput.mjs.map +1 -1
- package/build/main.css +7 -114
- package/build/moneyInput/MoneyInput.js +1 -1
- package/build/moneyInput/MoneyInput.js.map +1 -1
- package/build/moneyInput/MoneyInput.mjs +1 -1
- package/build/moneyInput/MoneyInput.mjs.map +1 -1
- package/build/statusIcon/StatusIcon.js +16 -3
- package/build/statusIcon/StatusIcon.js.map +1 -1
- package/build/statusIcon/StatusIcon.mjs +16 -3
- package/build/statusIcon/StatusIcon.mjs.map +1 -1
- package/build/styles/avatar/Avatar.css +0 -29
- package/build/styles/badge/Badge.css +0 -10
- package/build/styles/circularButton/CircularButton.css +0 -37
- package/build/styles/common/circle/Circle.css +7 -0
- package/build/styles/main.css +7 -114
- package/build/styles/statusIcon/StatusIcon.css +0 -33
- package/build/types/avatar/Avatar.d.ts.map +1 -1
- package/build/types/badge/Badge.d.ts +9 -2
- package/build/types/badge/Badge.d.ts.map +1 -1
- package/build/types/circularButton/CircularButton.d.ts.map +1 -1
- package/build/types/common/circle/Circle.d.ts +34 -0
- package/build/types/common/circle/Circle.d.ts.map +1 -0
- package/build/types/common/circle/index.d.ts +3 -0
- package/build/types/common/circle/index.d.ts.map +1 -0
- package/build/types/inputs/SelectInput.d.ts.map +1 -1
- package/build/types/statusIcon/StatusIcon.d.ts +1 -1
- package/build/types/statusIcon/StatusIcon.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/alert/Alert.spec.tsx +3 -1
- package/src/avatar/Avatar.css +0 -29
- package/src/avatar/Avatar.less +0 -12
- package/src/avatar/Avatar.tsx +9 -4
- package/src/avatarWrapper/AvatarWrapper.spec.tsx +3 -1
- package/src/avatarWrapper/__snapshots__/AvatarWrapper.spec.tsx.snap +22 -11
- package/src/badge/Badge.css +0 -10
- package/src/badge/Badge.less +0 -13
- package/src/badge/Badge.tsx +23 -3
- package/src/checkbox/Checkbox.spec.tsx +3 -1
- package/src/circularButton/CircularButton.css +0 -37
- package/src/circularButton/CircularButton.less +0 -27
- package/src/circularButton/CircularButton.spec.tsx +3 -1
- package/src/circularButton/CircularButton.tsx +10 -3
- package/src/circularButton/__snapshots__/CircularButton.spec.tsx.snap +20 -10
- package/src/common/circle/Circle.css +7 -0
- package/src/common/circle/Circle.less +6 -0
- package/src/common/circle/Circle.story.tsx +86 -0
- package/src/common/circle/Circle.tsx +46 -0
- package/src/common/circle/index.ts +2 -0
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +8 -4
- package/src/inlineAlert/InlineAlert.spec.tsx +3 -1
- package/src/inputs/SelectInput.story.tsx +2 -2
- package/src/inputs/SelectInput.tsx +6 -2
- package/src/main.css +7 -114
- package/src/main.less +1 -0
- package/src/moneyInput/MoneyInput.rtl.spec.tsx +1 -1
- package/src/moneyInput/MoneyInput.tsx +1 -1
- package/src/overlayHeader/__snapshots__/OverlayHeader.spec.tsx.snap +4 -2
- package/src/radio/__snapshots__/Radio.rtl.spec.tsx.snap +4 -2
- package/src/statusIcon/StatusIcon.css +0 -33
- package/src/statusIcon/StatusIcon.less +0 -24
- package/src/statusIcon/StatusIcon.spec.tsx +5 -3
- package/src/statusIcon/StatusIcon.tsx +17 -6
- package/src/summary/Summary.spec.tsx +3 -1
- package/src/typeahead/Typeahead.spec.js +3 -0
- package/src/upload/Upload.spec.js +3 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { storyConfig } from '../../test-utils';
|
|
3
|
+
import Circle from './Circle';
|
|
4
|
+
import { Profile } from '@transferwise/icons';
|
|
5
|
+
import { action } from '@storybook/addon-actions';
|
|
6
|
+
import { CircleProps } from '.';
|
|
7
|
+
import Body from '../../body';
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Internal/Circle',
|
|
11
|
+
component: Circle,
|
|
12
|
+
} satisfies Meta<typeof Circle>;
|
|
13
|
+
|
|
14
|
+
type Story = StoryObj<typeof Circle>;
|
|
15
|
+
|
|
16
|
+
export const Basic: Story = {
|
|
17
|
+
tags: ['autodocs'],
|
|
18
|
+
args: {
|
|
19
|
+
children: 'NP',
|
|
20
|
+
size: 40,
|
|
21
|
+
as: 'div',
|
|
22
|
+
className: 'bg-neutral',
|
|
23
|
+
},
|
|
24
|
+
render: (args) => {
|
|
25
|
+
return <Circle {...args} />;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Sizes: Story = storyConfig(
|
|
30
|
+
{
|
|
31
|
+
render: () => {
|
|
32
|
+
const content = <Profile size={16} />;
|
|
33
|
+
const sizes: CircleProps['size'][] = [32, 40, 48, 56, 72];
|
|
34
|
+
return (
|
|
35
|
+
<div
|
|
36
|
+
style={{
|
|
37
|
+
gap: '1em',
|
|
38
|
+
display: 'grid',
|
|
39
|
+
justifyContent: 'space-between',
|
|
40
|
+
gridTemplate: 'auto auto / repeat(5, min-content)',
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
{sizes.map((size) => (
|
|
44
|
+
<Circle key={size} size={size} className="bg-neutral">
|
|
45
|
+
{content}
|
|
46
|
+
</Circle>
|
|
47
|
+
))}
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{ variants: ['light', 'dark'] },
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
export const FixedSize: Story = storyConfig(
|
|
56
|
+
{
|
|
57
|
+
render: () => {
|
|
58
|
+
const size = 72;
|
|
59
|
+
const content = <Profile size={16} />;
|
|
60
|
+
return (
|
|
61
|
+
<div
|
|
62
|
+
style={{
|
|
63
|
+
gap: '1em',
|
|
64
|
+
display: 'grid',
|
|
65
|
+
justifyContent: 'space-between',
|
|
66
|
+
gridTemplate: 'auto auto / repeat(2, 180px)',
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<Body className="d-block">
|
|
70
|
+
Dynamic Size (<code>--size-{size}</code>)
|
|
71
|
+
</Body>
|
|
72
|
+
<Body className="d-block">
|
|
73
|
+
Fixed Size (<code>{size}px</code>)
|
|
74
|
+
</Body>
|
|
75
|
+
<Circle size={72} fixedSize={false} className="bg-neutral">
|
|
76
|
+
{content}
|
|
77
|
+
</Circle>
|
|
78
|
+
<Circle size={72} fixedSize className="bg-neutral">
|
|
79
|
+
{content}
|
|
80
|
+
</Circle>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{ variants: ['400%'] },
|
|
86
|
+
);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { HTMLAttributes, forwardRef } from 'react';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
|
|
4
|
+
export type ShapeSize = 16 | 24 | 32 | 40 | 48 | 56 | 64 | 72;
|
|
5
|
+
|
|
6
|
+
export type Props = {
|
|
7
|
+
/**
|
|
8
|
+
* Modify underlying element, `div` by default
|
|
9
|
+
*/
|
|
10
|
+
as?: React.ElementType;
|
|
11
|
+
/**
|
|
12
|
+
* Set size of the circle in px, `48` by default
|
|
13
|
+
*/
|
|
14
|
+
size?: ShapeSize;
|
|
15
|
+
/**
|
|
16
|
+
* When `true` will use the fixed size (`48px`) instead of the CSS spacing variable (`--size-*`)
|
|
17
|
+
* as those can be dynamic a at certain viewport sizes
|
|
18
|
+
*/
|
|
19
|
+
fixedSize?: boolean;
|
|
20
|
+
} & HTMLAttributes<HTMLDivElement>;
|
|
21
|
+
|
|
22
|
+
const Circle = forwardRef(function Circle(
|
|
23
|
+
{
|
|
24
|
+
as: Element = 'div',
|
|
25
|
+
children,
|
|
26
|
+
size = 48,
|
|
27
|
+
fixedSize = false,
|
|
28
|
+
className,
|
|
29
|
+
style,
|
|
30
|
+
...props
|
|
31
|
+
}: Props,
|
|
32
|
+
ref,
|
|
33
|
+
) {
|
|
34
|
+
return (
|
|
35
|
+
<Element
|
|
36
|
+
{...props}
|
|
37
|
+
ref={ref}
|
|
38
|
+
style={{ ...style, '--circle-size': fixedSize ? `${size}px` : `var(--size-${size})` }}
|
|
39
|
+
className={clsx('np-circle', 'd-flex align-items-center justify-content-center', className)}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
</Element>
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export default Circle;
|
|
@@ -21,10 +21,12 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
|
|
|
21
21
|
class="np-flow-header__right d-flex align-items-center justify-content-end order-2--lg"
|
|
22
22
|
>
|
|
23
23
|
<div
|
|
24
|
-
class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
24
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
25
|
+
style="--circle-size: 48px;"
|
|
25
26
|
>
|
|
26
27
|
<div
|
|
27
|
-
class="tw-avatar__content"
|
|
28
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar__content"
|
|
29
|
+
style="--circle-size: 48px;"
|
|
28
30
|
>
|
|
29
31
|
TM
|
|
30
32
|
</div>
|
|
@@ -136,10 +138,12 @@ exports[`FlowNavigation renders as expected 1`] = `
|
|
|
136
138
|
class="np-flow-header__right d-flex align-items-center justify-content-end order-2--lg"
|
|
137
139
|
>
|
|
138
140
|
<div
|
|
139
|
-
class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
141
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
142
|
+
style="--circle-size: 48px;"
|
|
140
143
|
>
|
|
141
144
|
<div
|
|
142
|
-
class="tw-avatar__content"
|
|
145
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar__content"
|
|
146
|
+
style="--circle-size: 48px;"
|
|
143
147
|
>
|
|
144
148
|
TM
|
|
145
149
|
</div>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { Sentiment } from '../common';
|
|
3
|
-
import { render, screen } from '../test-utils';
|
|
3
|
+
import { render, screen, mockMatchMedia } from '../test-utils';
|
|
4
4
|
|
|
5
5
|
import InlineAlert from './InlineAlert';
|
|
6
6
|
|
|
7
|
+
mockMatchMedia();
|
|
8
|
+
|
|
7
9
|
describe('InlineAlert', () => {
|
|
8
10
|
const message = 'Your card is on its way.';
|
|
9
11
|
|
|
@@ -208,8 +208,8 @@ export const Currencies: Story<Currency> = {
|
|
|
208
208
|
await userEvent.type(input, '{Backspace}{Backspace}');
|
|
209
209
|
await expect(within(screen.getByRole('listbox')).queryAllByRole('option')).toHaveLength(2);
|
|
210
210
|
|
|
211
|
-
await userEvent.type(input, '{Backspace}
|
|
212
|
-
await expect(input).toHaveAttribute('aria-activedescendant');
|
|
211
|
+
await userEvent.type(input, '{Backspace}e');
|
|
212
|
+
await expect(input).not.toHaveAttribute('aria-activedescendant');
|
|
213
213
|
});
|
|
214
214
|
},
|
|
215
215
|
};
|
|
@@ -546,8 +546,8 @@ function SelectInputOptions<T = string>({
|
|
|
546
546
|
listBoxLabelledBy,
|
|
547
547
|
}: SelectInputOptionsProps<T>) {
|
|
548
548
|
const intl = useIntl();
|
|
549
|
-
|
|
550
549
|
const controllerRef = filterable ? searchInputRef : listboxRef;
|
|
550
|
+
const [initialRender, setInitialRender] = useState(true);
|
|
551
551
|
|
|
552
552
|
const needle = useMemo(() => {
|
|
553
553
|
if (filterable) {
|
|
@@ -611,6 +611,10 @@ function SelectInputOptions<T = string>({
|
|
|
611
611
|
}
|
|
612
612
|
}, []);
|
|
613
613
|
|
|
614
|
+
useEffect(() => {
|
|
615
|
+
setInitialRender(false);
|
|
616
|
+
}, []);
|
|
617
|
+
|
|
614
618
|
const showStatus = resultsEmpty;
|
|
615
619
|
const statusId = useId();
|
|
616
620
|
const listboxId = useId();
|
|
@@ -635,7 +639,7 @@ function SelectInputOptions<T = string>({
|
|
|
635
639
|
className="np-select-input-options-container"
|
|
636
640
|
onAriaActiveDescendantChange={(value: React.AriaAttributes['aria-activedescendant']) => {
|
|
637
641
|
if (controllerRef.current != null) {
|
|
638
|
-
if (value != null) {
|
|
642
|
+
if (!initialRender && value != null) {
|
|
639
643
|
controllerRef.current.setAttribute('aria-activedescendant', value);
|
|
640
644
|
} else {
|
|
641
645
|
controllerRef.current.removeAttribute('aria-activedescendant');
|
package/src/main.css
CHANGED
|
@@ -207,27 +207,18 @@ div.critical-comms .critical-comms-body {
|
|
|
207
207
|
}
|
|
208
208
|
.tw-avatar {
|
|
209
209
|
position: relative;
|
|
210
|
-
border-radius: 50%;
|
|
211
210
|
-webkit-user-select: none;
|
|
212
211
|
-moz-user-select: none;
|
|
213
212
|
user-select: none;
|
|
214
213
|
box-sizing: border-box;
|
|
215
214
|
}
|
|
216
215
|
.tw-avatar .tw-avatar__content {
|
|
217
|
-
align-items: center;
|
|
218
216
|
background-color: rgba(134,167,189,0.10196);
|
|
219
217
|
background-color: #86a7bd1a;
|
|
220
218
|
background-color: var(--color-background-neutral);
|
|
221
|
-
border-radius: 50%;
|
|
222
|
-
color: #37517e;
|
|
223
|
-
color: var(--color-content-primary);
|
|
224
|
-
display: flex;
|
|
225
|
-
height: 100%;
|
|
226
|
-
justify-content: center;
|
|
227
219
|
max-height: 100%;
|
|
228
220
|
max-width: 100%;
|
|
229
221
|
overflow: hidden;
|
|
230
|
-
width: 100%;
|
|
231
222
|
}
|
|
232
223
|
.tw-avatar--outlined {
|
|
233
224
|
border: 1px solid #00a2dd;
|
|
@@ -270,11 +261,6 @@ div.critical-comms .critical-comms-body {
|
|
|
270
261
|
color: var(--color-dark-charcoal);
|
|
271
262
|
line-height: 1;
|
|
272
263
|
}
|
|
273
|
-
.tw-avatar--24 {
|
|
274
|
-
min-width: 24px;
|
|
275
|
-
width: 24px;
|
|
276
|
-
height: 24px;
|
|
277
|
-
}
|
|
278
264
|
.tw-avatar--24.tw-avatar--emoji,
|
|
279
265
|
.tw-avatar--24.tw-avatar--icon {
|
|
280
266
|
font-size: 12px;
|
|
@@ -305,11 +291,6 @@ div.critical-comms .critical-comms-body {
|
|
|
305
291
|
content: "";
|
|
306
292
|
border-radius: 50%;
|
|
307
293
|
}
|
|
308
|
-
.tw-avatar--40 {
|
|
309
|
-
min-width: 40px;
|
|
310
|
-
width: 40px;
|
|
311
|
-
height: 40px;
|
|
312
|
-
}
|
|
313
294
|
.tw-avatar--40.tw-avatar--emoji,
|
|
314
295
|
.tw-avatar--40.tw-avatar--icon {
|
|
315
296
|
font-size: 20px;
|
|
@@ -340,11 +321,6 @@ div.critical-comms .critical-comms-body {
|
|
|
340
321
|
content: "";
|
|
341
322
|
border-radius: 50%;
|
|
342
323
|
}
|
|
343
|
-
.tw-avatar--48 {
|
|
344
|
-
min-width: 48px;
|
|
345
|
-
width: 48px;
|
|
346
|
-
height: 48px;
|
|
347
|
-
}
|
|
348
324
|
.tw-avatar--48.tw-avatar--emoji,
|
|
349
325
|
.tw-avatar--48.tw-avatar--icon {
|
|
350
326
|
font-size: 24px;
|
|
@@ -375,11 +351,6 @@ div.critical-comms .critical-comms-body {
|
|
|
375
351
|
content: "";
|
|
376
352
|
border-radius: 50%;
|
|
377
353
|
}
|
|
378
|
-
.tw-avatar--56 {
|
|
379
|
-
min-width: 56px;
|
|
380
|
-
width: 56px;
|
|
381
|
-
height: 56px;
|
|
382
|
-
}
|
|
383
354
|
.tw-avatar--56.tw-avatar--emoji,
|
|
384
355
|
.tw-avatar--56.tw-avatar--icon {
|
|
385
356
|
font-size: 28px;
|
|
@@ -410,11 +381,6 @@ div.critical-comms .critical-comms-body {
|
|
|
410
381
|
content: "";
|
|
411
382
|
border-radius: 50%;
|
|
412
383
|
}
|
|
413
|
-
.tw-avatar--72 {
|
|
414
|
-
min-width: 72px;
|
|
415
|
-
width: 72px;
|
|
416
|
-
height: 72px;
|
|
417
|
-
}
|
|
418
384
|
.tw-avatar--72.tw-avatar--emoji,
|
|
419
385
|
.tw-avatar--72.tw-avatar--icon {
|
|
420
386
|
font-size: 36px;
|
|
@@ -463,10 +429,6 @@ div.critical-comms .critical-comms-body {
|
|
|
463
429
|
--badge-mask-offset: calc(var(--badge-size) / 2);
|
|
464
430
|
--badge-border-color: rgba(255, 255, 255, 0.08);
|
|
465
431
|
}
|
|
466
|
-
.tw-badge.tw-badge-md {
|
|
467
|
-
--badge-size: 20px;
|
|
468
|
-
--badge-mask: 2px;
|
|
469
|
-
}
|
|
470
432
|
.tw-badge.tw-badge-lg {
|
|
471
433
|
--badge-size: 24px;
|
|
472
434
|
--badge-mask: 3px;
|
|
@@ -484,16 +446,10 @@ div.critical-comms .critical-comms-body {
|
|
|
484
446
|
}
|
|
485
447
|
.tw-badge > .tw-badge__content {
|
|
486
448
|
position: absolute;
|
|
487
|
-
width: var(--badge-size);
|
|
488
|
-
height: var(--badge-size);
|
|
489
449
|
bottom: 0;
|
|
490
450
|
right: 0;
|
|
491
451
|
box-sizing: border-box;
|
|
492
|
-
border-radius: 50%;
|
|
493
452
|
text-align: center;
|
|
494
|
-
display: flex;
|
|
495
|
-
align-items: center;
|
|
496
|
-
justify-content: center;
|
|
497
453
|
overflow: hidden;
|
|
498
454
|
-webkit-user-select: none;
|
|
499
455
|
-moz-user-select: none;
|
|
@@ -1029,36 +985,6 @@ div.critical-comms .critical-comms-body {
|
|
|
1029
985
|
cursor: pointer;
|
|
1030
986
|
position: relative;
|
|
1031
987
|
}
|
|
1032
|
-
.np-circular-btn input[type="button"] {
|
|
1033
|
-
min-height: 40px;
|
|
1034
|
-
min-height: var(--size-40);
|
|
1035
|
-
width: 40px;
|
|
1036
|
-
width: var(--size-40);
|
|
1037
|
-
height: 40px;
|
|
1038
|
-
height: var(--size-40);
|
|
1039
|
-
padding: 0;
|
|
1040
|
-
border-radius: 50%;
|
|
1041
|
-
margin-bottom: 8px;
|
|
1042
|
-
margin-bottom: var(--size-8);
|
|
1043
|
-
}
|
|
1044
|
-
.np-theme-personal .np-circular-btn input[type="button"] {
|
|
1045
|
-
min-height: 56px;
|
|
1046
|
-
min-height: var(--size-56);
|
|
1047
|
-
width: 56px;
|
|
1048
|
-
width: var(--size-56);
|
|
1049
|
-
height: 56px;
|
|
1050
|
-
height: var(--size-56);
|
|
1051
|
-
}
|
|
1052
|
-
@media (max-width: 320px) {
|
|
1053
|
-
.np-theme-personal .np-circular-btn input[type="button"] {
|
|
1054
|
-
min-height: 64px;
|
|
1055
|
-
min-height: var(--size-64);
|
|
1056
|
-
width: 64px;
|
|
1057
|
-
width: var(--size-64);
|
|
1058
|
-
height: 64px;
|
|
1059
|
-
height: var(--size-64);
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
988
|
.np-circular-btn .tw-icon {
|
|
1063
989
|
position: absolute;
|
|
1064
990
|
top: 16px;
|
|
@@ -1099,13 +1025,6 @@ div.critical-comms .critical-comms-body {
|
|
|
1099
1025
|
.np-theme-personal .np-circular-btn.negative.secondary:not(.disabled):not(:disabled) .tw-icon {
|
|
1100
1026
|
color: var(--color-sentiment-negative) !important;
|
|
1101
1027
|
}
|
|
1102
|
-
.np-circular-btn__label {
|
|
1103
|
-
transition: color 0.15s ease-in-out;
|
|
1104
|
-
font-size: 0.875rem;
|
|
1105
|
-
font-size: var(--font-size-14);
|
|
1106
|
-
font-weight: 600;
|
|
1107
|
-
font-weight: var(--font-weight-semi-bold);
|
|
1108
|
-
}
|
|
1109
1028
|
.np-circular-btn.accent .np-circular-btn__label {
|
|
1110
1029
|
color: #00a2dd;
|
|
1111
1030
|
color: var(--color-interactive-accent);
|
|
@@ -1232,6 +1151,13 @@ div.critical-comms .critical-comms-body {
|
|
|
1232
1151
|
.np-theme-personal .np-circular-btn.negative.secondary:active input[type="button"] + .tw-icon {
|
|
1233
1152
|
color: var(--color-interactive-control);
|
|
1234
1153
|
}
|
|
1154
|
+
.np-circle {
|
|
1155
|
+
border-radius: 9999px;
|
|
1156
|
+
border-radius: var(--radius-full);
|
|
1157
|
+
width: var(--circle-size);
|
|
1158
|
+
height: var(--circle-size);
|
|
1159
|
+
flex-shrink: 0;
|
|
1160
|
+
}
|
|
1235
1161
|
.np-bottom-sheet {
|
|
1236
1162
|
border-radius: 10px 10px 0 0;
|
|
1237
1163
|
}
|
|
@@ -4224,13 +4150,6 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
4224
4150
|
width: 32px;
|
|
4225
4151
|
width: var(--size-32);
|
|
4226
4152
|
}
|
|
4227
|
-
.status-circle {
|
|
4228
|
-
border-radius: 50%;
|
|
4229
|
-
display: flex;
|
|
4230
|
-
align-items: center;
|
|
4231
|
-
justify-content: center;
|
|
4232
|
-
flex-shrink: 0;
|
|
4233
|
-
}
|
|
4234
4153
|
.status-circle .light {
|
|
4235
4154
|
color: var(--color-contrast);
|
|
4236
4155
|
}
|
|
@@ -4246,24 +4165,6 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
4246
4165
|
.np-theme-personal .status-circle.pending .status-icon {
|
|
4247
4166
|
color: var(--color-dark);
|
|
4248
4167
|
}
|
|
4249
|
-
.status-circle-lg {
|
|
4250
|
-
width: 48px;
|
|
4251
|
-
width: var(--size-48);
|
|
4252
|
-
height: 48px;
|
|
4253
|
-
height: var(--size-48);
|
|
4254
|
-
}
|
|
4255
|
-
.status-circle-md {
|
|
4256
|
-
width: 40px;
|
|
4257
|
-
width: var(--size-40);
|
|
4258
|
-
height: 40px;
|
|
4259
|
-
height: var(--size-40);
|
|
4260
|
-
}
|
|
4261
|
-
.status-circle-sm {
|
|
4262
|
-
width: 16px;
|
|
4263
|
-
width: var(--size-16);
|
|
4264
|
-
height: 16px;
|
|
4265
|
-
height: var(--size-16);
|
|
4266
|
-
}
|
|
4267
4168
|
.status-circle-sm .status-icon > svg {
|
|
4268
4169
|
height: 14px;
|
|
4269
4170
|
height: var(--size-14);
|
|
@@ -4278,14 +4179,6 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
4278
4179
|
height: var(--size-24);
|
|
4279
4180
|
}
|
|
4280
4181
|
}
|
|
4281
|
-
@media (max-width: 320px) {
|
|
4282
|
-
.status-circle-sm {
|
|
4283
|
-
width: 32px;
|
|
4284
|
-
width: var(--size-32);
|
|
4285
|
-
height: 32px;
|
|
4286
|
-
height: var(--size-32);
|
|
4287
|
-
}
|
|
4288
|
-
}
|
|
4289
4182
|
.status-circle.negative,
|
|
4290
4183
|
.status-circle.error {
|
|
4291
4184
|
background-color: var(--color-sentiment-negative);
|
package/src/main.less
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
@import "./checkboxButton/CheckboxButton.less";
|
|
10
10
|
@import "./chips/Chip.less";
|
|
11
11
|
@import "./circularButton/CircularButton.less";
|
|
12
|
+
@import "./common/circle/Circle.less";
|
|
12
13
|
@import "./common/bottomSheet/BottomSheet.less";
|
|
13
14
|
@import "./common/card/Card.less";
|
|
14
15
|
@import "./common/closeButton/CloseButton.less";
|
|
@@ -81,7 +81,7 @@ describe('MoneyInput', () => {
|
|
|
81
81
|
</>,
|
|
82
82
|
);
|
|
83
83
|
|
|
84
|
-
expect(screen.
|
|
84
|
+
expect(screen.getAllByLabelText('Prioritized label')[0]).toHaveClass('input-group');
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
it('supports `Field` for labeling', () => {
|
|
@@ -391,7 +391,7 @@ class MoneyInput extends Component<MoneyInputPropsWithInputAttributes, MoneyInpu
|
|
|
391
391
|
UNSAFE_triggerButtonProps={{
|
|
392
392
|
id: undefined,
|
|
393
393
|
'aria-labelledby': undefined,
|
|
394
|
-
'aria-describedby':
|
|
394
|
+
'aria-describedby': ariaLabelledBy,
|
|
395
395
|
'aria-invalid': undefined,
|
|
396
396
|
'aria-label': this.props.intl.formatMessage(messages.selectCurrencyLabel),
|
|
397
397
|
}}
|
|
@@ -18,10 +18,12 @@ exports[`OverlayHeader renders as expected 1`] = `
|
|
|
18
18
|
class="d-flex align-items-center order-2"
|
|
19
19
|
>
|
|
20
20
|
<div
|
|
21
|
-
class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
21
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
22
|
+
style="--circle-size: 48px;"
|
|
22
23
|
>
|
|
23
24
|
<div
|
|
24
|
-
class="tw-avatar__content"
|
|
25
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar__content"
|
|
26
|
+
style="--circle-size: 48px;"
|
|
25
27
|
>
|
|
26
28
|
TM
|
|
27
29
|
</div>
|
|
@@ -34,10 +34,12 @@ exports[`Radio shows the avatar when supplied 1`] = `
|
|
|
34
34
|
class="np-radio__avatar m-l-auto"
|
|
35
35
|
>
|
|
36
36
|
<div
|
|
37
|
-
class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
37
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
|
|
38
|
+
style="--circle-size: 48px;"
|
|
38
39
|
>
|
|
39
40
|
<div
|
|
40
|
-
class="tw-avatar__content"
|
|
41
|
+
class="np-circle d-flex align-items-center justify-content-center tw-avatar__content"
|
|
42
|
+
style="--circle-size: 48px;"
|
|
41
43
|
>
|
|
42
44
|
HD
|
|
43
45
|
</div>
|
|
@@ -4,13 +4,6 @@
|
|
|
4
4
|
width: 32px;
|
|
5
5
|
width: var(--size-32);
|
|
6
6
|
}
|
|
7
|
-
.status-circle {
|
|
8
|
-
border-radius: 50%;
|
|
9
|
-
display: flex;
|
|
10
|
-
align-items: center;
|
|
11
|
-
justify-content: center;
|
|
12
|
-
flex-shrink: 0;
|
|
13
|
-
}
|
|
14
7
|
.status-circle .light {
|
|
15
8
|
color: var(--color-contrast);
|
|
16
9
|
}
|
|
@@ -26,24 +19,6 @@
|
|
|
26
19
|
.np-theme-personal .status-circle.pending .status-icon {
|
|
27
20
|
color: var(--color-dark);
|
|
28
21
|
}
|
|
29
|
-
.status-circle-lg {
|
|
30
|
-
width: 48px;
|
|
31
|
-
width: var(--size-48);
|
|
32
|
-
height: 48px;
|
|
33
|
-
height: var(--size-48);
|
|
34
|
-
}
|
|
35
|
-
.status-circle-md {
|
|
36
|
-
width: 40px;
|
|
37
|
-
width: var(--size-40);
|
|
38
|
-
height: 40px;
|
|
39
|
-
height: var(--size-40);
|
|
40
|
-
}
|
|
41
|
-
.status-circle-sm {
|
|
42
|
-
width: 16px;
|
|
43
|
-
width: var(--size-16);
|
|
44
|
-
height: 16px;
|
|
45
|
-
height: var(--size-16);
|
|
46
|
-
}
|
|
47
22
|
.status-circle-sm .status-icon > svg {
|
|
48
23
|
height: 14px;
|
|
49
24
|
height: var(--size-14);
|
|
@@ -58,14 +33,6 @@
|
|
|
58
33
|
height: var(--size-24);
|
|
59
34
|
}
|
|
60
35
|
}
|
|
61
|
-
@media (max-width: 320px) {
|
|
62
|
-
.status-circle-sm {
|
|
63
|
-
width: 32px;
|
|
64
|
-
width: var(--size-32);
|
|
65
|
-
height: 32px;
|
|
66
|
-
height: var(--size-32);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
36
|
.status-circle.negative,
|
|
70
37
|
.status-circle.error {
|
|
71
38
|
background-color: var(--color-sentiment-negative);
|
|
@@ -4,12 +4,6 @@
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
.status-circle {
|
|
7
|
-
border-radius: 50%;
|
|
8
|
-
display: flex;
|
|
9
|
-
align-items: center;
|
|
10
|
-
justify-content: center;
|
|
11
|
-
flex-shrink: 0;
|
|
12
|
-
|
|
13
7
|
.light {
|
|
14
8
|
color: var(--color-contrast);
|
|
15
9
|
}
|
|
@@ -29,20 +23,7 @@
|
|
|
29
23
|
}
|
|
30
24
|
}
|
|
31
25
|
|
|
32
|
-
&-lg {
|
|
33
|
-
width: var(--size-48);
|
|
34
|
-
height: var(--size-48);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
&-md {
|
|
38
|
-
width: var(--size-40);
|
|
39
|
-
height: var(--size-40);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
26
|
&-sm {
|
|
43
|
-
width: var(--size-16);
|
|
44
|
-
height: var(--size-16);
|
|
45
|
-
|
|
46
27
|
.status-icon > svg {
|
|
47
28
|
height: var(--size-14);
|
|
48
29
|
width: var(--size-14);
|
|
@@ -52,11 +33,6 @@
|
|
|
52
33
|
height: var(--size-24);
|
|
53
34
|
}
|
|
54
35
|
}
|
|
55
|
-
|
|
56
|
-
@media (--screen-400-zoom) {
|
|
57
|
-
width: var(--size-32);
|
|
58
|
-
height: var(--size-32);
|
|
59
|
-
}
|
|
60
36
|
}
|
|
61
37
|
}
|
|
62
38
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Sentiment, Size, SizeLarge, SizeMedium, SizeSmall } from '../common';
|
|
2
|
-
import { render, cleanup, screen } from '../test-utils';
|
|
2
|
+
import { render, cleanup, screen, mockMatchMedia } from '../test-utils';
|
|
3
3
|
|
|
4
4
|
import StatusIcon from '.';
|
|
5
5
|
|
|
6
|
+
mockMatchMedia();
|
|
7
|
+
|
|
6
8
|
describe('StatusIcon', () => {
|
|
7
9
|
const renderStatusIcon = (props?: {
|
|
8
10
|
sentiment?: Sentiment;
|
|
@@ -33,7 +35,7 @@ describe('StatusIcon', () => {
|
|
|
33
35
|
])(
|
|
34
36
|
"if prop 'size' equals '%s' is passed, renders the status icon with class '%s'",
|
|
35
37
|
(size, expectedClass) => {
|
|
36
|
-
renderStatusIcon({ size
|
|
38
|
+
renderStatusIcon({ size });
|
|
37
39
|
|
|
38
40
|
expect(screen.getByTestId('status-icon')).toHaveClass(expectedClass);
|
|
39
41
|
cleanup();
|
|
@@ -49,7 +51,7 @@ describe('StatusIcon', () => {
|
|
|
49
51
|
])(
|
|
50
52
|
"if prop 'sentiment' equals '%s' is passed, renders the status icon with class '%s'",
|
|
51
53
|
(sentiment, expectedClass) => {
|
|
52
|
-
renderStatusIcon({ sentiment
|
|
54
|
+
renderStatusIcon({ sentiment });
|
|
53
55
|
|
|
54
56
|
expect(screen.getByTestId('status-icon')).toHaveClass(expectedClass);
|
|
55
57
|
cleanup();
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Info, Alert, Cross, Check, ClockBorderless } from '@transferwise/icons';
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
|
|
4
|
-
import { SizeSmall, SizeMedium, SizeLarge, Sentiment } from '../common';
|
|
4
|
+
import { SizeSmall, SizeMedium, SizeLarge, Sentiment, Size, Breakpoint } from '../common';
|
|
5
|
+
import Circle, { CircleProps } from '../common/circle';
|
|
6
|
+
import { useMedia } from '../common/hooks/useMedia';
|
|
5
7
|
|
|
6
8
|
export type StatusIconProps = {
|
|
7
9
|
sentiment: `${Sentiment}`;
|
|
@@ -19,17 +21,26 @@ const iconTypeMap = {
|
|
|
19
21
|
success: Check,
|
|
20
22
|
} satisfies Record<`${Sentiment}`, React.ElementType>;
|
|
21
23
|
|
|
22
|
-
const
|
|
24
|
+
const mapLegacySize = {
|
|
25
|
+
[String(Size.SMALL)]: 16,
|
|
26
|
+
[String(Size.MEDIUM)]: 40,
|
|
27
|
+
[String(Size.LARGE)]: 48,
|
|
28
|
+
} satisfies Record<string, CircleProps['size']>;
|
|
29
|
+
|
|
30
|
+
const StatusIcon = ({ sentiment = 'neutral', size: sizeProp = 'md' }: StatusIconProps) => {
|
|
23
31
|
const Icon = iconTypeMap[sentiment];
|
|
24
32
|
const iconColor = sentiment === 'warning' || sentiment === 'pending' ? 'dark' : 'light';
|
|
25
|
-
|
|
33
|
+
const isTinyViewport = useMedia(`(max-width: ${Breakpoint.ZOOM_400}px)`);
|
|
34
|
+
const size = sizeProp === Size.SMALL && isTinyViewport ? 32 : mapLegacySize[sizeProp];
|
|
26
35
|
return (
|
|
27
|
-
<
|
|
36
|
+
<Circle
|
|
37
|
+
as="span"
|
|
38
|
+
size={size}
|
|
28
39
|
data-testid="status-icon"
|
|
29
|
-
className={clsx('status-circle', `status-circle-${
|
|
40
|
+
className={clsx('status-circle', `status-circle-${sizeProp}`, sentiment)}
|
|
30
41
|
>
|
|
31
42
|
<Icon className={clsx('status-icon', iconColor)} />
|
|
32
|
-
</
|
|
43
|
+
</Circle>
|
|
33
44
|
);
|
|
34
45
|
};
|
|
35
46
|
|