@transferwise/components 0.0.0-experimental-c0d7cb2 → 0.0.0-experimental-95cea4f

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.
Files changed (156) hide show
  1. package/build/avatarLayout/AvatarLayout.js +9 -2
  2. package/build/avatarLayout/AvatarLayout.js.map +1 -1
  3. package/build/avatarLayout/AvatarLayout.mjs +9 -2
  4. package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
  5. package/build/button/Button/src/Button.js +90 -0
  6. package/build/button/Button/src/Button.js.map +1 -0
  7. package/build/button/Button/src/Button.mjs +88 -0
  8. package/build/button/Button/src/Button.mjs.map +1 -0
  9. package/build/button/{Button.js → LegacyButton/Button.js} +25 -24
  10. package/build/button/LegacyButton/Button.js.map +1 -0
  11. package/build/button/{Button.mjs → LegacyButton/Button.mjs} +25 -24
  12. package/build/button/LegacyButton/Button.mjs.map +1 -0
  13. package/build/button/LegacyButton/classMap.js +42 -0
  14. package/build/button/LegacyButton/classMap.js.map +1 -0
  15. package/build/button/LegacyButton/classMap.mjs +39 -0
  16. package/build/button/LegacyButton/classMap.mjs.map +1 -0
  17. package/build/button/{legacyUtils → LegacyButton/legacyUtils}/legacyUtils.js +21 -21
  18. package/build/button/LegacyButton/legacyUtils/legacyUtils.js.map +1 -0
  19. package/build/button/{legacyUtils → LegacyButton/legacyUtils}/legacyUtils.mjs +21 -21
  20. package/build/button/LegacyButton/legacyUtils/legacyUtils.mjs.map +1 -0
  21. package/build/button/src/Button.js +64 -0
  22. package/build/button/src/Button.js.map +1 -0
  23. package/build/button/src/Button.mjs +62 -0
  24. package/build/button/src/Button.mjs.map +1 -0
  25. package/build/circularButton/CircularButton.js +1 -1
  26. package/build/circularButton/CircularButton.js.map +1 -1
  27. package/build/circularButton/CircularButton.mjs +1 -1
  28. package/build/circularButton/CircularButton.mjs.map +1 -1
  29. package/build/common/action/Action.js +1 -1
  30. package/build/common/action/Action.js.map +1 -1
  31. package/build/common/action/Action.mjs +1 -1
  32. package/build/common/action/Action.mjs.map +1 -1
  33. package/build/criticalBanner/CriticalCommsBanner.js +1 -1
  34. package/build/criticalBanner/CriticalCommsBanner.mjs +1 -1
  35. package/build/header/Header.js +1 -1
  36. package/build/header/Header.mjs +1 -1
  37. package/build/i18n/zh-CN.json +0 -10
  38. package/build/i18n/zh-CN.json.js +0 -10
  39. package/build/i18n/zh-CN.json.js.map +1 -1
  40. package/build/i18n/zh-CN.json.mjs +0 -10
  41. package/build/i18n/zh-CN.json.mjs.map +1 -1
  42. package/build/index.js +1 -1
  43. package/build/index.mjs +1 -1
  44. package/build/link/Link.js +8 -3
  45. package/build/link/Link.js.map +1 -1
  46. package/build/link/Link.mjs +8 -3
  47. package/build/link/Link.mjs.map +1 -1
  48. package/build/main.css +288 -29
  49. package/build/nudge/Nudge.js +1 -1
  50. package/build/nudge/Nudge.js.map +1 -1
  51. package/build/nudge/Nudge.mjs +1 -1
  52. package/build/nudge/Nudge.mjs.map +1 -1
  53. package/build/select/Select.js +1 -1
  54. package/build/select/Select.mjs +1 -1
  55. package/build/styles/avatarLayout/AvatarLayout.css +11 -0
  56. package/build/styles/button/Button/less/Button.css +253 -0
  57. package/build/styles/button/Button/less/Button.vars.css +57 -0
  58. package/build/styles/iconButton/IconButton.css +24 -29
  59. package/build/styles/main.css +288 -29
  60. package/build/types/avatarLayout/AvatarLayout.d.ts +1 -2
  61. package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -1
  62. package/build/types/avatarLayout/index.d.ts +1 -0
  63. package/build/types/avatarLayout/index.d.ts.map +1 -1
  64. package/build/types/button/Button/index.d.ts +3 -0
  65. package/build/types/button/Button/index.d.ts.map +1 -0
  66. package/build/types/button/Button/src/Button.d.ts +4 -0
  67. package/build/types/button/Button/src/Button.d.ts.map +1 -0
  68. package/build/types/button/Button/src/Button.types.d.ts +49 -0
  69. package/build/types/button/Button/src/Button.types.d.ts.map +1 -0
  70. package/build/types/button/Button/src/index.d.ts +2 -0
  71. package/build/types/button/Button/src/index.d.ts.map +1 -0
  72. package/build/types/button/{Button.d.ts → LegacyButton/Button.d.ts} +7 -5
  73. package/build/types/button/LegacyButton/Button.d.ts.map +1 -0
  74. package/build/types/button/LegacyButton/classMap.d.ts.map +1 -0
  75. package/build/types/button/LegacyButton/index.d.ts +3 -0
  76. package/build/types/button/LegacyButton/index.d.ts.map +1 -0
  77. package/build/types/button/LegacyButton/legacyUtils/index.d.ts.map +1 -0
  78. package/build/types/button/{legacyUtils → LegacyButton/legacyUtils}/legacyUtils.d.ts +1 -1
  79. package/build/types/button/LegacyButton/legacyUtils/legacyUtils.d.ts.map +1 -0
  80. package/build/types/button/index.d.ts +2 -2
  81. package/build/types/button/index.d.ts.map +1 -1
  82. package/build/types/button/src/Button.d.ts +39 -0
  83. package/build/types/button/src/Button.d.ts.map +1 -0
  84. package/build/types/button/src/index.d.ts +3 -0
  85. package/build/types/button/src/index.d.ts.map +1 -0
  86. package/build/types/link/Link.d.ts +2 -2
  87. package/build/types/link/Link.d.ts.map +1 -1
  88. package/build/types/test-utils/index.d.ts.map +1 -1
  89. package/build/upload/steps/completeStep/completeStep.js +1 -1
  90. package/build/upload/steps/completeStep/completeStep.mjs +1 -1
  91. package/build/upload/steps/processingStep/processingStep.js +1 -1
  92. package/build/upload/steps/processingStep/processingStep.mjs +1 -1
  93. package/build/uploadInput/UploadInput.js +1 -1
  94. package/build/uploadInput/UploadInput.mjs +1 -1
  95. package/package.json +5 -5
  96. package/src/avatarLayout/AvatarLayout.css +11 -0
  97. package/src/avatarLayout/AvatarLayout.less +18 -1
  98. package/src/avatarLayout/AvatarLayout.tsx +11 -3
  99. package/src/avatarLayout/index.ts +1 -0
  100. package/src/avatarWrapper/AvatarWrapper.story.tsx +2 -0
  101. package/src/button/Button/index.ts +2 -0
  102. package/src/button/Button/less/Button.css +253 -0
  103. package/src/button/Button/less/Button.less +221 -0
  104. package/src/button/Button/less/Button.vars.css +57 -0
  105. package/src/button/Button/less/Button.vars.less +65 -0
  106. package/src/button/Button/src/Button.tsx +112 -0
  107. package/src/button/Button/src/Button.types.ts +68 -0
  108. package/src/button/Button/src/index.ts +1 -0
  109. package/src/button/Button/stories/Button.story.tsx +288 -0
  110. package/src/button/Button/stories/Button.tests.story.tsx +288 -0
  111. package/src/button/Button/test/Button.spec.tsx +304 -0
  112. package/src/button/{Button.less → LegacyButton/Button.less} +1 -1
  113. package/src/button/{Button.spec.tsx → LegacyButton/Button.spec.tsx} +3 -3
  114. package/src/button/LegacyButton/Button.story.tsx +224 -0
  115. package/src/button/{Button.tsx → LegacyButton/Button.tsx} +13 -9
  116. package/src/button/{classMap.ts → LegacyButton/classMap.ts} +1 -1
  117. package/src/button/LegacyButton/index.ts +3 -0
  118. package/src/button/{legacyUtils → LegacyButton/legacyUtils}/legacyUtils.spec.tsx +2 -2
  119. package/src/button/{legacyUtils → LegacyButton/legacyUtils}/legacyUtils.ts +2 -2
  120. package/src/button/index.ts +2 -3
  121. package/src/button/src/Button.tsx +60 -0
  122. package/src/button/src/index.ts +2 -0
  123. package/src/button/test/Button.spec.tsx +33 -0
  124. package/src/circularButton/CircularButton.tsx +1 -1
  125. package/src/common/action/Action.tsx +1 -1
  126. package/src/i18n/zh-CN.json +0 -10
  127. package/src/iconButton/IconButton.css +24 -29
  128. package/src/iconButton/IconButton.less +4 -4
  129. package/src/link/Link.tsx +15 -6
  130. package/src/main.css +288 -29
  131. package/src/main.less +2 -1
  132. package/src/nudge/Nudge.tsx +1 -1
  133. package/src/primitives/PrimitiveAnchor/stories/PrimitiveAnchor.story.tsx +1 -1
  134. package/src/primitives/PrimitiveAnchor/test/PrimitiveAnchor.spec.tsx +1 -1
  135. package/src/primitives/PrimitiveButton/stories/PrimitiveButton.story.tsx +1 -1
  136. package/src/primitives/PrimitiveButton/test/PrimitiveButton.spec.tsx +2 -3
  137. package/src/test-utils/index.tsx +0 -1
  138. package/build/button/Button.js.map +0 -1
  139. package/build/button/Button.mjs.map +0 -1
  140. package/build/button/classMap.js +0 -42
  141. package/build/button/classMap.js.map +0 -1
  142. package/build/button/classMap.mjs +0 -39
  143. package/build/button/classMap.mjs.map +0 -1
  144. package/build/button/legacyUtils/legacyUtils.js.map +0 -1
  145. package/build/button/legacyUtils/legacyUtils.mjs.map +0 -1
  146. package/build/types/button/Button.d.ts.map +0 -1
  147. package/build/types/button/classMap.d.ts.map +0 -1
  148. package/build/types/button/legacyUtils/index.d.ts.map +0 -1
  149. package/build/types/button/legacyUtils/legacyUtils.d.ts.map +0 -1
  150. package/src/button/Button.story.tsx +0 -163
  151. /package/build/styles/button/{Button.css → LegacyButton/Button.css} +0 -0
  152. /package/build/types/button/{classMap.d.ts → LegacyButton/classMap.d.ts} +0 -0
  153. /package/build/types/button/{legacyUtils → LegacyButton/legacyUtils}/index.d.ts +0 -0
  154. /package/src/button/{Button.css → LegacyButton/Button.css} +0 -0
  155. /package/src/button/{__snapshots__ → LegacyButton/__snapshots__}/Button.spec.tsx.snap +0 -0
  156. /package/src/button/{legacyUtils → LegacyButton/legacyUtils}/index.ts +0 -0
