@transferwise/components 46.87.2 → 46.88.0
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 +9 -2
- package/build/avatarLayout/AvatarLayout.js.map +1 -1
- package/build/avatarLayout/AvatarLayout.mjs +9 -2
- package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
- package/build/button/Button.js +92 -79
- package/build/button/Button.js.map +1 -1
- package/build/button/Button.mjs +93 -80
- package/build/button/Button.mjs.map +1 -1
- package/build/button/Button.resolver.js +74 -0
- package/build/button/Button.resolver.js.map +1 -0
- package/build/button/Button.resolver.mjs +72 -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/circularButton/CircularButton.js.map +1 -1
- package/build/circularButton/CircularButton.mjs.map +1 -1
- 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/index.js +2 -2
- package/build/index.mjs +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 +247 -0
- 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 +11 -0
- package/build/styles/button/Button.css +228 -15
- package/build/styles/button/Button.vars.css +46 -0
- package/build/styles/button/LegacyButton.css +23 -0
- package/build/styles/main.css +247 -0
- package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -1
- package/build/types/button/Button.d.ts +2 -23
- package/build/types/button/Button.d.ts.map +1 -1
- package/build/types/button/Button.resolver.d.ts +35 -0
- package/build/types/button/Button.resolver.d.ts.map +1 -0
- package/build/types/button/Button.types.d.ts +70 -0
- package/build/types/button/Button.types.d.ts.map +1 -0
- package/build/types/button/LegacyButton.d.ts +44 -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/circularButton/CircularButton.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 +6 -2
- 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/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/package.json +3 -3
- package/src/alert/Alert.tests.story.tsx +1 -1
- package/src/avatar/Avatar.story.tsx +1 -1
- package/src/avatarLayout/AvatarLayout.css +11 -0
- package/src/avatarLayout/AvatarLayout.less +18 -1
- package/src/avatarLayout/AvatarLayout.tsx +10 -2
- package/src/avatarWrapper/AvatarWrapper.story.tsx +1 -1
- package/src/badge/Badge.story.tsx +1 -1
- package/src/button/Button.accessibility.docs.mdx +103 -0
- package/src/button/Button.css +228 -15
- package/src/button/Button.less +242 -14
- package/src/button/Button.resolver.tsx +73 -0
- package/src/button/Button.spec.tsx +329 -213
- package/src/button/Button.story.tsx +782 -134
- package/src/button/Button.tests.story.tsx +27 -0
- package/src/button/Button.tsx +103 -132
- package/src/button/Button.types.ts +92 -0
- package/src/button/Button.vars.css +46 -0
- package/src/button/Button.vars.less +59 -0
- package/src/button/LegacyButton.css +23 -0
- package/src/button/LegacyButton.less +24 -0
- package/src/button/LegacyButton.spec.tsx +147 -0
- package/src/button/LegacyButton.story.tsx +228 -0
- package/src/button/LegacyButton.tsx +177 -0
- package/src/button/index.ts +2 -3
- package/src/card/Card.story.tsx +6 -1
- package/src/circularButton/CircularButton.tsx +1 -0
- package/src/field/Field.story.tsx +1 -1
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +1 -2
- 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 +247 -0
- package/src/main.less +1 -0
- package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.tsx +2 -8
- package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.ts +7 -2
- 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/select/Select.story.tsx +4 -1
- package/src/test-utils/Parameters.d.ts +9 -1
- package/src/test-utils/story-config.ts +10 -1
- package/src/button/__snapshots__/Button.spec.tsx.snap +0 -309
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { userEvent, within, fn, expect } from '@storybook/test';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import Button from '.';
|
|
6
|
+
import LegacyButton from './LegacyButton';
|
|
7
|
+
|
|
8
|
+
// needed for the SB to show correct name in the Source blocks
|
|
9
|
+
LegacyButton.displayName = 'Button';
|
|
10
|
+
|
|
11
|
+
const withContainer = (Story: any) => (
|
|
12
|
+
<div
|
|
13
|
+
style={{
|
|
14
|
+
display: 'flex',
|
|
15
|
+
flexDirection: 'initial',
|
|
16
|
+
justifyContent: 'center',
|
|
17
|
+
flexFlow: 'column',
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
}}
|
|
20
|
+
>
|
|
21
|
+
<Story />
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const meta: Meta<typeof LegacyButton> = {
|
|
26
|
+
component: LegacyButton,
|
|
27
|
+
title: 'Actions/Button/Legacy Button',
|
|
28
|
+
args: {
|
|
29
|
+
size: undefined,
|
|
30
|
+
priority: undefined,
|
|
31
|
+
type: undefined,
|
|
32
|
+
block: false,
|
|
33
|
+
disabled: false,
|
|
34
|
+
loading: false,
|
|
35
|
+
href: undefined,
|
|
36
|
+
as: undefined,
|
|
37
|
+
target: undefined,
|
|
38
|
+
htmlType: undefined,
|
|
39
|
+
children: 'Button text',
|
|
40
|
+
onClick: fn(),
|
|
41
|
+
onBlur: fn(),
|
|
42
|
+
onFocus: fn(),
|
|
43
|
+
},
|
|
44
|
+
argTypes: {
|
|
45
|
+
href: {
|
|
46
|
+
control: 'text',
|
|
47
|
+
description: 'If set together with `as="a"`, the component will render as an HTML anchor.',
|
|
48
|
+
},
|
|
49
|
+
as: {
|
|
50
|
+
control: {
|
|
51
|
+
name: 'enum',
|
|
52
|
+
options: ['button', 'a'],
|
|
53
|
+
},
|
|
54
|
+
description: 'If set together with `href`, the component will render as an HTML anchor.',
|
|
55
|
+
},
|
|
56
|
+
type: {
|
|
57
|
+
type: {
|
|
58
|
+
name: 'enum',
|
|
59
|
+
value: ['accent', 'positive', 'negative'],
|
|
60
|
+
},
|
|
61
|
+
description:
|
|
62
|
+
'**NB**: `primary` | `pay` | `secondary` | `danger` | `link` are deprecated.\n\n',
|
|
63
|
+
},
|
|
64
|
+
size: {
|
|
65
|
+
type: {
|
|
66
|
+
name: 'enum',
|
|
67
|
+
value: ['lg', 'md', 'sm', 'xs'],
|
|
68
|
+
},
|
|
69
|
+
description: '**NB**: `xs` is deprecated.\n\n',
|
|
70
|
+
},
|
|
71
|
+
priority: {
|
|
72
|
+
type: {
|
|
73
|
+
name: 'enum',
|
|
74
|
+
value: ['primary', 'secondary', 'tertiary'],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
block: {
|
|
78
|
+
table: {
|
|
79
|
+
defaultValue: { summary: 'false' },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
v2: {
|
|
83
|
+
table: {
|
|
84
|
+
disable: true,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
tags: ['autodocs'],
|
|
89
|
+
decorators: [withContainer],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default meta;
|
|
93
|
+
|
|
94
|
+
type Story = StoryObj<typeof Button>;
|
|
95
|
+
|
|
96
|
+
export const Basic: Story = {};
|
|
97
|
+
|
|
98
|
+
export const Secondary: Story = {
|
|
99
|
+
args: {
|
|
100
|
+
type: 'accent',
|
|
101
|
+
priority: 'secondary',
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const Tertiary: Story = {
|
|
106
|
+
args: {
|
|
107
|
+
type: 'accent',
|
|
108
|
+
priority: 'tertiary',
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const Negative: Story = {
|
|
113
|
+
args: {
|
|
114
|
+
type: 'negative',
|
|
115
|
+
priority: 'primary',
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const Loading: Story = {
|
|
120
|
+
args: {
|
|
121
|
+
loading: true,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const Variants: Story = {
|
|
126
|
+
render: () => {
|
|
127
|
+
return (
|
|
128
|
+
<div className="d-flex flex-column p-b-2 align-items-start">
|
|
129
|
+
<div className="d-flex flex-row p-b-2" style={{ gap: 'var(--size-16)' }}>
|
|
130
|
+
<Button type="accent" priority="primary">
|
|
131
|
+
Primary Accent
|
|
132
|
+
</Button>
|
|
133
|
+
<Button type="accent" priority="secondary">
|
|
134
|
+
Secondary Accent
|
|
135
|
+
</Button>
|
|
136
|
+
<Button type="accent" priority="tertiary">
|
|
137
|
+
Tertiary Accent
|
|
138
|
+
</Button>
|
|
139
|
+
</div>
|
|
140
|
+
<div className="d-flex flex-row p-b-2" style={{ gap: 'var(--size-16)' }}>
|
|
141
|
+
<Button type="positive" priority="primary">
|
|
142
|
+
Primary Positive
|
|
143
|
+
</Button>
|
|
144
|
+
<Button type="positive" priority="secondary">
|
|
145
|
+
Secondary Accent
|
|
146
|
+
</Button>
|
|
147
|
+
</div>
|
|
148
|
+
<div className="d-flex flex-row flex- p-b-2" style={{ gap: 'var(--size-16)' }}>
|
|
149
|
+
<Button type="negative" priority="primary">
|
|
150
|
+
Primary Negative
|
|
151
|
+
</Button>
|
|
152
|
+
<Button type="negative" priority="secondary">
|
|
153
|
+
Secondary Negative
|
|
154
|
+
</Button>
|
|
155
|
+
</div>
|
|
156
|
+
<div className="d-flex flex-row p-b-1" style={{ gap: 'var(--size-16)' }}>
|
|
157
|
+
<Button type="accent" priority="primary" disabled>
|
|
158
|
+
Button Disabled
|
|
159
|
+
</Button>
|
|
160
|
+
<Button type="accent" priority="secondary" disabled>
|
|
161
|
+
Button Disabled
|
|
162
|
+
</Button>
|
|
163
|
+
<Button type="accent" priority="tertiary" disabled>
|
|
164
|
+
Button Disabled
|
|
165
|
+
</Button>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const wait = async (duration = 500) =>
|
|
173
|
+
new Promise<void>((resolve) => {
|
|
174
|
+
setTimeout(resolve, duration);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
export const Focused: Story = {
|
|
178
|
+
play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
|
|
179
|
+
const canvas = within(canvasElement);
|
|
180
|
+
const button = canvas.getByRole('button');
|
|
181
|
+
await userEvent.tab();
|
|
182
|
+
await expect(button).toHaveFocus();
|
|
183
|
+
await expect(button).toHaveTextContent('Focused!');
|
|
184
|
+
},
|
|
185
|
+
render: function Render(args: React.ComponentProps<typeof Button>) {
|
|
186
|
+
const [focused, setFocused] = useState(false);
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<Button {...args} onFocus={() => setFocused(true)}>
|
|
190
|
+
{focused ? 'Focused!' : 'Button text'}
|
|
191
|
+
</Button>
|
|
192
|
+
);
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export const SocialMedia: Story = {
|
|
197
|
+
render: () => {
|
|
198
|
+
return (
|
|
199
|
+
<>
|
|
200
|
+
<div className="m-b-2">
|
|
201
|
+
<button type="button" className="btn btn-google">
|
|
202
|
+
Login with Google
|
|
203
|
+
</button>
|
|
204
|
+
</div>
|
|
205
|
+
<div className="m-b-2">
|
|
206
|
+
<button type="button" className="btn btn-facebook">
|
|
207
|
+
Login with Facebook
|
|
208
|
+
</button>
|
|
209
|
+
</div>
|
|
210
|
+
<div className="m-b-2">
|
|
211
|
+
<button type="button" className="btn btn-lg btn-facebook">
|
|
212
|
+
Large Button
|
|
213
|
+
</button>
|
|
214
|
+
</div>
|
|
215
|
+
<div className="m-b-2">
|
|
216
|
+
<button type="button" className="btn btn-block btn-facebook">
|
|
217
|
+
Block Button
|
|
218
|
+
</button>
|
|
219
|
+
</div>
|
|
220
|
+
<div className="m-b-2">
|
|
221
|
+
<button type="button" className="btn btn-lg btn-block btn-facebook">
|
|
222
|
+
Large Block Button
|
|
223
|
+
</button>
|
|
224
|
+
</div>
|
|
225
|
+
</>
|
|
226
|
+
);
|
|
227
|
+
},
|
|
228
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
import { ElementType, forwardRef, MouseEvent } from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Size,
|
|
7
|
+
ControlType,
|
|
8
|
+
Priority,
|
|
9
|
+
ControlTypeAccent,
|
|
10
|
+
ControlTypeNegative,
|
|
11
|
+
ControlTypePositive,
|
|
12
|
+
PriorityPrimary,
|
|
13
|
+
PrioritySecondary,
|
|
14
|
+
PriorityTertiary,
|
|
15
|
+
SizeExtraSmall,
|
|
16
|
+
SizeSmall,
|
|
17
|
+
SizeMedium,
|
|
18
|
+
SizeLarge,
|
|
19
|
+
} from '../common';
|
|
20
|
+
import ProcessIndicator from '../processIndicator';
|
|
21
|
+
|
|
22
|
+
import messages from '../i18n/commonMessages/Button.messages';
|
|
23
|
+
import { typeClassMap, priorityClassMap } from './classMap';
|
|
24
|
+
import { establishNewPriority, establishNewType, logDeprecationNotices } from './legacyUtils';
|
|
25
|
+
import { ButtonReferenceType } from './Button.types';
|
|
26
|
+
|
|
27
|
+
/** @deprecated */
|
|
28
|
+
type DeprecatedTypes = 'primary' | 'pay' | 'secondary' | 'danger' | 'link';
|
|
29
|
+
|
|
30
|
+
/** @deprecated */
|
|
31
|
+
type DeprecatedSizes = SizeExtraSmall;
|
|
32
|
+
|
|
33
|
+
type CommonProps = {
|
|
34
|
+
v2?: false;
|
|
35
|
+
|
|
36
|
+
/** Makes the button take up the full width of its container */
|
|
37
|
+
block?: boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The `target` attribute for HTML anchor.
|
|
41
|
+
* If set to `_blank`, `rel="noopener noreferrer"` is automatically added to the rendered node.
|
|
42
|
+
*/
|
|
43
|
+
target?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Toggles the disabled state
|
|
46
|
+
* @default false
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
disabled?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Toggles the loading state
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
loading?: boolean;
|
|
55
|
+
type?: ControlTypeAccent | ControlTypeNegative | ControlTypePositive | DeprecatedTypes | null;
|
|
56
|
+
priority?: PriorityPrimary | PrioritySecondary | PriorityTertiary | null;
|
|
57
|
+
size?: SizeSmall | SizeMedium | SizeLarge | DeprecatedSizes;
|
|
58
|
+
htmlType?: 'submit' | 'reset' | 'button';
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
type ButtonProps = CommonProps &
|
|
62
|
+
Omit<React.ComponentPropsWithRef<'button'>, 'type'> & {
|
|
63
|
+
as?: 'button';
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type AnchorProps = CommonProps &
|
|
67
|
+
Omit<React.ComponentPropsWithRef<'a'>, 'type'> & {
|
|
68
|
+
as?: 'a';
|
|
69
|
+
href?: string;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type LegacyButtonProps = ButtonProps | AnchorProps;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @deprecated make sure you use new Button component via `<Button v2 .. />` and new props
|
|
76
|
+
*/
|
|
77
|
+
const LegacyButton = forwardRef<ButtonReferenceType, LegacyButtonProps>(
|
|
78
|
+
(
|
|
79
|
+
{
|
|
80
|
+
as: component = 'button',
|
|
81
|
+
block = false,
|
|
82
|
+
children,
|
|
83
|
+
className,
|
|
84
|
+
disabled,
|
|
85
|
+
loading = false,
|
|
86
|
+
priority = Priority.PRIMARY,
|
|
87
|
+
size = Size.MEDIUM,
|
|
88
|
+
type = ControlType.ACCENT,
|
|
89
|
+
onClick,
|
|
90
|
+
...rest
|
|
91
|
+
}: LegacyButtonProps,
|
|
92
|
+
ref,
|
|
93
|
+
) => {
|
|
94
|
+
const intl = useIntl();
|
|
95
|
+
|
|
96
|
+
logDeprecationNotices({ size, type });
|
|
97
|
+
|
|
98
|
+
const newType = establishNewType(type);
|
|
99
|
+
const newPriority = establishNewPriority(priority, type);
|
|
100
|
+
|
|
101
|
+
const classes = clsx(
|
|
102
|
+
`btn btn-${size}`,
|
|
103
|
+
`np-btn np-btn-${size}`,
|
|
104
|
+
{
|
|
105
|
+
'btn-loading': loading,
|
|
106
|
+
'btn-block np-btn-block': block,
|
|
107
|
+
disabled,
|
|
108
|
+
},
|
|
109
|
+
// @ts-expect-error fix when refactor `typeClassMap` to TypeScript
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
111
|
+
typeClassMap[newType],
|
|
112
|
+
// @ts-expect-error fix when refactor `typeClassMap` to TypeScript
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
114
|
+
priorityClassMap[newPriority],
|
|
115
|
+
className,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
function processIndicatorSize() {
|
|
119
|
+
return ['sm', 'xs'].includes(size) ? 'xxs' : 'xs';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const Element = (component as ElementType) ?? 'button';
|
|
123
|
+
let props;
|
|
124
|
+
|
|
125
|
+
if (Element === 'button') {
|
|
126
|
+
const { htmlType = 'button', ...restProps } = rest as ButtonProps;
|
|
127
|
+
props = {
|
|
128
|
+
...restProps,
|
|
129
|
+
disabled,
|
|
130
|
+
'aria-disabled': loading,
|
|
131
|
+
type: htmlType,
|
|
132
|
+
};
|
|
133
|
+
} else {
|
|
134
|
+
props = {
|
|
135
|
+
...rest,
|
|
136
|
+
'aria-disabled': loading,
|
|
137
|
+
} as AnchorProps;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Ensures that the button cannot be activated in loading or disabled mode,
|
|
142
|
+
* when `aria-disabled` might be used over the `disabled` HTML attribute
|
|
143
|
+
*/
|
|
144
|
+
const handleClick =
|
|
145
|
+
(handler: LegacyButtonProps['onClick']) =>
|
|
146
|
+
(event: MouseEvent<HTMLButtonElement> & MouseEvent<HTMLAnchorElement>) => {
|
|
147
|
+
if (disabled || loading) {
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
} else if (typeof handler === 'function') {
|
|
150
|
+
handler(event);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<Element
|
|
156
|
+
ref={ref as React.Ref<ButtonReferenceType>}
|
|
157
|
+
className={classes}
|
|
158
|
+
onClick={handleClick(onClick)}
|
|
159
|
+
{...props}
|
|
160
|
+
aria-live={loading ? 'polite' : 'off'}
|
|
161
|
+
aria-busy={loading}
|
|
162
|
+
aria-label={loading ? intl.formatMessage(messages.loadingAriaLabel) : rest['aria-label']}
|
|
163
|
+
>
|
|
164
|
+
{children}
|
|
165
|
+
{loading && (
|
|
166
|
+
<ProcessIndicator
|
|
167
|
+
size={processIndicatorSize()}
|
|
168
|
+
className="btn-loader"
|
|
169
|
+
data-testid="ButtonProgressIndicator"
|
|
170
|
+
/>
|
|
171
|
+
)}
|
|
172
|
+
</Element>
|
|
173
|
+
);
|
|
174
|
+
},
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
export default LegacyButton;
|
package/src/button/index.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { default } from './Button';
|
|
2
|
-
|
|
3
|
-
export type { Props as ButtonProps } from './Button';
|
|
1
|
+
export { default } from './Button.resolver';
|
|
2
|
+
export type { ButtonProps } from './Button.resolver';
|
package/src/card/Card.story.tsx
CHANGED
|
@@ -7,9 +7,14 @@ import Card from '.';
|
|
|
7
7
|
|
|
8
8
|
type Story = StoryObj<typeof Card>;
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated use Navigation pattern (via `NavigationOption` component)
|
|
12
|
+
*
|
|
13
|
+
* @see https://transferwise.atlassian.net/wiki/spaces/DS/pages/2387314550/Instructions+for+killing+expanding+cards+on+web+design+pattern
|
|
14
|
+
*/
|
|
10
15
|
export default {
|
|
11
16
|
component: Card,
|
|
12
|
-
title: 'Layouts/Card',
|
|
17
|
+
title: 'Layouts/Card (Deprecated)',
|
|
13
18
|
args: {
|
|
14
19
|
title: 'A card',
|
|
15
20
|
details: 'Some details about this card',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
|
|
3
3
|
import Body from '../body/Body';
|
|
4
|
+
import { typeClassMap, priorityClassMap } from '../button/classMap';
|
|
4
5
|
import { Breakpoint, ControlType, Priority, Typography } from '../common';
|
|
5
6
|
import IconButton, { IconButtonProps } from '../iconButton';
|
|
6
7
|
import { useMedia } from '../common/hooks/useMedia';
|
|
@@ -9,10 +9,9 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
|
|
|
9
9
|
class="np-flow-header d-flex flex-wrap align-items-center justify-content-between flex__item--12 np-flow-navigation__content p-x-3 np-flow-navigation--xs-max"
|
|
10
10
|
>
|
|
11
11
|
<button
|
|
12
|
-
aria-disabled="false"
|
|
13
12
|
aria-label="back to previous step"
|
|
14
13
|
aria-live="off"
|
|
15
|
-
class="
|
|
14
|
+
class="np-circle d-flex align-items-center justify-content-center np-icon-button np-icon-button-tertiary-default"
|
|
16
15
|
style="--circle-size: 40px; --circle-icon-size: 20px; --circle-font-size: 18px;"
|
|
17
16
|
type="button"
|
|
18
17
|
>
|
|
@@ -5,7 +5,7 @@ import { Flag } from '@wise/art';
|
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import Button from '../button
|
|
8
|
+
import Button from '../button';
|
|
9
9
|
import { getMonthNames } from '../common/dateUtils';
|
|
10
10
|
import Drawer from '../drawer';
|
|
11
11
|
import { Field } from '../field/Field';
|
package/src/link/Link.tsx
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { NavigateAway as NavigateAwayIcon } from '@transferwise/icons';
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
|
-
import { AnchorHTMLAttributes } from 'react';
|
|
4
3
|
import { useIntl } from 'react-intl';
|
|
4
|
+
import { PrimitiveAnchor } from '../primitives';
|
|
5
|
+
import type { PrimitiveAnchorProps } from '../primitives';
|
|
5
6
|
|
|
6
7
|
import { LinkLarge, LinkDefault } from '../common';
|
|
7
8
|
|
|
8
9
|
import messages from './Link.messages';
|
|
9
10
|
|
|
10
|
-
export type Props =
|
|
11
|
+
export type Props = PrimitiveAnchorProps & { type?: LinkLarge | LinkDefault };
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Standard Link component with navigate away icon
|
|
@@ -24,22 +25,30 @@ const Link = ({
|
|
|
24
25
|
onClick,
|
|
25
26
|
...props
|
|
26
27
|
}: Props) => {
|
|
28
|
+
const { formatMessage } = useIntl();
|
|
27
29
|
const isBlank = target === '_blank';
|
|
28
30
|
|
|
29
|
-
const
|
|
31
|
+
const classNames = clsx(
|
|
32
|
+
'np-link',
|
|
33
|
+
'd-inline-flex',
|
|
34
|
+
{
|
|
35
|
+
[`np-text-${type}`]: type,
|
|
36
|
+
},
|
|
37
|
+
className,
|
|
38
|
+
);
|
|
30
39
|
|
|
31
40
|
return (
|
|
32
|
-
<
|
|
41
|
+
<PrimitiveAnchor
|
|
33
42
|
href={href}
|
|
34
43
|
target={target}
|
|
35
|
-
className={
|
|
44
|
+
className={classNames}
|
|
36
45
|
aria-label={ariaLabel}
|
|
37
46
|
rel={isBlank ? 'noreferrer' : undefined}
|
|
38
47
|
onClick={onClick}
|
|
39
48
|
{...props}
|
|
40
49
|
>
|
|
41
50
|
{children} {isBlank && <NavigateAwayIcon title={formatMessage(messages.opensInNewTab)} />}
|
|
42
|
-
</
|
|
51
|
+
</PrimitiveAnchor>
|
|
43
52
|
);
|
|
44
53
|
};
|
|
45
54
|
|