@transferwise/components 0.0.0-experimental-e7eccea → 0.0.0-experimental-696128b
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/avatarLayout/AvatarLayout.js +1 -2
- package/build/avatarLayout/AvatarLayout.js.map +1 -1
- package/build/avatarLayout/AvatarLayout.mjs +1 -2
- package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
- package/build/button/Button.js +3 -0
- package/build/button/Button.js.map +1 -1
- package/build/button/Button.mjs +3 -0
- package/build/button/Button.mjs.map +1 -1
- package/build/button/Button.resolver.js +8 -20
- package/build/button/Button.resolver.js.map +1 -1
- package/build/button/Button.resolver.mjs +8 -20
- package/build/button/Button.resolver.mjs.map +1 -1
- package/build/button/LegacyButton.js.map +1 -1
- package/build/button/LegacyButton.mjs.map +1 -1
- package/build/index.js +0 -2
- package/build/index.js.map +1 -1
- package/build/index.mjs +0 -1
- package/build/index.mjs.map +1 -1
- package/build/main.css +8 -5
- package/build/styles/avatarLayout/AvatarLayout.css +1 -2
- package/build/styles/button/Button.css +7 -3
- package/build/styles/main.css +8 -5
- package/build/types/avatarLayout/AvatarLayout.d.ts +2 -1
- package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -1
- package/build/types/avatarLayout/index.d.ts +0 -1
- package/build/types/avatarLayout/index.d.ts.map +1 -1
- package/build/types/button/Button.d.ts +2 -1
- package/build/types/button/Button.d.ts.map +1 -1
- package/build/types/button/Button.resolver.d.ts +29 -27
- package/build/types/button/Button.resolver.d.ts.map +1 -1
- package/build/types/button/Button.types.d.ts +8 -15
- package/build/types/button/Button.types.d.ts.map +1 -1
- package/build/types/button/LegacyButton.d.ts +4 -4
- package/build/types/button/LegacyButton.d.ts.map +1 -1
- package/build/types/index.d.ts +0 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts +1 -1
- package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts.map +1 -1
- package/build/types/uploadInput/uploadButton/getAllowedFileTypes.d.ts.map +1 -1
- package/build/uploadInput/uploadButton/getAllowedFileTypes.js +3 -23
- package/build/uploadInput/uploadButton/getAllowedFileTypes.js.map +1 -1
- package/build/uploadInput/uploadButton/getAllowedFileTypes.mjs +3 -23
- package/build/uploadInput/uploadButton/getAllowedFileTypes.mjs.map +1 -1
- package/package.json +3 -3
- package/src/avatarLayout/AvatarLayout.css +1 -2
- package/src/avatarLayout/AvatarLayout.less +1 -1
- package/src/avatarLayout/AvatarLayout.tsx +1 -2
- package/src/avatarLayout/index.ts +0 -1
- package/src/button/Button.css +7 -3
- package/src/button/Button.less +15 -11
- package/src/button/Button.resolver.tsx +10 -71
- package/src/button/Button.spec.tsx +1 -1
- package/src/button/Button.story.tsx +1 -2
- package/src/button/Button.tsx +9 -2
- package/src/button/Button.types.ts +9 -21
- package/src/button/LegacyButton.spec.tsx +2 -1
- package/src/button/LegacyButton.tsx +4 -5
- package/src/drawer/Drawer.rtl.spec.tsx +59 -0
- package/src/drawer/Drawer.spec.js +101 -0
- package/src/drawer/__snapshots__/Drawer.rtl.spec.tsx.snap +55 -0
- package/src/index.ts +0 -12
- package/src/main.css +8 -5
- package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.ts +1 -1
- package/src/uploadInput/UploadInput.tests.story.tsx +5 -5
- package/src/uploadInput/uploadButton/getAllowedFileTypes.spec.ts +0 -12
- package/src/uploadInput/uploadButton/getAllowedFileTypes.ts +7 -33
- package/build/table/Table.js +0 -166
- package/build/table/Table.js.map +0 -1
- package/build/table/Table.messages.js +0 -24
- package/build/table/Table.messages.js.map +0 -1
- package/build/table/Table.messages.mjs +0 -22
- package/build/table/Table.messages.mjs.map +0 -1
- package/build/table/Table.mjs +0 -164
- package/build/table/Table.mjs.map +0 -1
- package/build/table/TableCell.js +0 -86
- package/build/table/TableCell.js.map +0 -1
- package/build/table/TableCell.mjs +0 -84
- package/build/table/TableCell.mjs.map +0 -1
- package/build/table/TableHeader.js +0 -57
- package/build/table/TableHeader.js.map +0 -1
- package/build/table/TableHeader.mjs +0 -55
- package/build/table/TableHeader.mjs.map +0 -1
- package/build/table/TableRow.js +0 -85
- package/build/table/TableRow.js.map +0 -1
- package/build/table/TableRow.mjs +0 -83
- package/build/table/TableRow.mjs.map +0 -1
- package/build/table/TableStatusText.js +0 -54
- package/build/table/TableStatusText.js.map +0 -1
- package/build/table/TableStatusText.mjs +0 -52
- package/build/table/TableStatusText.mjs.map +0 -1
- package/src/drawer/Drawer.spec.tsx +0 -93
|
@@ -1,48 +1,12 @@
|
|
|
1
1
|
import { forwardRef } from 'react';
|
|
2
|
-
import LegacyButton, {
|
|
3
|
-
|
|
4
|
-
ButtonProps as LegacyButtonProps,
|
|
5
|
-
} from './LegacyButton';
|
|
6
|
-
import { ButtonProps as NewButtonProps } from './Button.types';
|
|
2
|
+
import LegacyButton, { LegacyButtonProps } from './LegacyButton';
|
|
3
|
+
import { ButtonReferenceType, ButtonProps as NewButtonProps } from './Button.types';
|
|
7
4
|
import NewButton from './Button';
|
|
8
5
|
|
|
9
|
-
type
|
|
10
|
-
| 'accent'
|
|
11
|
-
| 'negative'
|
|
12
|
-
| 'positive'
|
|
13
|
-
| 'primary'
|
|
14
|
-
| 'pay'
|
|
15
|
-
| 'secondary'
|
|
16
|
-
| 'danger'
|
|
17
|
-
| 'link'
|
|
18
|
-
| null
|
|
19
|
-
| undefined;
|
|
20
|
-
|
|
21
|
-
type NewButtonType = 'button' | 'submit' | 'reset' | LegacyButtonType | undefined;
|
|
22
|
-
|
|
23
|
-
type CommonButtonProps = {
|
|
24
|
-
href?: string;
|
|
25
|
-
target?: string;
|
|
26
|
-
ref?: React.Ref<HTMLButtonElement | HTMLAnchorElement>;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type ButtonProps =
|
|
30
|
-
| (Omit<LegacyButtonProps, 'ref'> &
|
|
31
|
-
CommonButtonProps & {
|
|
32
|
-
priority?: LegacyButtonProps['priority'];
|
|
33
|
-
type?: LegacyButtonType;
|
|
34
|
-
htmlType?: string;
|
|
35
|
-
v2?: false;
|
|
36
|
-
})
|
|
37
|
-
| (Omit<Omit<NewButtonProps, 'type'>, 'ref'> &
|
|
38
|
-
CommonButtonProps & {
|
|
39
|
-
priority?: NewButtonProps['priority'];
|
|
40
|
-
type?: NewButtonType;
|
|
41
|
-
v2: true;
|
|
42
|
-
});
|
|
6
|
+
export type ButtonProps = LegacyButtonProps | NewButtonProps;
|
|
43
7
|
|
|
44
8
|
const mapProps = (props: LegacyButtonProps): NewButtonProps => {
|
|
45
|
-
const { priority, size, type,
|
|
9
|
+
const { priority, size, type, ...newProps } = props;
|
|
46
10
|
|
|
47
11
|
const priorityMapping: Record<string, Record<string, NewButtonProps['priority']>> = {
|
|
48
12
|
accent: {
|
|
@@ -66,7 +30,7 @@ const mapProps = (props: LegacyButtonProps): NewButtonProps => {
|
|
|
66
30
|
type && priority ? priorityMapping[type]?.[priority] || priority : priority || undefined;
|
|
67
31
|
const mappedSentiment = type === 'negative' ? 'negative' : undefined;
|
|
68
32
|
|
|
69
|
-
const legacyButtonTypes:
|
|
33
|
+
const legacyButtonTypes: LegacyButtonProps['type'][] = [
|
|
70
34
|
'accent',
|
|
71
35
|
'negative',
|
|
72
36
|
'positive',
|
|
@@ -90,43 +54,18 @@ const mapProps = (props: LegacyButtonProps): NewButtonProps => {
|
|
|
90
54
|
size: resolveSize(),
|
|
91
55
|
priority: mappedPriority,
|
|
92
56
|
sentiment: mappedSentiment || ('sentiment' in props ? props.sentiment : null),
|
|
93
|
-
type:
|
|
94
|
-
|
|
95
|
-
v2: undefined,
|
|
57
|
+
type: type && !legacyButtonTypes.includes(type) ? type : props.htmlType || null,
|
|
58
|
+
v2: true,
|
|
96
59
|
} as NewButtonProps;
|
|
97
60
|
};
|
|
98
61
|
|
|
99
|
-
const Button = forwardRef<
|
|
100
|
-
const { v2 = false, as, ...rest } = props;
|
|
101
|
-
|
|
62
|
+
const Button = forwardRef<ButtonReferenceType, ButtonProps>(({ v2 = false, ...props }, ref) => {
|
|
102
63
|
if (v2) {
|
|
103
64
|
const mappedProps = mapProps(props as LegacyButtonProps);
|
|
104
|
-
return
|
|
105
|
-
<NewButton
|
|
106
|
-
{...mappedProps}
|
|
107
|
-
ref={ref as React.Ref<HTMLButtonElement | HTMLAnchorElement>}
|
|
108
|
-
as={as}
|
|
109
|
-
/>
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (as === 'a') {
|
|
114
|
-
return (
|
|
115
|
-
<LegacyButton
|
|
116
|
-
{...(rest as LegacyAnchorProps)}
|
|
117
|
-
ref={ref as React.Ref<HTMLAnchorElement>}
|
|
118
|
-
as="a"
|
|
119
|
-
/>
|
|
120
|
-
);
|
|
65
|
+
return <NewButton {...mappedProps} ref={ref} />;
|
|
121
66
|
}
|
|
122
67
|
|
|
123
|
-
return (
|
|
124
|
-
<LegacyButton
|
|
125
|
-
{...(rest as LegacyButtonProps)}
|
|
126
|
-
ref={ref as React.Ref<HTMLButtonElement>}
|
|
127
|
-
as="button"
|
|
128
|
-
/>
|
|
129
|
-
);
|
|
68
|
+
return <LegacyButton {...(props as LegacyButtonProps)} ref={ref} />;
|
|
130
69
|
});
|
|
131
70
|
|
|
132
71
|
Button.displayName = 'Button';
|
|
@@ -14,7 +14,6 @@ describe('Button', () => {
|
|
|
14
14
|
v2: true,
|
|
15
15
|
priority: 'primary',
|
|
16
16
|
size: 'md',
|
|
17
|
-
type: 'accent',
|
|
18
17
|
testId: 'new-button',
|
|
19
18
|
};
|
|
20
19
|
|
|
@@ -73,6 +72,7 @@ describe('Button', () => {
|
|
|
73
72
|
it('does not set type when type is in LegacyButtonType', () => {
|
|
74
73
|
const legacyTypeProps: ButtonProps = {
|
|
75
74
|
...newProps,
|
|
75
|
+
// @ts-expect-error here we intentionally set wrong value to test `type` attr in DOM
|
|
76
76
|
type: 'accent',
|
|
77
77
|
};
|
|
78
78
|
render(<Button {...legacyTypeProps}>Button Type</Button>);
|
|
@@ -240,7 +240,6 @@ const meta: Meta<typeof Button> = {
|
|
|
240
240
|
loading: false,
|
|
241
241
|
block: false,
|
|
242
242
|
href: undefined,
|
|
243
|
-
target: undefined,
|
|
244
243
|
as: undefined,
|
|
245
244
|
type: undefined,
|
|
246
245
|
iconStart: undefined,
|
|
@@ -753,5 +752,5 @@ export const AllVariants = storyConfig(
|
|
|
753
752
|
</div>
|
|
754
753
|
),
|
|
755
754
|
},
|
|
756
|
-
{ variants: ['default', 'dark', 'bright-green', 'forest-green'
|
|
755
|
+
{ variants: ['default', 'dark', 'bright-green', 'forest-green'] },
|
|
757
756
|
);
|
package/src/button/Button.tsx
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
/* eslint-disable react/display-name */
|
|
1
2
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
3
|
import { forwardRef } from 'react';
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AnchorElementProps,
|
|
6
|
+
ButtonReferenceType,
|
|
7
|
+
ButtonProps as NewButtonProps,
|
|
8
|
+
} from './Button.types';
|
|
4
9
|
import { PrimitiveAnchor, PrimitiveButton } from '../primitives';
|
|
5
10
|
import AvatarLayout from '../avatarLayout';
|
|
6
11
|
import ProcessIndicator from '../processIndicator';
|
|
@@ -8,7 +13,7 @@ import { clsx } from 'clsx';
|
|
|
8
13
|
import { Typography } from '../common';
|
|
9
14
|
import Body from '../body';
|
|
10
15
|
|
|
11
|
-
const Button = forwardRef<
|
|
16
|
+
const Button = forwardRef<ButtonReferenceType, NewButtonProps>(
|
|
12
17
|
(
|
|
13
18
|
{
|
|
14
19
|
as = 'button',
|
|
@@ -22,9 +27,11 @@ const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, NewButtonProps>
|
|
|
22
27
|
iconStart: IconStart,
|
|
23
28
|
iconEnd: IconEnd,
|
|
24
29
|
avatars,
|
|
30
|
+
// @ts-expect-error NewButtonProps has `type` prop
|
|
25
31
|
type = 'button',
|
|
26
32
|
loading = false,
|
|
27
33
|
block = false,
|
|
34
|
+
v2,
|
|
28
35
|
...props
|
|
29
36
|
},
|
|
30
37
|
ref,
|
|
@@ -1,27 +1,17 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
PrimitiveAnchorProps,
|
|
5
|
-
PrimitiveButtonElementRef,
|
|
6
|
-
PrimitiveAnchorElementRef,
|
|
7
|
-
} from '../primitives';
|
|
8
|
-
import type { SingleAvatarType } from '../avatarLayout';
|
|
2
|
+
import type { PrimitiveButtonProps, PrimitiveAnchorProps } from '../primitives';
|
|
3
|
+
import type { AvatarLayoutProps } from '../avatarLayout';
|
|
9
4
|
|
|
10
5
|
export type ButtonSentiment = 'default' | 'negative';
|
|
11
6
|
export type ButtonPriority = 'primary' | 'secondary' | 'tertiary' | 'minimal';
|
|
12
|
-
export type ButtonType = 'button' | 'submit' | 'reset';
|
|
13
7
|
export type ButtonSize = 'sm' | 'md' | 'lg';
|
|
14
|
-
export type
|
|
8
|
+
export type ButtonReferenceType = HTMLButtonElement | HTMLAnchorElement;
|
|
15
9
|
|
|
16
10
|
/**
|
|
17
11
|
* Common properties for the Button component.
|
|
18
12
|
*/
|
|
19
|
-
export interface
|
|
20
|
-
|
|
21
|
-
* If set, toggles the new Button API
|
|
22
|
-
* @default false
|
|
23
|
-
* */
|
|
24
|
-
v2?: boolean;
|
|
13
|
+
export interface CommonProps {
|
|
14
|
+
v2: true;
|
|
25
15
|
|
|
26
16
|
/**
|
|
27
17
|
* The HTML element to render
|
|
@@ -72,15 +62,13 @@ export interface CommonButtonProps {
|
|
|
72
62
|
iconEnd?: React.ElementType;
|
|
73
63
|
|
|
74
64
|
/** Media to be displayed on the left side of the button */
|
|
75
|
-
avatars?:
|
|
76
|
-
|
|
77
|
-
/** Optional property to provide component Ref */
|
|
78
|
-
ref?: ButtonRefType;
|
|
65
|
+
avatars?: AvatarLayoutProps['avatars'];
|
|
79
66
|
|
|
80
67
|
/** Content to be displayed inside the button */
|
|
81
68
|
children?: ReactNode;
|
|
82
69
|
}
|
|
83
70
|
|
|
84
|
-
export type ButtonElementProps = PrimitiveButtonProps &
|
|
85
|
-
export type AnchorElementProps = PrimitiveAnchorProps &
|
|
71
|
+
export type ButtonElementProps = PrimitiveButtonProps & CommonProps;
|
|
72
|
+
export type AnchorElementProps = PrimitiveAnchorProps & CommonProps;
|
|
73
|
+
|
|
86
74
|
export type ButtonProps = ButtonElementProps | AnchorElementProps;
|
|
@@ -2,8 +2,9 @@ import { createRef } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { render, screen, userEvent } from '../test-utils';
|
|
4
4
|
|
|
5
|
-
import LegacyButton
|
|
5
|
+
import LegacyButton from './LegacyButton';
|
|
6
6
|
import messages from '../i18n/commonMessages/Button.messages';
|
|
7
|
+
import { ButtonReferenceType } from './Button.types';
|
|
7
8
|
|
|
8
9
|
describe('LegacyButton', () => {
|
|
9
10
|
// eslint-disable-next-line no-console
|
|
@@ -22,6 +22,7 @@ import ProcessIndicator from '../processIndicator';
|
|
|
22
22
|
import messages from '../i18n/commonMessages/Button.messages';
|
|
23
23
|
import { typeClassMap, priorityClassMap } from './classMap';
|
|
24
24
|
import { establishNewPriority, establishNewType, logDeprecationNotices } from './legacyUtils';
|
|
25
|
+
import { ButtonReferenceType } from './Button.types';
|
|
25
26
|
|
|
26
27
|
/** @deprecated */
|
|
27
28
|
type DeprecatedTypes = 'primary' | 'pay' | 'secondary' | 'danger' | 'link';
|
|
@@ -30,22 +31,22 @@ type DeprecatedTypes = 'primary' | 'pay' | 'secondary' | 'danger' | 'link';
|
|
|
30
31
|
type DeprecatedSizes = SizeExtraSmall;
|
|
31
32
|
|
|
32
33
|
type CommonProps = {
|
|
34
|
+
v2?: false;
|
|
33
35
|
block?: boolean;
|
|
34
36
|
disabled?: boolean;
|
|
35
37
|
loading?: boolean;
|
|
36
|
-
/** @deprecated */
|
|
37
38
|
type?: ControlTypeAccent | ControlTypeNegative | ControlTypePositive | DeprecatedTypes | null;
|
|
38
39
|
priority?: PriorityPrimary | PrioritySecondary | PriorityTertiary | null;
|
|
39
40
|
size?: SizeSmall | SizeMedium | SizeLarge | DeprecatedSizes;
|
|
40
41
|
htmlType?: 'submit' | 'reset' | 'button';
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
type ButtonProps = CommonProps &
|
|
44
45
|
Omit<React.ComponentPropsWithRef<'button'>, 'type'> & {
|
|
45
46
|
as?: 'button';
|
|
46
47
|
};
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
type AnchorProps = CommonProps &
|
|
49
50
|
Omit<React.ComponentPropsWithRef<'a'>, 'type'> & {
|
|
50
51
|
as?: 'a';
|
|
51
52
|
href?: string;
|
|
@@ -53,8 +54,6 @@ export type AnchorProps = CommonProps &
|
|
|
53
54
|
|
|
54
55
|
export type LegacyButtonProps = ButtonProps | AnchorProps;
|
|
55
56
|
|
|
56
|
-
export type ButtonReferenceType = HTMLButtonElement | HTMLAnchorElement;
|
|
57
|
-
|
|
58
57
|
/**
|
|
59
58
|
* @deprecated make sure you use new Button component via `<Button v2 .. />` and new props
|
|
60
59
|
*/
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { DimmerProps } from '../dimmer';
|
|
2
|
+
import { SlidingPanelProps } from '../slidingPanel';
|
|
3
|
+
import { mockMatchMedia, render, screen, userEvent } from '../test-utils';
|
|
4
|
+
|
|
5
|
+
import Drawer from './Drawer';
|
|
6
|
+
|
|
7
|
+
mockMatchMedia();
|
|
8
|
+
|
|
9
|
+
jest.mock(
|
|
10
|
+
'../dimmer',
|
|
11
|
+
() =>
|
|
12
|
+
function Dimmer({ open, children }: DimmerProps) {
|
|
13
|
+
return open ? <div className="dimmer">{children}</div> : null;
|
|
14
|
+
},
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
jest.mock(
|
|
18
|
+
'../slidingPanel',
|
|
19
|
+
() =>
|
|
20
|
+
function SlidingPanel({ open, children }: SlidingPanelProps) {
|
|
21
|
+
return open ? <div className="sliding-panel">{children}</div> : null;
|
|
22
|
+
},
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
describe('Drawer', () => {
|
|
26
|
+
const props = {
|
|
27
|
+
onClose: jest.fn(),
|
|
28
|
+
open: true,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
jest.clearAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('renders content when open', () => {
|
|
36
|
+
const { container } = render(<Drawer {...props}>content</Drawer>);
|
|
37
|
+
|
|
38
|
+
expect(container).toMatchSnapshot();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("doesn't render content when closed", () => {
|
|
42
|
+
const { container } = render(
|
|
43
|
+
<Drawer {...props} open={false}>
|
|
44
|
+
content
|
|
45
|
+
</Drawer>,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(container).toMatchSnapshot();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('calls onClose when user clicks close button', async () => {
|
|
52
|
+
render(<Drawer {...props}>content</Drawer>);
|
|
53
|
+
expect(props.onClose).not.toHaveBeenCalled();
|
|
54
|
+
await userEvent.click(getCloseButton());
|
|
55
|
+
expect(props.onClose).toHaveBeenCalledTimes(1);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const getCloseButton = () => screen.getByLabelText('Close');
|
|
59
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { mount } from 'enzyme';
|
|
2
|
+
|
|
3
|
+
import { mockMatchMedia } from '../test-utils';
|
|
4
|
+
import Title from '../title/Title';
|
|
5
|
+
|
|
6
|
+
import Drawer from '.';
|
|
7
|
+
|
|
8
|
+
mockMatchMedia();
|
|
9
|
+
jest.mock('../common');
|
|
10
|
+
jest.useFakeTimers();
|
|
11
|
+
|
|
12
|
+
jest.mock(
|
|
13
|
+
'../dimmer',
|
|
14
|
+
() =>
|
|
15
|
+
function Dimmer({ open, children }) {
|
|
16
|
+
return open ? <div className="dimmer">{children}</div> : null;
|
|
17
|
+
},
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
jest.mock(
|
|
21
|
+
'../slidingPanel',
|
|
22
|
+
() =>
|
|
23
|
+
function SlidingPanel({ open, children }) {
|
|
24
|
+
return open ? <div className="sliding-panel">{children}</div> : null;
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const defaultLocale = 'en-GB';
|
|
29
|
+
|
|
30
|
+
jest.mock('react-intl', () => ({
|
|
31
|
+
injectIntl: (Component) =>
|
|
32
|
+
function InjectedComponent(props) {
|
|
33
|
+
return <Component {...props} intl={{ locale: defaultLocale }} />;
|
|
34
|
+
},
|
|
35
|
+
useIntl: () => ({ locale: defaultLocale, formatMessage: (id) => String(id) }),
|
|
36
|
+
defineMessages: (translations) => translations,
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
describe('Drawer', () => {
|
|
40
|
+
let component;
|
|
41
|
+
const props = {
|
|
42
|
+
open: true,
|
|
43
|
+
position: 'left',
|
|
44
|
+
onClose: jest.fn(),
|
|
45
|
+
children: null,
|
|
46
|
+
headerTitle: null,
|
|
47
|
+
footerContent: null,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
component = mount(<Drawer {...props} />);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
afterEach(() => {
|
|
55
|
+
jest.clearAllMocks();
|
|
56
|
+
component.unmount();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('renders drawer header if title is provided', () => {
|
|
60
|
+
expect(component.find('.np-drawer-header--title')).toHaveLength(0);
|
|
61
|
+
component.setProps({ headerTitle: 'A title' });
|
|
62
|
+
expect(component.find(Title)).toHaveLength(1);
|
|
63
|
+
expect(component.find(Title).props().children).toBe('A title');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('renders header with or without borders', () => {
|
|
67
|
+
expect(component.find('.np-drawer-header--withborder')).toHaveLength(0);
|
|
68
|
+
component.setProps({ headerTitle: 'A title' });
|
|
69
|
+
expect(component.find('.np-drawer-header--withborder')).toHaveLength(1);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('renders content if children are provided', () => {
|
|
73
|
+
expect(component.find('.np-drawer-content')).toHaveLength(0);
|
|
74
|
+
component.setProps({ children: 'SomeChildren' });
|
|
75
|
+
expect(component.find('.np-drawer-content')).toHaveLength(1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('renders drawer footer if footerContent is provided', () => {
|
|
79
|
+
expect(component.find('.np-drawer-footer')).toHaveLength(0);
|
|
80
|
+
component.setProps({ footerContent: 'SomeContent' });
|
|
81
|
+
expect(component.find('.np-drawer-footer')).toHaveLength(1);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('passes onUnmount to Dimmer onExited prop', () => {
|
|
85
|
+
const onUnmount = jest.fn();
|
|
86
|
+
component.setProps({ onUnmount });
|
|
87
|
+
component.setProps({ open: true });
|
|
88
|
+
expect(component.find('Dimmer').prop('onExited')).toBe(onUnmount);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('calls onUnmount when the component unmounts', () => {
|
|
92
|
+
const onUnmount = jest.fn();
|
|
93
|
+
component.setProps({ onUnmount });
|
|
94
|
+
component.setProps({ open: true });
|
|
95
|
+
expect(onUnmount).not.toHaveBeenCalled();
|
|
96
|
+
jest.runAllTimers();
|
|
97
|
+
component.setProps({ open: false });
|
|
98
|
+
component.find('Dimmer').prop('onExited')();
|
|
99
|
+
expect(onUnmount).toHaveBeenCalledTimes(1);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Drawer doesn't render content when closed 1`] = `<div />`;
|
|
4
|
+
|
|
5
|
+
exports[`Drawer renders content when open 1`] = `
|
|
6
|
+
<div>
|
|
7
|
+
<div
|
|
8
|
+
class="dimmer"
|
|
9
|
+
>
|
|
10
|
+
<div
|
|
11
|
+
class="sliding-panel"
|
|
12
|
+
>
|
|
13
|
+
<div
|
|
14
|
+
aria-modal="true"
|
|
15
|
+
class="np-drawer"
|
|
16
|
+
role="dialog"
|
|
17
|
+
>
|
|
18
|
+
<div
|
|
19
|
+
class="np-drawer-header"
|
|
20
|
+
>
|
|
21
|
+
<button
|
|
22
|
+
aria-label="Close"
|
|
23
|
+
class="np-close-button close btn-link text-no-decoration np-close-button--large"
|
|
24
|
+
type="button"
|
|
25
|
+
>
|
|
26
|
+
<span
|
|
27
|
+
class="tw-icon tw-icon-cross "
|
|
28
|
+
data-testid="cross-icon"
|
|
29
|
+
>
|
|
30
|
+
<svg
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
fill="currentColor"
|
|
33
|
+
focusable="false"
|
|
34
|
+
height="24"
|
|
35
|
+
role="none"
|
|
36
|
+
viewBox="0 0 24 24"
|
|
37
|
+
width="24"
|
|
38
|
+
>
|
|
39
|
+
<path
|
|
40
|
+
d="m19.629 5.915-1.2-1.2-6.257 6.257-6.258-6.257-1.2 1.2 6.258 6.257-6.258 6.257 1.2 1.2 6.258-6.257 6.257 6.257 1.2-1.2-6.258-6.257 6.258-6.257Z"
|
|
41
|
+
/>
|
|
42
|
+
</svg>
|
|
43
|
+
</span>
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
46
|
+
<div
|
|
47
|
+
class="np-drawer-content"
|
|
48
|
+
>
|
|
49
|
+
content
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
`;
|
package/src/index.ts
CHANGED
|
@@ -96,17 +96,6 @@ export type { UploadProps } from './upload';
|
|
|
96
96
|
export type { UploadError, UploadResponse, UploadedFile } from './uploadInput/types';
|
|
97
97
|
export type { WithIdProps } from './withId';
|
|
98
98
|
export type { IconButtonProps } from './iconButton';
|
|
99
|
-
export type {
|
|
100
|
-
TableProps,
|
|
101
|
-
TableRowType,
|
|
102
|
-
TableRowClickableType,
|
|
103
|
-
TableHeaderType,
|
|
104
|
-
TableCellLeading,
|
|
105
|
-
TableCellText,
|
|
106
|
-
TableCellCurrency,
|
|
107
|
-
TableCellStatus,
|
|
108
|
-
TableCellType,
|
|
109
|
-
} from './table';
|
|
110
99
|
|
|
111
100
|
/**
|
|
112
101
|
* Components
|
|
@@ -207,7 +196,6 @@ export { default as Tooltip } from './tooltip';
|
|
|
207
196
|
export { default as Typeahead } from './typeahead';
|
|
208
197
|
export { default as Upload } from './upload';
|
|
209
198
|
export { default as UploadInput } from './uploadInput';
|
|
210
|
-
export { default as Table } from './table';
|
|
211
199
|
|
|
212
200
|
/**
|
|
213
201
|
* Hooks
|
package/src/main.css
CHANGED
|
@@ -531,8 +531,7 @@ div.critical-comms .critical-comms-body {
|
|
|
531
531
|
margin-right: calc(var(--np-avatar-layout-size) - var(--np-avatar-size) * 2);
|
|
532
532
|
}
|
|
533
533
|
.np-avatar-layout-horizontal {
|
|
534
|
-
width: calc(var(--np-avatar-size) *
|
|
535
|
-
width: calc(var(--np-avatar-size) * var(--np-avatar-avatars-count) - calc(var(--np-avatar-offset) * calc(var(--np-avatar-avatars-count) - 1)));
|
|
534
|
+
width: calc(var(--np-avatar-size) * 2 - var(--np-avatar-offset));
|
|
536
535
|
height: var(--np-avatar-layout-size);
|
|
537
536
|
}
|
|
538
537
|
.np-avatar-layout-horizontal-mask {
|
|
@@ -901,6 +900,13 @@ div.critical-comms .critical-comms-body {
|
|
|
901
900
|
.wds-Button-loader .process-circle {
|
|
902
901
|
stroke: var(--Button-color);
|
|
903
902
|
}
|
|
903
|
+
/* RTL Styles */
|
|
904
|
+
[dir="rtl"] .wds-Button .tw-icon-chevron-right,[dir="rtl"] .wds-Button .tw-icon-arrow-right {
|
|
905
|
+
transform: rotate(180deg);
|
|
906
|
+
}
|
|
907
|
+
[dir="rtl"] .wds-Button .tw-icon-chevron-left,[dir="rtl"] .wds-Button .tw-icon-arrow-left {
|
|
908
|
+
transform: rotate(180deg);
|
|
909
|
+
}
|
|
904
910
|
/* Avatar border transparency */
|
|
905
911
|
/* dark buttons get 20% transparency, light buttons get 12% */
|
|
906
912
|
.wds-Button-avatars .np-circle {
|
|
@@ -922,9 +928,6 @@ div.critical-comms .critical-comms-body {
|
|
|
922
928
|
.np-theme-personal--bright-green .wds-Button--minimal .wds-Button-avatars .np-circle {
|
|
923
929
|
--circle-border-color: color-mix(in srgb, var(--Button-color) 12%, transparent);
|
|
924
930
|
}
|
|
925
|
-
[dir="rtl"] .wds-Button .tw-icon-chevron-right,[dir="rtl"] .wds-Button .tw-icon-arrow-right,[dir="rtl"] .wds-Button .tw-icon-chevron-left,[dir="rtl"] .wds-Button .tw-icon-arrow-left {
|
|
926
|
-
transform: rotate(180deg);
|
|
927
|
-
}
|
|
928
931
|
.np-card {
|
|
929
932
|
overflow: hidden;
|
|
930
933
|
transition-property: transform, box-shadow;
|
|
@@ -13,7 +13,7 @@ export type PrimitiveAnchorElementRef = React.Ref<HTMLAnchorElement>;
|
|
|
13
13
|
export interface PrimitiveAnchorProps
|
|
14
14
|
extends BasePrimitiveProps,
|
|
15
15
|
StyleProp,
|
|
16
|
-
Omit<PrimitiveAnchorAttributes, 'role'> {
|
|
16
|
+
Omit<PrimitiveAnchorAttributes, 'role' | 'type'> {
|
|
17
17
|
/** Content of the anchor */
|
|
18
18
|
children?: ReactNode;
|
|
19
19
|
|
|
@@ -4,7 +4,7 @@ import { Meta, StoryObj } from '@storybook/react';
|
|
|
4
4
|
import { Status } from '../common';
|
|
5
5
|
import UploadInput, { UploadInputProps } from './UploadInput';
|
|
6
6
|
import { UploadedFile, UploadResponse } from './types';
|
|
7
|
-
import { userEvent } from '@storybook/test';
|
|
7
|
+
import { userEvent, within } from '@storybook/test';
|
|
8
8
|
|
|
9
9
|
const meta: Meta<typeof UploadInput> = {
|
|
10
10
|
title: 'Forms/UploadInput/Tests',
|
|
@@ -65,8 +65,8 @@ const createDelayedPromise = async ({
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
const props = {
|
|
68
|
-
onUploadFile: async () => createDelayedPromise(),
|
|
69
|
-
onDeleteFile: async () => createDelayedPromise(),
|
|
68
|
+
onUploadFile: async (formData: FormData) => createDelayedPromise(),
|
|
69
|
+
onDeleteFile: async (id: string | number) => createDelayedPromise(),
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
export const UploadInputWithDescriptionFromProps: Story = {
|
|
@@ -268,7 +268,7 @@ export const DeletingTop: Story = {
|
|
|
268
268
|
files: [files[0], files[1], files[2]],
|
|
269
269
|
multiple: true,
|
|
270
270
|
},
|
|
271
|
-
play: async () => {
|
|
271
|
+
play: async ({ canvasElement }) => {
|
|
272
272
|
await userEvent.tab();
|
|
273
273
|
await triggerModalAndConfirm();
|
|
274
274
|
await triggerModalAndConfirm({ isLink: false });
|
|
@@ -282,7 +282,7 @@ export const DeletingBottom: Story = {
|
|
|
282
282
|
files: [files[0], files[1], files[2]],
|
|
283
283
|
multiple: true,
|
|
284
284
|
},
|
|
285
|
-
play: async () => {
|
|
285
|
+
play: async ({ canvasElement }) => {
|
|
286
286
|
await userEvent.tab();
|
|
287
287
|
await userEvent.tab();
|
|
288
288
|
await userEvent.tab();
|
|
@@ -38,16 +38,4 @@ describe('getAllowedFileTypes', () => {
|
|
|
38
38
|
expect(allowedFileTypes).toStrictEqual(['*']);
|
|
39
39
|
});
|
|
40
40
|
});
|
|
41
|
-
|
|
42
|
-
describe('using only mime types', () => {
|
|
43
|
-
const mimeTypes = ['application/json', 'image/jpeg'];
|
|
44
|
-
|
|
45
|
-
beforeAll(() => {
|
|
46
|
-
allowedFileTypes = getAllowedFileTypes(mimeTypes);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('returns the original mime types', () => {
|
|
50
|
-
expect(allowedFileTypes).toStrictEqual(['JSON', 'JPG, JPEG']);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
41
|
});
|
|
@@ -1,38 +1,12 @@
|
|
|
1
1
|
import { FileType } from '../../common';
|
|
2
2
|
|
|
3
|
-
const parseFileType = (fileType: string): string => {
|
|
4
|
-
if (fileType?.includes('.')) {
|
|
5
|
-
return fileType.replace('.', '').toUpperCase();
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const mimeType = fileType?.split('/');
|
|
9
|
-
if (mimeType?.length > 1) {
|
|
10
|
-
let parsedType = mimeType[1];
|
|
11
|
-
|
|
12
|
-
if (parsedType.toLocaleLowerCase() === 'jpeg') {
|
|
13
|
-
parsedType = 'jpg, '.concat(parsedType).toUpperCase();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return parsedType.toUpperCase();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return fileType;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
3
|
const getAllowedFileTypes = (fileTypes: readonly FileType[] | readonly string[]): string[] =>
|
|
23
|
-
fileTypes.map((
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.map((splittedFileType: string) => parseFileType(splittedFileType))
|
|
31
|
-
.join(', ');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// If `fileType` contains only `format` or `mime` type, parse the type
|
|
35
|
-
return parseFileType(fileType);
|
|
36
|
-
});
|
|
4
|
+
fileTypes.map((fileTypeDefinition: string) =>
|
|
5
|
+
fileTypeDefinition
|
|
6
|
+
.split(',')
|
|
7
|
+
.filter((extension) => !extension.includes('/')) // Filter out mime types
|
|
8
|
+
.map((extension) => extension.replace('.', '').toUpperCase()) // Remove dot and convert extensions to uppercase to be displayed in the instructions
|
|
9
|
+
.join(', '),
|
|
10
|
+
);
|
|
37
11
|
|
|
38
12
|
export default getAllowedFileTypes;
|