@@ -0,0 +1,224 @@
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
+
7
+ const withContainer = (Story: any) => (
8
+ <div
9
+ style={{
10
+ display: 'flex',
11
+ flexDirection: 'initial',
12
+ justifyContent: 'center',
13
+ flexFlow: 'column',
14
+ alignItems: 'center',
15
+ }}
16
+ >
17
+ <Story />
18
+ </div>
19
+ );
20
+
21
+ const meta: Meta<typeof Button> = {
22
+ component: Button,
23
+ title: 'Actions/Button/Legacy',
24
+ args: {
25
+ children: 'Button text',
26
+ loading: false,
27
+ type: undefined,
28
+ onClick: fn(),
29
+ onBlur: fn(),
30
+ onFocus: fn(),
31
+ href: 'https://example.com',
32
+ },
33
+ argTypes: {
34
+ as: {
35
+ control: {
36
+ type: 'select',
37
+ options: ['button', 'a'],
38
+ },
39
+ },
40
+ type: {
41
+ type: {
42
+ name: 'enum',
43
+ value: ['accent', 'positive', 'negative'],
44
+ },
45
+ },
46
+ size: {
47
+ type: {
48
+ name: 'enum',
49
+ value: ['xs', 'sm', 'md', 'lg'],
50
+ },
51
+ },
52
+ priority: {
53
+ type: {
54
+ name: 'enum',
55
+ value: ['primary', 'secondary', 'tertiary'],
56
+ },
57
+ },
58
+ appearance: {
59
+ table: {
60
+ disable: true,
61
+ },
62
+ },
63
+ iconLeft: {
64
+ table: {
65
+ disable: true,
66
+ },
67
+ },
68
+ iconRight: {
69
+ table: {
70
+ disable: true,
71
+ },
72
+ },
73
+ avatars: {
74
+ table: {
75
+ disable: true,
76
+ },
77
+ },
78
+ 'data-testid': {
79
+ table: {
80
+ disable: true,
81
+ },
82
+ },
83
+ },
84
+ tags: ['autodocs'],
85
+ decorators: [withContainer],
86
+ };
87
+
88
+ export default meta;
89
+
90
+ type Story = StoryObj<typeof Button>;
91
+
92
+ export const Basic: Story = {};
93
+
94
+ export const Secondary: Story = {
95
+ args: {
96
+ type: 'accent',
97
+ priority: 'secondary',
98
+ },
99
+ };
100
+
101
+ export const Tertiary: Story = {
102
+ args: {
103
+ type: 'accent',
104
+ priority: 'tertiary',
105
+ },
106
+ };
107
+
108
+ export const Negative: Story = {
109
+ args: {
110
+ type: 'negative',
111
+ priority: 'primary',
112
+ },
113
+ };
114
+
115
+ export const Loading: Story = {
116
+ args: {
117
+ loading: true,
118
+ },
119
+ };
120
+
121
+ export const Variants: Story = {
122
+ render: () => {
123
+ return (
124
+ <div className="d-flex flex-column p-b-2 align-items-start">
125
+ <div className="d-flex flex-row p-b-2" style={{ gap: 'var(--size-16)' }}>
126
+ <Button type="accent" priority="primary">
127
+ Primary Accent
128
+ </Button>
129
+ <Button type="accent" priority="secondary">
130
+ Secondary Accent
131
+ </Button>
132
+ <Button type="accent" priority="tertiary">
133
+ Tertiary Accent
134
+ </Button>
135
+ </div>
136
+ <div className="d-flex flex-row p-b-2" style={{ gap: 'var(--size-16)' }}>
137
+ <Button type="positive" priority="primary">
138
+ Primary Positive
139
+ </Button>
140
+ <Button type="positive" priority="secondary">
141
+ Secondary Accent
142
+ </Button>
143
+ </div>
144
+ <div className="d-flex flex-row flex- p-b-2" style={{ gap: 'var(--size-16)' }}>
145
+ <Button type="negative" priority="primary">
146
+ Primary Negative
147
+ </Button>
148
+ <Button type="negative" priority="secondary">
149
+ Secondary Negative
150
+ </Button>
151
+ </div>
152
+ <div className="d-flex flex-row p-b-1" style={{ gap: 'var(--size-16)' }}>
153
+ <Button type="accent" priority="primary" disabled>
154
+ Button Disabled
155
+ </Button>
156
+ <Button type="accent" priority="secondary" disabled>
157
+ Button Disabled
158
+ </Button>
159
+ <Button type="accent" priority="tertiary" disabled>
160
+ Button Disabled
161
+ </Button>
162
+ </div>
163
+ </div>
164
+ );
165
+ },
166
+ };
167
+
168
+ const wait = async (duration = 500) =>
169
+ new Promise<void>((resolve) => {
170
+ setTimeout(resolve, duration);
171
+ });
172
+
173
+ export const Focused: Story = {
174
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
175
+ const canvas = within(canvasElement);
176
+ const button = canvas.getByRole('button');
177
+ await userEvent.tab();
178
+ await expect(button).toHaveFocus();
179
+ await expect(button).toHaveTextContent('Focused!');
180
+ },
181
+ render: function Render(args: React.ComponentProps<typeof Button>) {
182
+ const [focused, setFocused] = useState(false);
183
+
184
+ return (
185
+ <Button {...args} onFocus={() => setFocused(true)}>
186
+ {focused ? 'Focused!' : 'Button text'}
187
+ </Button>
188
+ );
189
+ },
190
+ };
191
+
192
+ export const SocialMedia: Story = {
193
+ render: () => {
194
+ return (
195
+ <>
196
+ <div className="m-b-2">
197
+ <button type="button" className="btn btn-google">
198
+ Login with Google
199
+ </button>
200
+ </div>
201
+ <div className="m-b-2">
202
+ <button type="button" className="btn btn-facebook">
203
+ Login with Facebook
204
+ </button>
205
+ </div>
206
+ <div className="m-b-2">
207
+ <button type="button" className="btn btn-lg btn-facebook">
208
+ Large Button
209
+ </button>
210
+ </div>
211
+ <div className="m-b-2">
212
+ <button type="button" className="btn btn-block btn-facebook">
213
+ Block Button
214
+ </button>
215
+ </div>
216
+ <div className="m-b-2">
217
+ <button type="button" className="btn btn-lg btn-block btn-facebook">
218
+ Large Block Button
219
+ </button>
220
+ </div>
221
+ </>
222
+ );
223
+ },
224
+ };
@@ -16,10 +16,10 @@ import {
16
16
  SizeSmall,
17
17
  SizeMedium,
18
18
  SizeLarge,
19
- } from '../common';
20
- import ProcessIndicator from '../processIndicator';
19
+ } from '../../common';
20
+ import ProcessIndicator from '../../processIndicator';
21
21
 
