@transferwise/components 0.0.0-experimental-3868cf1 → 0.0.0-experimental-69a95e1
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 +10 -4
- package/build/avatarLayout/AvatarLayout.js.map +1 -1
- package/build/avatarLayout/AvatarLayout.mjs +10 -4
- package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
- package/build/button/Button.js +79 -79
- package/build/button/Button.js.map +1 -1
- package/build/button/Button.mjs +80 -80
- package/build/button/Button.mjs.map +1 -1
- package/build/button/Button.resolver.js +86 -0
- package/build/button/Button.resolver.js.map +1 -0
- package/build/button/Button.resolver.mjs +84 -0
- package/build/button/Button.resolver.mjs.map +1 -0
- package/build/button/LegacyButton.js +114 -0
- package/build/button/LegacyButton.js.map +1 -0
- package/build/button/LegacyButton.mjs +112 -0
- package/build/button/LegacyButton.mjs.map +1 -0
- package/build/criticalBanner/CriticalCommsBanner.js +2 -2
- package/build/criticalBanner/CriticalCommsBanner.js.map +1 -1
- package/build/criticalBanner/CriticalCommsBanner.mjs +1 -1
- package/build/header/Header.js +2 -2
- package/build/header/Header.js.map +1 -1
- package/build/header/Header.mjs +1 -1
- package/build/i18n/ja.json +0 -1
- package/build/i18n/ja.json.js +0 -1
- package/build/i18n/ja.json.js.map +1 -1
- package/build/i18n/ja.json.mjs +0 -1
- package/build/i18n/ja.json.mjs.map +1 -1
- package/build/i18n/pt.json +0 -1
- package/build/i18n/pt.json.js +0 -1
- package/build/i18n/pt.json.js.map +1 -1
- package/build/i18n/pt.json.mjs +0 -1
- package/build/i18n/pt.json.mjs.map +1 -1
- package/build/i18n/ru.json +0 -1
- package/build/i18n/ru.json.js +0 -1
- package/build/i18n/ru.json.js.map +1 -1
- package/build/i18n/ru.json.mjs +0 -1
- package/build/i18n/ru.json.mjs.map +1 -1
- package/build/i18n/zh-HK.json +0 -1
- package/build/i18n/zh-HK.json.js +0 -1
- package/build/i18n/zh-HK.json.js.map +1 -1
- package/build/i18n/zh-HK.json.mjs +0 -1
- package/build/i18n/zh-HK.json.mjs.map +1 -1
- package/build/index.js +2 -4
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -2
- package/build/index.mjs.map +1 -1
- package/build/link/Link.js +8 -3
- package/build/link/Link.js.map +1 -1
- package/build/link/Link.mjs +8 -3
- package/build/link/Link.mjs.map +1 -1
- package/build/main.css +227 -2
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.js +2 -4
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.js.map +1 -1
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.mjs +2 -4
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.mjs.map +1 -1
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.js +3 -5
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.js.map +1 -1
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.mjs +3 -5
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.mjs.map +1 -1
- package/build/select/Select.js +2 -2
- package/build/select/Select.js.map +1 -1
- package/build/select/Select.mjs +1 -1
- package/build/styles/avatarLayout/AvatarLayout.css +12 -2
- package/build/styles/button/Button.css +207 -15
- package/build/styles/button/Button.vars.css +39 -0
- package/build/styles/button/LegacyButton.css +23 -0
- package/build/styles/main.css +227 -2
- package/build/types/avatarLayout/AvatarLayout.d.ts +1 -2
- package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -1
- package/build/types/avatarLayout/index.d.ts +1 -0
- package/build/types/avatarLayout/index.d.ts.map +1 -1
- package/build/types/button/Button.d.ts +1 -23
- package/build/types/button/Button.d.ts.map +1 -1
- package/build/types/button/Button.resolver.d.ts +31 -0
- package/build/types/button/Button.resolver.d.ts.map +1 -0
- package/build/types/button/Button.types.d.ts +65 -0
- package/build/types/button/Button.types.d.ts.map +1 -0
- package/build/types/button/LegacyButton.d.ts +30 -0
- package/build/types/button/LegacyButton.d.ts.map +1 -0
- package/build/types/button/index.d.ts +2 -2
- package/build/types/button/index.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/link/Link.d.ts +2 -2
- package/build/types/link/Link.d.ts.map +1 -1
- package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.d.ts.map +1 -1
- package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts +5 -1
- package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts.map +1 -1
- package/build/types/primitives/PrimitiveButton/src/PrimitiveButton.d.ts.map +1 -1
- package/build/types/test-utils/story-config.d.ts +1 -1
- package/build/types/test-utils/story-config.d.ts.map +1 -1
- package/build/types/uploadInput/uploadButton/getAllowedFileTypes.d.ts.map +1 -1
- package/build/upload/steps/completeStep/completeStep.js +2 -2
- package/build/upload/steps/completeStep/completeStep.js.map +1 -1
- package/build/upload/steps/completeStep/completeStep.mjs +1 -1
- package/build/upload/steps/processingStep/processingStep.js +2 -2
- package/build/upload/steps/processingStep/processingStep.js.map +1 -1
- package/build/upload/steps/processingStep/processingStep.mjs +1 -1
- package/build/uploadInput/UploadInput.js +3 -3
- package/build/uploadInput/UploadInput.js.map +1 -1
- package/build/uploadInput/UploadInput.mjs +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 +5 -5
- package/src/alert/Alert.tests.story.tsx +1 -1
- package/src/avatarLayout/AvatarLayout.css +12 -2
- package/src/avatarLayout/AvatarLayout.less +19 -2
- package/src/avatarLayout/AvatarLayout.tsx +11 -4
- package/src/avatarLayout/index.ts +1 -0
- package/src/button/Button.css +207 -15
- package/src/button/Button.less +217 -14
- package/src/button/Button.resolver.tsx +134 -0
- package/src/button/Button.spec.tsx +176 -225
- package/src/button/Button.story.tsx +729 -135
- package/src/button/Button.tests.story.tsx +27 -0
- package/src/button/Button.tsx +89 -132
- package/src/button/Button.types.ts +86 -0
- package/src/button/Button.vars.css +39 -0
- package/src/button/Button.vars.less +49 -0
- package/src/button/LegacyButton.css +23 -0
- package/src/button/LegacyButton.less +24 -0
- package/src/button/LegacyButton.spec.tsx +146 -0
- package/src/button/LegacyButton.story.tsx +225 -0
- package/src/button/LegacyButton.tsx +161 -0
- package/src/button/index.ts +2 -3
- package/src/field/Field.story.tsx +1 -1
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +1 -2
- package/src/i18n/ja.json +0 -1
- package/src/i18n/pt.json +0 -1
- package/src/i18n/ru.json +0 -1
- package/src/i18n/zh-HK.json +0 -1
- package/src/index.ts +0 -12
- package/src/inputs/SelectInput.story.tsx +1 -1
- package/src/label/Label.story.tsx +1 -1
- package/src/link/Link.tsx +15 -6
- package/src/main.css +227 -2
- package/src/main.less +1 -0
- package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.tsx +2 -8
- package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.ts +6 -1
- package/src/primitives/PrimitiveAnchor/test/PrimitiveAnchor.spec.tsx +1 -3
- package/src/primitives/PrimitiveButton/src/PrimitiveButton.tsx +4 -12
- package/src/primitives/PrimitiveButton/test/PrimitiveButton.spec.tsx +16 -13
- package/src/test-utils/Parameters.d.ts +9 -1
- package/src/test-utils/story-config.ts +10 -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/button/__snapshots__/Button.spec.tsx.snap +0 -309
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import LegacyButton, {
|
|
3
|
+
AnchorProps as LegacyAnchorProps,
|
|
4
|
+
ButtonProps as LegacyButtonProps,
|
|
5
|
+
} from './LegacyButton';
|
|
6
|
+
import { ButtonProps as NewButtonProps } from './Button.types';
|
|
7
|
+
import NewButton from './Button';
|
|
8
|
+
|
|
9
|
+
type LegacyButtonType =
|
|
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
|
+
});
|
|
43
|
+
|
|
44
|
+
const mapProps = (props: LegacyButtonProps): NewButtonProps => {
|
|
45
|
+
const { priority, size, type, as, ...newProps } = props;
|
|
46
|
+
|
|
47
|
+
const priorityMapping: Record<string, Record<string, NewButtonProps['priority']>> = {
|
|
48
|
+
accent: {
|
|
49
|
+
primary: 'primary',
|
|
50
|
+
secondary: 'tertiary',
|
|
51
|
+
tertiary: 'minimal',
|
|
52
|
+
},
|
|
53
|
+
positive: {
|
|
54
|
+
primary: 'primary',
|
|
55
|
+
secondary: 'tertiary',
|
|
56
|
+
tertiary: 'tertiary',
|
|
57
|
+
},
|
|
58
|
+
negative: {
|
|
59
|
+
primary: 'primary',
|
|
60
|
+
secondary: 'secondary',
|
|
61
|
+
tertiary: 'secondary',
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const mappedPriority =
|
|
66
|
+
type && priority ? priorityMapping[type]?.[priority] || priority : priority || undefined;
|
|
67
|
+
const mappedSentiment = type === 'negative' ? 'negative' : undefined;
|
|
68
|
+
|
|
69
|
+
const legacyButtonTypes: LegacyButtonType[] = [
|
|
70
|
+
'accent',
|
|
71
|
+
'negative',
|
|
72
|
+
'positive',
|
|
73
|
+
'primary',
|
|
74
|
+
'pay',
|
|
75
|
+
'secondary',
|
|
76
|
+
'danger',
|
|
77
|
+
'link',
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
const resolveSize = () => {
|
|
81
|
+
if (size) {
|
|
82
|
+
return { xs: 'sm', sm: 'sm', md: 'md', lg: 'lg' }[size] || size;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return size;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
...newProps,
|
|
90
|
+
size: resolveSize(),
|
|
91
|
+
priority: mappedPriority,
|
|
92
|
+
sentiment: mappedSentiment || ('sentiment' in props ? props.sentiment : null),
|
|
93
|
+
type:
|
|
94
|
+
type && !legacyButtonTypes.includes(type as LegacyButtonType) ? type : props.htmlType || null,
|
|
95
|
+
v2: undefined,
|
|
96
|
+
} as NewButtonProps;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonProps>((props, ref) => {
|
|
100
|
+
const { v2 = false, as, ...rest } = props;
|
|
101
|
+
|
|
102
|
+
if (v2) {
|
|
103
|
+
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
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<LegacyButton
|
|
125
|
+
{...(rest as LegacyButtonProps)}
|
|
126
|
+
ref={ref as React.Ref<HTMLButtonElement>}
|
|
127
|
+
as="button"
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
Button.displayName = 'Button';
|
|
133
|
+
|
|
134
|
+
export default Button;
|
|
@@ -1,246 +1,197 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { ControlType, Type, Priority, Size } from '../common';
|
|
4
|
-
import { render, screen, userEvent } from '../test-utils';
|
|
5
|
-
|
|
6
|
-
import Button from '.';
|
|
7
|
-
import messages from '../i18n/commonMessages/Button.messages';
|
|
8
|
-
import { ButtonReferenceType } from './Button';
|
|
9
|
-
|
|
10
|
-
const { ACCENT, POSITIVE, NEGATIVE } = ControlType;
|
|
11
|
-
const { PAY, LINK, DANGER } = Type;
|
|
12
|
-
const { PRIMARY, SECONDARY, TERTIARY } = Priority;
|
|
13
|
-
const { SMALL, MEDIUM, LARGE } = Size;
|
|
1
|
+
import { render, screen } from '../test-utils';
|
|
2
|
+
import Button, { ButtonProps } from './Button.resolver';
|
|
14
3
|
|
|
15
4
|
describe('Button', () => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
onClick: jest.fn(),
|
|
22
|
-
onFocus: jest.fn(),
|
|
23
|
-
onBlur: jest.fn(),
|
|
24
|
-
children: 'Send money',
|
|
5
|
+
const legacyProps: ButtonProps = {
|
|
6
|
+
as: 'button',
|
|
7
|
+
priority: 'primary',
|
|
8
|
+
size: 'md',
|
|
9
|
+
type: 'accent',
|
|
25
10
|
};
|
|
26
11
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
beforeEach(jest.clearAllMocks);
|
|
38
|
-
|
|
39
|
-
afterAll(() => {
|
|
40
|
-
// eslint-disable-next-line no-console
|
|
41
|
-
console.warn = originalWarn;
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('by default', () => {
|
|
45
|
-
it('renders the text', () => {
|
|
46
|
-
render(<Button {...props} />);
|
|
47
|
-
expect(screen.getByText(props.children)).toBeInTheDocument();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('set `ref` to be true on Button', () => {
|
|
51
|
-
const reference = createRef<ButtonReferenceType>();
|
|
52
|
-
|
|
53
|
-
expect(reference.current).toBeFalsy();
|
|
54
|
-
render(<Button ref={reference}>Click me!</Button>);
|
|
55
|
-
expect(reference.current).toBeTruthy();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('is not disabled', () => {
|
|
59
|
-
render(<Button {...props} />);
|
|
60
|
-
expect(screen.getByRole('button')).toBeEnabled();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('renders a medium button of type accent and priority primary', () => {
|
|
64
|
-
expect(render(<Button {...props} />).container).toMatchSnapshot();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('renders an anchor tag with button styles of type accent and priority primary', () => {
|
|
68
|
-
expect(render(<Button {...props} as="a" href="#" />).container).toMatchSnapshot();
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
describe('button attributes', () => {
|
|
73
|
-
it('sets the htmlType if set', () => {
|
|
74
|
-
render(<Button {...props} htmlType="submit" />);
|
|
75
|
-
expect(screen.getByRole('button')).toHaveAttribute('type', 'submit');
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('passes through custom classes if set', () => {
|
|
79
|
-
render(<Button {...props} className="donkeysarethebest" />);
|
|
80
|
-
expect(screen.getByRole('button')).toHaveClass('donkeysarethebest');
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('passes through aria-label if set', () => {
|
|
84
|
-
render(<Button {...props} aria-label="unique label" />);
|
|
85
|
-
const loadingButton = screen.getByLabelText('unique label');
|
|
86
|
-
expect(loadingButton).toBeInTheDocument();
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
describe('onClick', () => {
|
|
91
|
-
it('calls onClick when clicked', async () => {
|
|
92
|
-
render(<Button {...props} />);
|
|
93
|
-
await userEvent.click(screen.getByRole('button'));
|
|
94
|
-
expect(props.onClick).toHaveBeenCalledTimes(1);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('does not call onClick when clicked if disabled', async () => {
|
|
98
|
-
render(<Button {...props} disabled />);
|
|
99
|
-
await userEvent.click(screen.getByRole('button'));
|
|
100
|
-
expect(props.onClick).toHaveBeenCalledTimes(0);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('does not call onClick when clicked if loading', async () => {
|
|
104
|
-
render(<Button {...props} loading />);
|
|
105
|
-
await userEvent.click(screen.getByRole('button'));
|
|
106
|
-
expect(props.onClick).toHaveBeenCalledTimes(0);
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
describe('onFocus and onBlur', () => {
|
|
111
|
-
it('calls both handlers by default', async () => {
|
|
112
|
-
render(<Button {...props} />);
|
|
113
|
-
await userEvent.tab();
|
|
114
|
-
expect(props.onFocus).toHaveBeenCalledTimes(1);
|
|
115
|
-
await userEvent.tab();
|
|
116
|
-
expect(props.onFocus).toHaveBeenCalledTimes(1);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('does not call either handler if disabled', async () => {
|
|
120
|
-
render(<Button {...props} disabled />);
|
|
121
|
-
await userEvent.tab();
|
|
122
|
-
expect(props.onFocus).not.toHaveBeenCalled();
|
|
123
|
-
await userEvent.tab();
|
|
124
|
-
expect(props.onFocus).not.toHaveBeenCalled();
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('calls both handlers if loading', async () => {
|
|
128
|
-
render(<Button {...props} loading />);
|
|
129
|
-
await userEvent.tab();
|
|
130
|
-
expect(props.onFocus).toHaveBeenCalledTimes(1);
|
|
131
|
-
await userEvent.tab();
|
|
132
|
-
expect(props.onFocus).toHaveBeenCalledTimes(1);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
describe('sizes', () => {
|
|
137
|
-
it('renders small buttons', () => {
|
|
138
|
-
expect(render(<Button {...props} size={SMALL} />).container).toMatchSnapshot();
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('renders medium buttons', () => {
|
|
142
|
-
expect(render(<Button {...props} size={MEDIUM} />).container).toMatchSnapshot();
|
|
143
|
-
});
|
|
12
|
+
const newProps: ButtonProps = {
|
|
13
|
+
as: 'button',
|
|
14
|
+
v2: true,
|
|
15
|
+
priority: 'primary',
|
|
16
|
+
size: 'md',
|
|
17
|
+
type: 'accent',
|
|
18
|
+
testId: 'new-button',
|
|
19
|
+
};
|
|
144
20
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
21
|
+
it('renders LegacyButton when v2 is false', () => {
|
|
22
|
+
render(<Button {...legacyProps}>Legacy Button</Button>);
|
|
23
|
+
const button = screen.getByText('Legacy Button');
|
|
24
|
+
expect(button).toBeInTheDocument();
|
|
25
|
+
expect(button).toHaveClass('btn btn-md np-btn np-btn-md btn-accent btn-priority-1');
|
|
148
26
|
});
|
|
149
27
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
it('renders positive buttons', () => {
|
|
156
|
-
expect(render(<Button {...props} type={POSITIVE} />).container).toMatchSnapshot();
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('renders negative buttons', () => {
|
|
160
|
-
expect(render(<Button {...props} type={NEGATIVE} />).container).toMatchSnapshot();
|
|
161
|
-
});
|
|
28
|
+
it('renders the new Button when v2 is true', () => {
|
|
29
|
+
render(<Button {...newProps}>New Button</Button>);
|
|
30
|
+
const button = screen.getByTestId('new-button');
|
|
31
|
+
expect(button).toBeInTheDocument();
|
|
32
|
+
expect(button).toHaveClass('wds-Button wds-Button--medium wds-Button--primary');
|
|
162
33
|
});
|
|
163
34
|
|
|
164
|
-
describe('
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
expect(
|
|
168
|
-
render(<Button {...props} priority={PRIMARY} type={type} />).container,
|
|
169
|
-
).toMatchSnapshot(),
|
|
170
|
-
);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('renders secondary buttons', () => {
|
|
174
|
-
[ACCENT, POSITIVE, NEGATIVE].forEach((type) =>
|
|
175
|
-
expect(
|
|
176
|
-
render(<Button {...props} priority={SECONDARY} type={type} />).container,
|
|
177
|
-
).toMatchSnapshot(),
|
|
178
|
-
);
|
|
179
|
-
});
|
|
35
|
+
describe('render as HTML anchor', () => {
|
|
36
|
+
const href = 'https://example.com';
|
|
37
|
+
const name = 'Button as link';
|
|
180
38
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
render(<Button {
|
|
184
|
-
|
|
185
|
-
|
|
39
|
+
describe('v2', () => {
|
|
40
|
+
it('should render as button by default', () => {
|
|
41
|
+
render(<Button v2>{name}</Button>);
|
|
42
|
+
expect(screen.getByRole('button', { name })).toBeInTheDocument();
|
|
43
|
+
});
|
|
44
|
+
it('should render as link if href is provided', () => {
|
|
45
|
+
render(
|
|
46
|
+
<Button v2 href={href}>
|
|
47
|
+
{name}
|
|
48
|
+
</Button>,
|
|
49
|
+
);
|
|
50
|
+
expect(screen.getByRole('link', { name })).toHaveAttribute('href', href);
|
|
51
|
+
});
|
|
186
52
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
53
|
+
it('should render as link if `as="a"` is provided', () => {
|
|
54
|
+
render(
|
|
55
|
+
<Button v2 as="a">
|
|
56
|
+
{name}
|
|
57
|
+
</Button>,
|
|
58
|
+
);
|
|
59
|
+
expect(screen.getByText(name).closest('a')).toBeInTheDocument();
|
|
60
|
+
});
|
|
195
61
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
62
|
+
it('should render as link if href is set and `as="button"`', () => {
|
|
63
|
+
render(
|
|
64
|
+
<Button v2 href={href} as="button">
|
|
65
|
+
{name}
|
|
66
|
+
</Button>,
|
|
67
|
+
);
|
|
68
|
+
expect(screen.getByRole('link', { name })).toHaveAttribute('href', href);
|
|
201
69
|
});
|
|
202
|
-
expect(button).toBeInTheDocument();
|
|
203
|
-
expect(button).toBeEnabled();
|
|
204
|
-
expect(button).toHaveClass('btn-loading');
|
|
205
|
-
expect(button).toHaveAttribute('aria-disabled', 'true');
|
|
206
|
-
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
207
|
-
expect(button).toHaveAttribute('aria-live', 'polite');
|
|
208
|
-
expect(screen.getByTestId('ButtonProgressIndicator')).toBeInTheDocument();
|
|
209
|
-
});
|
|
210
70
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
71
|
+
describe('disabled mode', () => {
|
|
72
|
+
describe('button', () => {
|
|
73
|
+
it('should not be disabled by default', () => {
|
|
74
|
+
render(<Button v2>{name}</Button>);
|
|
75
|
+
const button = screen.getByRole('button');
|
|
76
|
+
expect(button).toBeEnabled();
|
|
77
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should respect disabled mode and set it only via the `disabled` attribute', () => {
|
|
81
|
+
render(
|
|
82
|
+
<Button v2 disabled>
|
|
83
|
+
{name}
|
|
84
|
+
</Button>,
|
|
85
|
+
);
|
|
86
|
+
const button = screen.getByRole('button');
|
|
87
|
+
expect(button).toBeDisabled();
|
|
88
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('anchor', () => {
|
|
93
|
+
it('should not be disabled by default', () => {
|
|
94
|
+
render(
|
|
95
|
+
<Button v2 href="wise.com">
|
|
96
|
+
{name}
|
|
97
|
+
</Button>,
|
|
98
|
+
);
|
|
99
|
+
const button = screen.getByRole('link');
|
|
100
|
+
expect(button).toBeEnabled();
|
|
101
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should respect disabled mode', () => {
|
|
105
|
+
render(
|
|
106
|
+
<Button v2 href="wise.com" disabled>
|
|
107
|
+
{name}
|
|
108
|
+
</Button>,
|
|
109
|
+
);
|
|
110
|
+
const button = screen.getByRole('link');
|
|
111
|
+
expect(button).toHaveAttribute('aria-disabled');
|
|
112
|
+
expect(button).toBeEnabled();
|
|
113
|
+
expect(button).not.toHaveAttribute('href');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
220
117
|
|
|
221
|
-
|
|
222
|
-
|
|
118
|
+
describe('loading mode', () => {
|
|
119
|
+
describe('button', () => {
|
|
120
|
+
it('should not be loading by default', () => {
|
|
121
|
+
render(<Button v2>{name}</Button>);
|
|
122
|
+
const button = screen.getByRole('button');
|
|
123
|
+
expect(button).toBeEnabled();
|
|
124
|
+
expect(button).not.toHaveAttribute('aria-busy');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should respect loading mode', () => {
|
|
128
|
+
render(
|
|
129
|
+
<Button v2 loading>
|
|
130
|
+
{name}
|
|
131
|
+
</Button>,
|
|
132
|
+
);
|
|
133
|
+
const button = screen.getByRole('button');
|
|
134
|
+
expect(button).toHaveAttribute('aria-busy');
|
|
135
|
+
// the `disabled` attribute is not set to keep the button
|
|
136
|
+
// focusable but aria attribute is defined to make it
|
|
137
|
+
// announced properly by the assistive tech
|
|
138
|
+
expect(button).toBeEnabled();
|
|
139
|
+
expect(button).toHaveAttribute('aria-disabled');
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('anchor', () => {
|
|
144
|
+
it('should not be loading by default', () => {
|
|
145
|
+
render(
|
|
146
|
+
<Button v2 href="wise.com">
|
|
147
|
+
{name}
|
|
148
|
+
</Button>,
|
|
149
|
+
);
|
|
150
|
+
const button = screen.getByRole('link');
|
|
151
|
+
expect(button).toBeEnabled();
|
|
152
|
+
expect(button).not.toHaveAttribute('aria-busy');
|
|
153
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should respect loading mode', () => {
|
|
157
|
+
render(
|
|
158
|
+
<Button v2 loading href="wise.com">
|
|
159
|
+
{name}
|
|
160
|
+
</Button>,
|
|
161
|
+
);
|
|
162
|
+
const button = screen.getByRole('link');
|
|
163
|
+
expect(button).toHaveAttribute('aria-busy');
|
|
164
|
+
// the `disabled` attribute is not set to keep the button
|
|
165
|
+
// focusable but aria attribute is defined to make it
|
|
166
|
+
// announced properly by the assistive tech
|
|
167
|
+
expect(button).toBeEnabled();
|
|
168
|
+
expect(button).toHaveAttribute('aria-disabled');
|
|
169
|
+
expect(button).not.toHaveAttribute('href');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
223
173
|
});
|
|
224
174
|
});
|
|
225
175
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
it('renders danger as negative buttons with priority secondary and logs a warning', () => {
|
|
238
|
-
expect(render(<Button {...props} type={DANGER} />).container).toMatchSnapshot();
|
|
239
|
-
expect(mockedWarn).toHaveBeenCalledTimes(1);
|
|
240
|
-
});
|
|
176
|
+
it('does not set type when type is in LegacyButtonType', () => {
|
|
177
|
+
const legacyTypeProps: ButtonProps = {
|
|
178
|
+
...newProps,
|
|
179
|
+
type: 'accent',
|
|
180
|
+
};
|
|
181
|
+
render(<Button {...legacyTypeProps}>Button Type</Button>);
|
|
182
|
+
const button = screen.getByTestId('new-button');
|
|
183
|
+
expect(button).toBeInTheDocument();
|
|
184
|
+
expect(button).not.toHaveAttribute('type');
|
|
185
|
+
});
|
|
241
186
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
187
|
+
it('sets type when type is not in LegacyButtonType', () => {
|
|
188
|
+
const buttonTypeProps: ButtonProps = {
|
|
189
|
+
...newProps,
|
|
190
|
+
type: 'submit',
|
|
191
|
+
};
|
|
192
|
+
render(<Button {...buttonTypeProps}>Submit Button</Button>);
|
|
193
|
+
const button = screen.getByTestId('new-button');
|
|
194
|
+
expect(button).toBeInTheDocument();
|
|
195
|
+
expect(button).toHaveAttribute('type', 'submit');
|
|
245
196
|
});
|
|
246
197
|
});
|