@transferwise/components 0.0.0-experimental-eec707b → 0.0.0-experimental-dc27730
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/index.esm.js +29 -90
- package/build/index.esm.js.map +1 -1
- package/build/index.js +32 -93
- package/build/index.js.map +1 -1
- package/build/types/avatarWrapper/AvatarWrapper.d.ts +18 -28
- package/build/types/avatarWrapper/AvatarWrapper.d.ts.map +1 -1
- package/build/types/avatarWrapper/index.d.ts +1 -1
- package/build/types/avatarWrapper/index.d.ts.map +1 -1
- package/build/types/badge/Badge.d.ts +2 -2
- package/build/types/badge/Badge.d.ts.map +1 -1
- package/build/types/badge/index.d.ts +2 -1
- package/build/types/badge/index.d.ts.map +1 -1
- package/build/types/common/index.d.ts +1 -1
- package/build/types/common/propsValues/profileType.d.ts +2 -0
- package/build/types/common/propsValues/profileType.d.ts.map +1 -1
- package/build/types/common/propsValues/sentiment.d.ts +1 -0
- package/build/types/common/propsValues/sentiment.d.ts.map +1 -1
- package/build/types/image/Image.d.ts +17 -21
- package/build/types/image/Image.d.ts.map +1 -1
- package/build/types/image/index.d.ts +1 -1
- package/build/types/image/index.d.ts.map +1 -1
- package/build/types/inlineAlert/InlineAlert.d.ts +12 -15
- package/build/types/inlineAlert/InlineAlert.d.ts.map +1 -1
- package/build/types/inlineAlert/index.d.ts +1 -1
- package/build/types/inlineAlert/index.d.ts.map +1 -1
- package/build/types/promoCard/PromoCard.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/avatarWrapper/AvatarWrapper.spec.tsx +105 -0
- package/src/avatarWrapper/AvatarWrapper.story.tsx +1 -41
- package/src/avatarWrapper/{AvatarWrapper.js → AvatarWrapper.tsx} +25 -56
- package/src/avatarWrapper/__snapshots__/{AvatarWrapper.spec.js.snap → AvatarWrapper.spec.tsx.snap} +76 -76
- package/src/badge/Badge.tsx +2 -2
- package/src/badge/index.ts +2 -0
- package/src/common/index.js +1 -1
- package/src/common/propsValues/profileType.ts +3 -0
- package/src/common/propsValues/sentiment.ts +10 -0
- package/src/image/{Image.spec.js → Image.spec.tsx} +5 -5
- package/src/image/{Image.story.js → Image.story.tsx} +3 -3
- package/src/image/Image.tsx +65 -0
- package/src/inlineAlert/{InlineAlert.story.js → InlineAlert.story.tsx} +3 -2
- package/src/inlineAlert/InlineAlert.tsx +59 -0
- package/src/promoCard/PromoCard.tsx +1 -6
- package/src/promoCard/__snapshots__/PromoCardGroup.spec.tsx.snap +2 -2
- package/src/avatarWrapper/AvatarWrapper.spec.js +0 -81
- package/src/badge/index.js +0 -1
- package/src/image/Image.js +0 -78
- package/src/inlineAlert/InlineAlert.js +0 -62
- /package/src/avatarWrapper/{index.js → index.ts} +0 -0
- /package/src/image/{index.js → index.ts} +0 -0
- /package/src/inlineAlert/{InlineAlert.spec.js → InlineAlert.spec.tsx} +0 -0
- /package/src/inlineAlert/{index.js → index.ts} +0 -0
package/src/avatarWrapper/__snapshots__/{AvatarWrapper.spec.js.snap → AvatarWrapper.spec.tsx.snap}
RENAMED
|
@@ -1,6 +1,79 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`FlowNavigationAvatar with a
|
|
3
|
+
exports[`FlowNavigationAvatar with a name AND profileType FlowNavigationAvatar with a name AND profileType AND avatar url renders the image 1`] = `
|
|
4
|
+
<div
|
|
5
|
+
class="tw-avatar tw-avatar--48 tw-avatar--thumbnail"
|
|
6
|
+
>
|
|
7
|
+
<div
|
|
8
|
+
class="tw-avatar__content"
|
|
9
|
+
>
|
|
10
|
+
<img
|
|
11
|
+
alt="avatar"
|
|
12
|
+
src="https://wise.com"
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
exports[`FlowNavigationAvatar with a name AND profileType FlowNavigationAvatar with a name AND profileType renders as BUSINESS profile type with an icon 1`] = `
|
|
19
|
+
<div
|
|
20
|
+
class="tw-avatar tw-avatar--48 tw-avatar--icon"
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
class="tw-avatar__content"
|
|
24
|
+
>
|
|
25
|
+
<span
|
|
26
|
+
aria-hidden="true"
|
|
27
|
+
class="tw-icon tw-icon-briefcase "
|
|
28
|
+
data-testid="briefcase-icon"
|
|
29
|
+
role="presentation"
|
|
30
|
+
>
|
|
31
|
+
<svg
|
|
32
|
+
fill="currentColor"
|
|
33
|
+
focusable="false"
|
|
34
|
+
height="24"
|
|
35
|
+
viewBox="0 0 24 24"
|
|
36
|
+
width="24"
|
|
37
|
+
>
|
|
38
|
+
<path
|
|
39
|
+
d="M21.428 6.429H18V3.857A.86.86 0 0 0 17.143 3H6.857A.86.86 0 0 0 6 3.857V6.43H2.571a.86.86 0 0 0-.857.857v12.857a.86.86 0 0 0 .857.857h18.857a.86.86 0 0 0 .858-.857V7.286a.86.86 0 0 0-.858-.857ZM7.714 4.714h8.572V6.43H7.714V4.714Zm8.572 3.429v11.143H7.714V8.143h8.572Zm-12.857 0H6v11.143H3.429V8.143ZM20.57 19.286H18V8.143h2.571v11.143Z"
|
|
40
|
+
/>
|
|
41
|
+
</svg>
|
|
42
|
+
</span>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
exports[`FlowNavigationAvatar with a name AND profileType FlowNavigationAvatar with a name AND profileType renders as PERSONAL profile type with an icon 1`] = `
|
|
48
|
+
<div
|
|
49
|
+
class="tw-avatar tw-avatar--48 tw-avatar--icon"
|
|
50
|
+
>
|
|
51
|
+
<div
|
|
52
|
+
class="tw-avatar__content"
|
|
53
|
+
>
|
|
54
|
+
<span
|
|
55
|
+
aria-hidden="true"
|
|
56
|
+
class="tw-icon tw-icon-person "
|
|
57
|
+
data-testid="person-icon"
|
|
58
|
+
role="presentation"
|
|
59
|
+
>
|
|
60
|
+
<svg
|
|
61
|
+
fill="currentColor"
|
|
62
|
+
focusable="false"
|
|
63
|
+
height="24"
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
width="24"
|
|
66
|
+
>
|
|
67
|
+
<path
|
|
68
|
+
d="M15.257 14.014A5.922 5.922 0 0 0 18 9c0-3.3-2.7-6-6-6S6 5.7 6 9c0 2.1 1.071 3.943 2.743 5.014-2.614 1.243-4.457 3.9-4.457 6.986H6c0-3.3 2.7-6 6-6s6 2.7 6 6h1.714c0-3.086-1.842-5.743-4.457-6.986ZM7.714 9A4.298 4.298 0 0 1 12 4.714 4.298 4.298 0 0 1 16.286 9 4.298 4.298 0 0 1 12 13.286 4.298 4.298 0 0 1 7.714 9Z"
|
|
69
|
+
/>
|
|
70
|
+
</svg>
|
|
71
|
+
</span>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
exports[`FlowNavigationAvatar with a name AND profileType with a badge status icon passed renders the badge 1`] = `
|
|
4
77
|
<div
|
|
5
78
|
class="tw-badge tw-badge-border-light tw-badge-sm"
|
|
6
79
|
>
|
|
@@ -64,7 +137,7 @@ exports[`FlowNavigationAvatar with a badge status icon passed renders the badge
|
|
|
64
137
|
</div>
|
|
65
138
|
`;
|
|
66
139
|
|
|
67
|
-
exports[`FlowNavigationAvatar with a badge url passed renders the badge 1`] = `
|
|
140
|
+
exports[`FlowNavigationAvatar with a name AND profileType with a badge url passed renders the badge 1`] = `
|
|
68
141
|
<div
|
|
69
142
|
class="tw-badge tw-badge-border-light tw-badge-lg"
|
|
70
143
|
>
|
|
@@ -109,80 +182,7 @@ exports[`FlowNavigationAvatar with a badge url passed renders the badge 1`] = `
|
|
|
109
182
|
</div>
|
|
110
183
|
`;
|
|
111
184
|
|
|
112
|
-
exports[`FlowNavigationAvatar with a name AND profileType
|
|
113
|
-
<div
|
|
114
|
-
class="tw-avatar tw-avatar--48 tw-avatar--thumbnail"
|
|
115
|
-
>
|
|
116
|
-
<div
|
|
117
|
-
class="tw-avatar__content"
|
|
118
|
-
>
|
|
119
|
-
<img
|
|
120
|
-
alt="avatar"
|
|
121
|
-
src="https://wise.com"
|
|
122
|
-
/>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
`;
|
|
126
|
-
|
|
127
|
-
exports[`FlowNavigationAvatar with a name AND profileType renders as BUSINESS profile type with an icon 1`] = `
|
|
128
|
-
<div
|
|
129
|
-
class="tw-avatar tw-avatar--48 tw-avatar--icon"
|
|
130
|
-
>
|
|
131
|
-
<div
|
|
132
|
-
class="tw-avatar__content"
|
|
133
|
-
>
|
|
134
|
-
<span
|
|
135
|
-
aria-hidden="true"
|
|
136
|
-
class="tw-icon tw-icon-briefcase "
|
|
137
|
-
data-testid="briefcase-icon"
|
|
138
|
-
role="presentation"
|
|
139
|
-
>
|
|
140
|
-
<svg
|
|
141
|
-
fill="currentColor"
|
|
142
|
-
focusable="false"
|
|
143
|
-
height="24"
|
|
144
|
-
viewBox="0 0 24 24"
|
|
145
|
-
width="24"
|
|
146
|
-
>
|
|
147
|
-
<path
|
|
148
|
-
d="M21.428 6.429H18V3.857A.86.86 0 0 0 17.143 3H6.857A.86.86 0 0 0 6 3.857V6.43H2.571a.86.86 0 0 0-.857.857v12.857a.86.86 0 0 0 .857.857h18.857a.86.86 0 0 0 .858-.857V7.286a.86.86 0 0 0-.858-.857ZM7.714 4.714h8.572V6.43H7.714V4.714Zm8.572 3.429v11.143H7.714V8.143h8.572Zm-12.857 0H6v11.143H3.429V8.143ZM20.57 19.286H18V8.143h2.571v11.143Z"
|
|
149
|
-
/>
|
|
150
|
-
</svg>
|
|
151
|
-
</span>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
`;
|
|
155
|
-
|
|
156
|
-
exports[`FlowNavigationAvatar with a name AND profileType renders as PERSONAL profile type with an icon 1`] = `
|
|
157
|
-
<div
|
|
158
|
-
class="tw-avatar tw-avatar--48 tw-avatar--icon"
|
|
159
|
-
>
|
|
160
|
-
<div
|
|
161
|
-
class="tw-avatar__content"
|
|
162
|
-
>
|
|
163
|
-
<span
|
|
164
|
-
aria-hidden="true"
|
|
165
|
-
class="tw-icon tw-icon-person "
|
|
166
|
-
data-testid="person-icon"
|
|
167
|
-
role="presentation"
|
|
168
|
-
>
|
|
169
|
-
<svg
|
|
170
|
-
fill="currentColor"
|
|
171
|
-
focusable="false"
|
|
172
|
-
height="24"
|
|
173
|
-
viewBox="0 0 24 24"
|
|
174
|
-
width="24"
|
|
175
|
-
>
|
|
176
|
-
<path
|
|
177
|
-
d="M15.257 14.014A5.922 5.922 0 0 0 18 9c0-3.3-2.7-6-6-6S6 5.7 6 9c0 2.1 1.071 3.943 2.743 5.014-2.614 1.243-4.457 3.9-4.457 6.986H6c0-3.3 2.7-6 6-6s6 2.7 6 6h1.714c0-3.086-1.842-5.743-4.457-6.986ZM7.714 9A4.298 4.298 0 0 1 12 4.714 4.298 4.298 0 0 1 16.286 9 4.298 4.298 0 0 1 12 13.286 4.298 4.298 0 0 1 7.714 9Z"
|
|
178
|
-
/>
|
|
179
|
-
</svg>
|
|
180
|
-
</span>
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
`;
|
|
184
|
-
|
|
185
|
-
exports[`FlowNavigationAvatar with nothing passed renders a personal icon 1`] = `
|
|
185
|
+
exports[`FlowNavigationAvatar with a name AND profileType with nothing passed renders a personal icon 1`] = `
|
|
186
186
|
<div
|
|
187
187
|
class="tw-avatar tw-avatar--48 tw-avatar--icon"
|
|
188
188
|
>
|
package/src/badge/Badge.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
CommonProps,
|
|
13
13
|
} from '../common';
|
|
14
14
|
|
|
15
|
-
type
|
|
15
|
+
export type BadgeProps = {
|
|
16
16
|
badge: ReactNode;
|
|
17
17
|
children: ReactNode;
|
|
18
18
|
size?: SizeSmall | SizeMedium | SizeLarge;
|
|
@@ -25,7 +25,7 @@ const Badge = ({
|
|
|
25
25
|
size = Size.SMALL,
|
|
26
26
|
border = Theme.LIGHT,
|
|
27
27
|
children,
|
|
28
|
-
}:
|
|
28
|
+
}: BadgeProps): ReactElement => {
|
|
29
29
|
const classes: string = classNames(
|
|
30
30
|
'tw-badge',
|
|
31
31
|
{
|
package/src/common/index.js
CHANGED
|
@@ -16,7 +16,7 @@ export * from './propsValues/position';
|
|
|
16
16
|
export { Layout } from './propsValues/layouts';
|
|
17
17
|
export * from './propsValues/status';
|
|
18
18
|
export { Sentiment } from './propsValues/sentiment';
|
|
19
|
-
export
|
|
19
|
+
export * from './propsValues/profileType';
|
|
20
20
|
export { Variant } from './propsValues/variant';
|
|
21
21
|
export * from './propsValues/scroll';
|
|
22
22
|
export { MarkdownNodeType } from './propsValues/markdownNodeType';
|
|
@@ -2,11 +2,11 @@ import '@testing-library/jest-dom';
|
|
|
2
2
|
import * as useHasIntersectedUtils from '../common/hooks/useHasIntersected/useHasIntersected';
|
|
3
3
|
import { render, fireEvent, screen } from '../test-utils';
|
|
4
4
|
|
|
5
|
-
import { EmptyTransparentImage } from './Image';
|
|
5
|
+
import { EmptyTransparentImage, ImageProps } from './Image';
|
|
6
6
|
|
|
7
7
|
import Image from '.';
|
|
8
8
|
|
|
9
|
-
const props = {
|
|
9
|
+
const props: ImageProps = {
|
|
10
10
|
id: 'id',
|
|
11
11
|
src: 'https://www.a-valid-src.png/',
|
|
12
12
|
alt: 'test',
|
|
@@ -23,7 +23,7 @@ describe('Image', () => {
|
|
|
23
23
|
it(`renders image`, () => {
|
|
24
24
|
render(<Image {...props} loading="eager" />);
|
|
25
25
|
|
|
26
|
-
const image = screen.getByRole('img');
|
|
26
|
+
const image: HTMLImageElement = screen.getByRole('img');
|
|
27
27
|
|
|
28
28
|
expect(image).toBeInTheDocument();
|
|
29
29
|
expect(image.src).toStrictEqual(props.src);
|
|
@@ -37,7 +37,7 @@ describe('Image', () => {
|
|
|
37
37
|
jest.spyOn(useHasIntersectedUtils, 'useHasIntersected').mockReturnValue([false]);
|
|
38
38
|
render(<Image {...props} />);
|
|
39
39
|
|
|
40
|
-
const image = screen.getByRole('img');
|
|
40
|
+
const image: HTMLImageElement = screen.getByRole('img');
|
|
41
41
|
|
|
42
42
|
expect(image).toBeInTheDocument();
|
|
43
43
|
expect(image.src).toStrictEqual(EmptyTransparentImage);
|
|
@@ -48,7 +48,7 @@ describe('Image', () => {
|
|
|
48
48
|
|
|
49
49
|
render(<Image {...props} />);
|
|
50
50
|
|
|
51
|
-
const image = screen.getByRole('img');
|
|
51
|
+
const image: HTMLImageElement = screen.getByRole('img');
|
|
52
52
|
|
|
53
53
|
expect(image).toBeInTheDocument();
|
|
54
54
|
expect(image.src).toStrictEqual(props.src);
|
|
@@ -33,7 +33,7 @@ export const Basic = () => {
|
|
|
33
33
|
shrink={shrink}
|
|
34
34
|
stretch={stretch}
|
|
35
35
|
onLoad={action('load 1')}
|
|
36
|
-
onError={
|
|
36
|
+
onError={action('error')}
|
|
37
37
|
/>
|
|
38
38
|
<Image
|
|
39
39
|
alt="test"
|
|
@@ -44,7 +44,7 @@ export const Basic = () => {
|
|
|
44
44
|
shrink={shrink}
|
|
45
45
|
stretch={stretch}
|
|
46
46
|
onLoad={action('load 2')}
|
|
47
|
-
onError={
|
|
47
|
+
onError={action('error')}
|
|
48
48
|
/>
|
|
49
49
|
<Image
|
|
50
50
|
alt="test"
|
|
@@ -55,7 +55,7 @@ export const Basic = () => {
|
|
|
55
55
|
shrink={shrink}
|
|
56
56
|
stretch={stretch}
|
|
57
57
|
onLoad={action('load 3')}
|
|
58
|
-
onError={
|
|
58
|
+
onError={action('error')}
|
|
59
59
|
/>
|
|
60
60
|
</>
|
|
61
61
|
);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import classnames from 'classnames';
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useHasIntersected } from '../common/hooks';
|
|
5
|
+
|
|
6
|
+
export interface ImageProps {
|
|
7
|
+
alt: string;
|
|
8
|
+
src: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
onLoad?: () => void;
|
|
11
|
+
onError?: () => void;
|
|
12
|
+
className?: string;
|
|
13
|
+
loading?: 'lazy' | 'eager';
|
|
14
|
+
stretch?: boolean;
|
|
15
|
+
role?: string;
|
|
16
|
+
shrink?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const EmptyTransparentImage =
|
|
20
|
+
'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
|
|
21
|
+
|
|
22
|
+
const Image = ({
|
|
23
|
+
id,
|
|
24
|
+
src,
|
|
25
|
+
alt,
|
|
26
|
+
onLoad,
|
|
27
|
+
onError,
|
|
28
|
+
className,
|
|
29
|
+
loading,
|
|
30
|
+
stretch = true,
|
|
31
|
+
role,
|
|
32
|
+
shrink = true,
|
|
33
|
+
}: ImageProps) => {
|
|
34
|
+
const elementReference = useRef<HTMLImageElement>(null);
|
|
35
|
+
const [hasIntersected] = useHasIntersected({ elRef: elementReference, loading });
|
|
36
|
+
let imageSource = src;
|
|
37
|
+
let imageOnLoad = onLoad;
|
|
38
|
+
|
|
39
|
+
if (loading === 'lazy' && !hasIntersected) {
|
|
40
|
+
imageSource = EmptyTransparentImage;
|
|
41
|
+
imageOnLoad = undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<img
|
|
46
|
+
ref={elementReference}
|
|
47
|
+
id={id}
|
|
48
|
+
alt={alt}
|
|
49
|
+
src={imageSource}
|
|
50
|
+
className={classnames([
|
|
51
|
+
'tw-image',
|
|
52
|
+
{
|
|
53
|
+
'tw-image__stretch': stretch,
|
|
54
|
+
'tw-image__shrink': shrink,
|
|
55
|
+
},
|
|
56
|
+
className,
|
|
57
|
+
])}
|
|
58
|
+
role={role}
|
|
59
|
+
onLoad={imageOnLoad}
|
|
60
|
+
onError={onError}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default Image;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { select, text } from '@storybook/addon-knobs';
|
|
2
|
+
import { Meta } from '@storybook/react';
|
|
2
3
|
|
|
3
4
|
import { Sentiment } from '../common';
|
|
4
5
|
import { Input } from '../inputs/Input';
|
|
5
6
|
|
|
6
|
-
import InlineAlert from './InlineAlert';
|
|
7
|
+
import InlineAlert, { InlineAlertProps } from './InlineAlert';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
component: InlineAlert,
|
|
10
11
|
title: 'Forms/InlineAlert',
|
|
11
|
-
}
|
|
12
|
+
} as Meta<InlineAlertProps>;
|
|
12
13
|
|
|
13
14
|
export const Basic = () => {
|
|
14
15
|
const type = select(
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { AlertCircle as AlertCircleIcon } from '@transferwise/icons';
|
|
2
|
+
import { useTheme } from '@wise/components-theming';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
import withArrow, { AlertArrowPosition } from '../alert/withArrow';
|
|
7
|
+
import { Sentiment } from '../common';
|
|
8
|
+
import { SentimentString } from '../common/propsValues/sentiment';
|
|
9
|
+
|
|
10
|
+
export interface InlineAlertProps {
|
|
11
|
+
id?: string;
|
|
12
|
+
type?: Sentiment | SentimentString;
|
|
13
|
+
className?: string;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const typeClassMap: Record<Sentiment.ERROR | Sentiment.NEGATIVE, string> = {
|
|
18
|
+
[Sentiment.ERROR]: 'danger',
|
|
19
|
+
[Sentiment.NEGATIVE]: 'danger',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const InlineAlert = ({ id, type = Sentiment.NEUTRAL, className, children }: InlineAlertProps) => {
|
|
23
|
+
const { isModern } = useTheme();
|
|
24
|
+
|
|
25
|
+
const typeClass = `alert-${typeClassMap[type as Sentiment.ERROR | Sentiment.NEGATIVE] || type}`;
|
|
26
|
+
|
|
27
|
+
if (isModern) {
|
|
28
|
+
return (
|
|
29
|
+
<div role="alert" id={id} className={classNames('alert alert-detach', typeClass, className)}>
|
|
30
|
+
{(type === 'error' || type === 'negative') && <AlertCircleIcon />}
|
|
31
|
+
<div>{children}</div>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const getAlertContents = ({
|
|
37
|
+
children,
|
|
38
|
+
className,
|
|
39
|
+
}: {
|
|
40
|
+
children: ReactNode;
|
|
41
|
+
className?: string;
|
|
42
|
+
}) => {
|
|
43
|
+
return (
|
|
44
|
+
<div
|
|
45
|
+
role="alert"
|
|
46
|
+
id={id}
|
|
47
|
+
className={classNames('alert alert-detach p-x-2 p-y-1', typeClass, className)}
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const AlertWithArrow = withArrow(getAlertContents, AlertArrowPosition.TOP_LEFT);
|
|
55
|
+
|
|
56
|
+
return <AlertWithArrow {...{ id, type, className, children }} />;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default InlineAlert;
|
|
@@ -326,12 +326,7 @@ const PromoCard: FunctionComponent<PromoCardProps> = forwardRef(
|
|
|
326
326
|
<Body className="np-Card-description">{description}</Body>
|
|
327
327
|
{imageSource && (
|
|
328
328
|
<div className={classNames('np-Card-image', { imageClass })}>
|
|
329
|
-
<Image
|
|
330
|
-
src={imageSource}
|
|
331
|
-
alt={imageAlt}
|
|
332
|
-
role={!imageAlt ? 'presentation' : null}
|
|
333
|
-
loading="lazy"
|
|
334
|
-
/>
|
|
329
|
+
<Image src={imageSource} alt={imageAlt || ''} loading="lazy" />
|
|
335
330
|
</div>
|
|
336
331
|
)}
|
|
337
332
|
<PromoCardIndicator label={indicatorLabel} icon={icon} />
|
|
@@ -31,8 +31,8 @@ exports[`PromoCardGroup matches snapshot 1`] = `
|
|
|
31
31
|
class="np-Card-image"
|
|
32
32
|
>
|
|
33
33
|
<img
|
|
34
|
+
alt=""
|
|
34
35
|
class="tw-image tw-image__stretch tw-image__shrink"
|
|
35
|
-
role="presentation"
|
|
36
36
|
src="https://via.placeholder.com/150"
|
|
37
37
|
/>
|
|
38
38
|
</div>
|
|
@@ -65,8 +65,8 @@ exports[`PromoCardGroup matches snapshot 1`] = `
|
|
|
65
65
|
class="np-Card-image"
|
|
66
66
|
>
|
|
67
67
|
<img
|
|
68
|
+
alt=""
|
|
68
69
|
class="tw-image tw-image__stretch tw-image__shrink"
|
|
69
|
-
role="presentation"
|
|
70
70
|
src="https://via.placeholder.com/150"
|
|
71
71
|
/>
|
|
72
72
|
</div>
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { Size } from '../common';
|
|
2
|
-
import { render, screen } from '../test-utils';
|
|
3
|
-
|
|
4
|
-
import Avatar from '.';
|
|
5
|
-
|
|
6
|
-
const name = 'Elizabeth Alexandra Mary Windsor';
|
|
7
|
-
|
|
8
|
-
describe('FlowNavigationAvatar', () => {
|
|
9
|
-
describe('with a name', () => {
|
|
10
|
-
it('shows the initials for a long name', () => {
|
|
11
|
-
render(<Avatar name={name} />);
|
|
12
|
-
|
|
13
|
-
expect(screen.getByText('EW')).toBeInTheDocument();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('shows the first letter for a mononym', () => {
|
|
17
|
-
render(<Avatar name="Michelangelo" />);
|
|
18
|
-
|
|
19
|
-
expect(screen.getByText('M')).toBeInTheDocument();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
describe('AND profileType', () => {
|
|
23
|
-
it('renders as BUSINESS profile type with an icon', async () => {
|
|
24
|
-
const { container } = render(<Avatar name={name} profileType="BUSINESS" />);
|
|
25
|
-
|
|
26
|
-
expect(container.firstChild).toMatchSnapshot();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('renders as PERSONAL profile type with an icon', async () => {
|
|
30
|
-
const { container } = render(<Avatar name={name} profileType="PERSONAL" />);
|
|
31
|
-
|
|
32
|
-
expect(container.firstChild).toMatchSnapshot();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('AND avatar url', () => {
|
|
36
|
-
it('renders the image', async () => {
|
|
37
|
-
const { container } = render(
|
|
38
|
-
<Avatar
|
|
39
|
-
url="https://wise.com"
|
|
40
|
-
name={name}
|
|
41
|
-
profileType="BUSINESS"
|
|
42
|
-
avatarProps={{ theme: 'dark' }}
|
|
43
|
-
/>,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
expect(container.firstChild).toMatchSnapshot();
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('with nothing passed', () => {
|
|
53
|
-
it('renders a personal icon', () => {
|
|
54
|
-
const { container } = render(<Avatar />);
|
|
55
|
-
|
|
56
|
-
expect(container.firstChild).toMatchSnapshot();
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('with a badge url passed', () => {
|
|
61
|
-
it('renders the badge', () => {
|
|
62
|
-
const { container } = render(
|
|
63
|
-
<Avatar
|
|
64
|
-
badgeUrl="https://badge.com"
|
|
65
|
-
badgeAltText="badge alt text"
|
|
66
|
-
badgeProps={{ size: Size.LARGE }}
|
|
67
|
-
/>,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
expect(container.firstChild).toMatchSnapshot();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe('with a badge status icon passed', () => {
|
|
75
|
-
it('renders the badge', () => {
|
|
76
|
-
const { container } = render(<Avatar badgeStatusIcon="positive" />);
|
|
77
|
-
|
|
78
|
-
expect(container.firstChild).toMatchSnapshot();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
});
|
package/src/badge/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Badge';
|
package/src/image/Image.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import classnames from 'classnames';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { useRef } from 'react';
|
|
4
|
-
|
|
5
|
-
import { useHasIntersected } from '../common/hooks';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Image component provides a wrapper for image tag. Optional lazy loading functionalities can also be enabled passing prop loading = "lazy.
|
|
9
|
-
* Once element intersects viewport image loads.
|
|
10
|
-
*
|
|
11
|
-
* @param {string} [alt=""] - string that contains the alt text. Required.
|
|
12
|
-
* @param {string} [src=""] - string that contains the src text. Required.
|
|
13
|
-
* @param {string} [id=""] - string that contains the id text.
|
|
14
|
-
* @param {Function} [onLoad=()=>{}] - function that contains load callback. Doesn't fire on SSR https://github.com/facebook/react/issues/15446
|
|
15
|
-
* @param {Function} [onError=()=>{}] - function that contains error callback. Doesn't fire on SSR https://github.com/facebook/react/issues/15446
|
|
16
|
-
* @param {boolean} [loading="lazy"] - This attribute follows the loading API attribute. If set to eager image will load immediately just like a normal image tag otherwise it will lazy load.
|
|
17
|
-
* @usage `<Image alt="alt" src="src" id="id1" onLoad={()=>{}} onError={())=>{}} loading="lazy" />`
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export const EmptyTransparentImage =
|
|
21
|
-
'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
|
|
22
|
-
|
|
23
|
-
const Image = ({ id, src, alt, onLoad, onError, className, loading, stretch, role, shrink }) => {
|
|
24
|
-
const elementReference = useRef();
|
|
25
|
-
const [hasIntersected] = useHasIntersected({ elRef: elementReference, loading });
|
|
26
|
-
let imageSource = src;
|
|
27
|
-
let imageOnLoad = onLoad;
|
|
28
|
-
|
|
29
|
-
if (loading === 'lazy' && !hasIntersected) {
|
|
30
|
-
imageSource = EmptyTransparentImage;
|
|
31
|
-
imageOnLoad = null;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<img
|
|
36
|
-
ref={elementReference}
|
|
37
|
-
id={id}
|
|
38
|
-
alt={alt}
|
|
39
|
-
src={imageSource}
|
|
40
|
-
className={classnames([
|
|
41
|
-
'tw-image',
|
|
42
|
-
{
|
|
43
|
-
'tw-image__stretch': stretch,
|
|
44
|
-
'tw-image__shrink': shrink,
|
|
45
|
-
},
|
|
46
|
-
className,
|
|
47
|
-
])}
|
|
48
|
-
role={role}
|
|
49
|
-
onLoad={imageOnLoad}
|
|
50
|
-
onError={onError}
|
|
51
|
-
/>
|
|
52
|
-
);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
Image.propTypes = {
|
|
56
|
-
id: PropTypes.string,
|
|
57
|
-
src: PropTypes.string.isRequired,
|
|
58
|
-
alt: PropTypes.string.isRequired,
|
|
59
|
-
onLoad: PropTypes.func,
|
|
60
|
-
onError: PropTypes.func,
|
|
61
|
-
className: PropTypes.string,
|
|
62
|
-
loading: PropTypes.oneOf(['lazy', 'eager']),
|
|
63
|
-
stretch: PropTypes.bool,
|
|
64
|
-
shrink: PropTypes.bool,
|
|
65
|
-
role: PropTypes.string,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
Image.defaultProps = {
|
|
69
|
-
id: null,
|
|
70
|
-
className: '',
|
|
71
|
-
onLoad: () => {},
|
|
72
|
-
onError: () => {},
|
|
73
|
-
loading: 'eager',
|
|
74
|
-
stretch: true,
|
|
75
|
-
shrink: true,
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export default Image;
|