22
- import messages from '../i18n/commonMessages/Button.messages';
22
+ import messages from '../../i18n/commonMessages/Button.messages';
23
23
  import { typeClassMap, priorityClassMap } from './classMap';
24
24
  import { establishNewPriority, establishNewType, logDeprecationNotices } from './legacyUtils';
25
25
 
@@ -33,20 +33,22 @@ type CommonProps = {
33
33
  block?: boolean;
34
34
  disabled?: boolean;
35
35
  loading?: boolean;
36
+ /** @deprecated */
36
37
  type?: ControlTypeAccent | ControlTypeNegative | ControlTypePositive | DeprecatedTypes | null;
37
38
  priority?: PriorityPrimary | PrioritySecondary | PriorityTertiary | null;
38
39
  size?: SizeSmall | SizeMedium | SizeLarge | DeprecatedSizes;
39
40
  };
40
41
 
41
- type ButtonProps = CommonProps &
42
+ export type ButtonProps = CommonProps &
42
43
  Omit<React.ComponentPropsWithRef<'button'>, 'type'> & {
43
- as?: 'button';
44
+ as?: 'button' | undefined;
45
+ /** @deprecated */
44
46
  htmlType?: 'submit' | 'reset' | 'button';
45
47
  };
46
48
 
47
- type AnchorProps = CommonProps &
49
+ export type AnchorProps = CommonProps &
48
50
  Omit<React.ComponentPropsWithRef<'a'>, 'type'> & {
49
- as?: 'a';
51
+ as?: 'a' | undefined;
50
52
  };
51
53
 
52
54
  export type Props = ButtonProps | AnchorProps;
@@ -68,7 +70,7 @@ const Button = forwardRef<ButtonReferenceType, Props>(
68
70
  onClick,
69
71
  ...rest
70
72
  }: Props,
71
- reference,
73
+ ref,
72
74
  ) => {
73
75
  const intl = useIntl();
74
76
 
@@ -132,7 +134,7 @@ const Button = forwardRef<ButtonReferenceType, Props>(
132
134
 
133
135
  return (
134
136
  <Element
135
- ref={reference}
137
+ ref={ref}
136
138
  className={classes}
137
139
  onClick={handleClick(onClick)}
138
140
  {...props}
@@ -153,4 +155,6 @@ const Button = forwardRef<ButtonReferenceType, Props>(
153
155
  },
154
156
  );
155
157
 
158
+ Button.displayName = 'Button';
159
+
156
160
  export default Button;
@@ -1,4 +1,4 @@
1
- import { ControlType, Priority } from '../common';
1
+ import { ControlType, Priority } from '../../common';
2
2
 
3
3
  export const typeClassMap = {
4
4
  [ControlType.ACCENT]: 'btn-accent',
@@ -0,0 +1,3 @@
1
+ export { default } from './Button';
2
+
3
+ export type { Props as ButtonProps } from './Button';
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-console */
2
- import { ControlType, Priority, Size, Type } from '../../common';
3
- import { cleanup } from '../../test-utils';
2
+ import { ControlType, Priority, Size, Type } from '../../../common';
3
+ import { cleanup } from '../../../test-utils';
4
4
 
5
5
  import { establishNewPriority, establishNewType, logDeprecationNotices } from '.';
6
6
 
@@ -1,5 +1,5 @@
1
- import { ControlType, Priority, Size, Type } from '../../common';
2
- import { logActionRequired, logActionRequiredIf } from '../../utilities';
1
+ import { ControlType, Priority, Size, Type } from '../../../common';
2
+ import { logActionRequired, logActionRequiredIf } from '../../../utilities';
3
3
 
4
4
  const deprecatedTypeMap: Record<Type, ControlType> = {
5
5
  [Type.PRIMARY]: ControlType.ACCENT,
@@ -1,3 +1,2 @@
1
- export { default } from './Button';
2
-
3
- export type { Props as ButtonProps } from './Button';
1
+ export { default } from './src';
2
+ export * from './src';
@@ -0,0 +1,60 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
+ import { forwardRef } from 'react';
3
+ import LegacyButton, { ButtonProps as LegacyButtonProps } from '../LegacyButton';
4
+ import NewButton from '../Button';
5
+ import { ButtonProps as NewButtonProps } from '../Button/src/Button.types';
6
+
7
+ export type ButtonProps = {
8
+ useNewButton?: boolean;
9
+ } & (LegacyButtonProps | NewButtonProps);
10
+
11
+ const mapProps = (props: LegacyButtonProps): NewButtonProps => {
12
+ const { priority, size, type, as, ...newProps } = props;
13
+
14
+ const priorityMapping: Record<string, Record<string, NewButtonProps['priority']>> = {
15
+ accent: {
16
+ primary: 'primary',
17
+ secondary: 'tertiary',
18
+ tertiary: 'minimal',
19
+ },
20
+ positive: {
21
+ primary: 'primary',
22
+ secondary: 'tertiary',
23
+ tertiary: 'tertiary',
24
+ },
25
+ negative: {
26
+ primary: 'primary',
27
+ secondary: 'secondary',
28
+ tertiary: 'secondary',
29
+ },
30
+ };
31
+
32
+ const mappedPriority =
33
+ type && priority ? priorityMapping[type]?.[priority] || priority : priority || undefined;
34
+ const mappedAppearance = type === 'negative' ? 'negative' : undefined;
35
+
36
+ return {
37
+ ...newProps,
38
+ size:
39
+ size === 'xs' || size === 'sm' ? 'sm' : size === 'md' ? 'md' : size === 'lg' ? 'lg' : size,
40
+ priority: mappedPriority,
41
+ appearance: mappedAppearance || ('appearance' in props ? props.appearance : undefined),
42
+ type: as === 'button' ? props.htmlType : undefined,
43
+ href: as === 'a' ? props.href || '' : undefined,
44
+ } as NewButtonProps;
45
+ };
46
+
47
+ const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonProps>(
48
+ ({ useNewButton = false, ...props }, ref) => {
49
+ if (useNewButton) {
50
+ const mappedProps = mapProps(props as LegacyButtonProps);
51
+ return <NewButton {...mappedProps} ref={ref as any} />;
52
+ }
53
+
54
+ return <LegacyButton {...(props as LegacyButtonProps)} ref={ref} />;
55
+ },
56
+ );
57
+
58
+ Button.displayName = 'Button';
59
+
60
+ export default Button;
@@ -0,0 +1,2 @@
1
+ export { default } from './Button';
2
+ export type { ButtonProps } from './Button';
@@ -0,0 +1,33 @@
1
+ import { render, screen } from '../../test-utils';
2
+ import Button, { ButtonProps } from '..';
3
+
4
+ describe('Button', () => {
5
+ const legacyProps: ButtonProps = {
6
+ useNewButton: false,
7
+ priority: 'primary',
8
+ size: 'md',
9
+ type: 'accent',
10
+ };
11
+
12
+ const newProps: ButtonProps = {
13
+ useNewButton: true,
14
+ priority: 'primary',
15
+ size: 'md',
16
+ type: 'accent',
17
+ testId: 'new-button',
18
+ };
19
+
20
+ it('renders LegacyButton when useNewButton is false', () => {
21
+ render(<Button {...legacyProps}>Legacy Button</Button>);
22
+ const button = screen.getByText('Legacy Button');
23
+ expect(button).toBeInTheDocument();
24
+ expect(button).toHaveClass('btn btn-md np-btn np-btn-md btn-accent btn-priority-1');
25
+ });
26
+
27
+ it('renders the new Button when useNewButton is true', () => {
28
+ render(<Button {...newProps}>New Button</Button>);
29
+ const button = screen.getByTestId('new-button');
30
+ expect(button).toBeInTheDocument();
31
+ expect(button).toHaveClass('wds-Button wds-Button--medium wds-Button--primary');
32
+ });
33
+ });
@@ -2,7 +2,7 @@ import { clsx } from 'clsx';
2
2
  import { cloneElement } from 'react';
3
3
 
4
4
  import Body from '../body/Body';
5
- import { typeClassMap, priorityClassMap } from '../button/classMap';
5
+ import { typeClassMap, priorityClassMap } from '../button/LegacyButton/classMap';
6
6
  import { Breakpoint, ControlType, Priority, Typography } from '../common';
7
7
  import Circle from '../common/circle';
8
8
  import { useMedia } from '../common/hooks/useMedia';
@@ -22,7 +22,7 @@ export function Action({ action, className, variant = 'button' }: Props) {
22
22
  if ('href' in action) {
23
23
  return (
24
24
  <Link
25
- href={action.href}
25
+ href={action.href ?? ''}
26
26
  className={className}
27
27
  aria-label={action['aria-label']}
28
28
  target={action.target}
@@ -27,19 +27,9 @@
27
27
  "neptune.SelectInput.noResultsFound": "找不到结果",
28
28
  "neptune.SelectOption.action.label": "选择",
29
29
  "neptune.SelectOption.selected.action.label": "更改所选选项",
30
- "neptune.StatusIcon.iconLabel.error": "错误:",
31
- "neptune.StatusIcon.iconLabel.information": "信息:",
32
- "neptune.StatusIcon.iconLabel.pending": "待处理:",
33
- "neptune.StatusIcon.iconLabel.success": "成功:",
34
- "neptune.StatusIcon.iconLabel.warning": "警告:",
35
30
  "neptune.Summary.statusDone": "已完成",
36
31
  "neptune.Summary.statusNotDone": "未完成",
37
32
  "neptune.Summary.statusPending": "待处理",
38
- "neptune.Table.actionHeader": "操作",
39
- "neptune.Table.emptyData": "找不到结果",
40
- "neptune.Table.loaded": "表数据已加载",
41
- "neptune.Table.loading": "表数据正在加载",
42
- "neptune.Table.refreshPage": "刷新页面",
43
33
  "neptune.Upload.csButtonText": "上传另一个文件?",
44
34
  "neptune.Upload.csFailureText": "上传失败。请重试",
45
35
  "neptune.Upload.csSuccessText": "上传完毕!",
@@ -2,77 +2,72 @@
2
2
  border: none;
3
3
  }
4
4
  .np-icon-button-tertiary-default {
5
- color: var(--color-interactive-primary);
6
- background-color: rgba(134,167,189,0.10196);
7
- background-color: var(--color-background-neutral);
5
+ --Button-color: var(--color-interactive-primary);
6
+ --Button-background: var(--color-background-neutral);
8
7
  }
9
8
  .np-icon-button-tertiary-default:not(.disabled):not(:disabled):hover {
10
- background-color: var(--color-background-neutral-hover);
9
+ --Button-hover-background: var(--color-background-neutral-hover);
11
10
  }
12
11
  .np-icon-button-tertiary-default:not(.disabled):not(:disabled):active {
13
- background-color: var(--color-background-neutral-active);
12
+ --Button-active-background: var(--color-background-neutral-active);
14
13
  }
15
14
  .np-icon-button-primary-default {
16
- color: var(--color-interactive-control);
17
- background-color: #00a2dd;
18
- background-color: var(--color-interactive-accent);
15
+ --Button-color: var(--color-interactive-control);
16
+ --Button-background: var(--color-interactive-accent);
19
17
  }
20
18
  .np-icon-button-primary-default:not(.disabled):not(:disabled):hover {
21
- background-color: #008fc9;
22
- background-color: var(--color-interactive-accent-hover);
19
+ --Button-hover-background: var(--color-interactive-accent-hover);
23
20
  }
24
21
  .np-icon-button-primary-default:not(.disabled):not(:disabled):active {
25
- background-color: #0081ba;
26
- background-color: var(--color-interactive-accent-active);
22
+ --Button-active-background: var(--color-interactive-accent-active);
27
23
  }
28
24
  .np-icon-button-primary-negative {
29
- color: var(--color-contrast-overlay);
30
- background-color: var(--color-sentiment-negative-primary);
25
+ --Button-color: var(--color-contrast-overlay);
26
+ --Button-background: var(--color-sentiment-negative-primary);
31
27
  }
32
28
  .np-icon-button-primary-negative:not(.disabled):not(:disabled):hover {
33
- background-color: var(--color-sentiment-negative-primary-hover);
29
+ --Button-hover-background: var(--color-sentiment-negative-primary-hover);
34
30
  }
35
31
  .np-icon-button-primary-negative:not(.disabled):not(:disabled):active {
36
- background-color: var(--color-sentiment-negative-primary-active);
32
+ --Button-active-background: var(--color-sentiment-negative-primary-active);
37
33
  }
38
34
  .np-theme-personal--bright-green .np-icon-button-primary-negative {
39
35
  color: var(--color-white);
40
36
  }
41
37
  .np-icon-button-minimal-default {
42
- color: var(--color-interactive-primary);
43
- background-color: #ffffff;
44
- background-color: var(--color-background-screen);
38
+ --Button-color: var(--color-interactive-primary);
39
+ --Button-background: var(--color-background-screen);
45
40
  background-color: transparent;
46
41
  }
47
42
  .np-icon-button-minimal-default:not(.disabled):not(:disabled):hover {
48
- background-color: var(--color-background-screen-hover);
43
+ --Button-hover-background: var(--color-background-screen-hover);
49
44
  }
50
45
  .np-icon-button-minimal-default:not(.disabled):not(:disabled):active {
51
- background-color: var(--color-background-screen-active);
46
+ --Button-active-background: var(--color-background-screen-active);
52
47
  }
53
48
  .np-icon-button-secondary-default {
54
- color: var(--color-interactive-primary);
55
- background-color: var(--color-interactive-neutral);
49
+ --Button-color: var(--color-interactive-primary);
50
+ --Button-background: var(--color-interactive-neutral);
56
51
  }
57
52
  .np-icon-button-secondary-default:not(.disabled):not(:disabled):hover {
58
- background-color: var(--color-interactive-neutral-hover);
53
+ --Button-hover-background: var(--color-interactive-neutral-hover);
59
54
  }
60
55
  .np-icon-button-secondary-default:not(.disabled):not(:disabled):active {
61
- background-color: var(--color-interactive-neutral-active);
56
+ --Button-active-background: var(--color-interactive-neutral-active);
62
57
  }
63
58
  .np-theme-personal--bright-green .np-icon-button-secondary-default,
64
59
  .np-theme-personal--forest-green .np-icon-button-secondary-default {
65
60
  color: var(--color-interactive-control);
66
61
  }
67
62
  .np-icon-button-secondary-negative {
68
- color: var(--color-sentiment-negative-primary);
69
- background-color: var(--color-sentiment-negative-secondary);
63
+ --Button-color: var(--color-sentiment-negative-primary);
64
+ --Button-background: var(--color-sentiment-negative-secondary);
70
65
  }
71
66
  .np-icon-button-secondary-negative:not(.disabled):not(:disabled):hover {
72
- background-color: var(--color-sentiment-negative-secondary-hover);
67
+ --Button-hover-background: var(--color-sentiment-negative-secondary-hover);
73
68
  }
74
69
  .np-icon-button-secondary-negative:not(.disabled):not(:disabled):active {
75
- background-color: var(--color-sentiment-negative-secondary-active);
70
+ --Button-active-background: var(--color-sentiment-negative-secondary-active);
76
71
  }
77
72
  .np-theme-personal--bright-green .np-icon-button-secondary-negative {
78
73
  color: var(--color-white);
@@ -42,14 +42,14 @@
42
42
  }
43
43
 
44
44
  .colors(@icon-color, @bg-color) {
45
- color: var(@icon-color);
46
- background-color: var(@bg-color);
45
+ --Button-color: var(@icon-color);
46
+ --Button-background: var(@bg-color);
47
47
 
48
48
  &:not(.disabled, :disabled):hover {
49
- background-color:~"var(@{bg-color}-hover)";
49
+ --Button-hover-background:~"var(@{bg-color}-hover)";
50
50
  }
51
51
  &:not(.disabled, :disabled):active {
52
- background-color:~"var(@{bg-color}-active)";
52
+ --Button-active-background:~"var(@{bg-color}-active)";
53
53
  }
54
54
  }
55
55
  }
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 = AnchorHTMLAttributes<HTMLAnchorElement> & { type?: LinkLarge | LinkDefault };
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 { formatMessage } = useIntl();
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
- <a
41
+ <PrimitiveAnchor
33
42
  href={href}
34
43
  target={target}
35
- className={clsx('np-link', type ? `np-text-${type}` : undefined, 'd-inline-flex', 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
- </a>
51
+ </PrimitiveAnchor>
43
52
  );
44
53
  };
45
54