@transferwise/components 46.132.1 → 46.133.1

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 (90) hide show
  1. package/build/chips/Chips.js.map +1 -1
  2. package/build/chips/Chips.mjs.map +1 -1
  3. package/build/inputs/InputGroup.js +10 -1
  4. package/build/inputs/InputGroup.js.map +1 -1
  5. package/build/inputs/InputGroup.mjs +10 -1
  6. package/build/inputs/InputGroup.mjs.map +1 -1
  7. package/build/label/Label.js +1 -1
  8. package/build/label/Label.js.map +1 -1
  9. package/build/label/Label.mjs +1 -1
  10. package/build/label/Label.mjs.map +1 -1
  11. package/build/logo/Logo.js +6 -0
  12. package/build/logo/Logo.js.map +1 -1
  13. package/build/logo/Logo.mjs +6 -0
  14. package/build/logo/Logo.mjs.map +1 -1
  15. package/build/main.css +22 -6
  16. package/build/phoneNumberInput/PhoneNumberInput.js +6 -1
  17. package/build/phoneNumberInput/PhoneNumberInput.js.map +1 -1
  18. package/build/phoneNumberInput/PhoneNumberInput.mjs +6 -1
  19. package/build/phoneNumberInput/PhoneNumberInput.mjs.map +1 -1
  20. package/build/styles/inputs/InputGroup.css +10 -2
  21. package/build/styles/listItem/ListItem.css +4 -4
  22. package/build/styles/listItem/ListItem.grid.css +3 -3
  23. package/build/styles/main.css +22 -6
  24. package/build/styles/phoneNumberInput/PhoneNumberInput.css +5 -0
  25. package/build/types/chips/Chips.d.ts +1 -1
  26. package/build/types/chips/Chips.d.ts.map +1 -1
  27. package/build/types/common/commonProps.d.ts +0 -6
  28. package/build/types/common/commonProps.d.ts.map +1 -1
  29. package/build/types/label/Label.d.ts.map +1 -1
  30. package/build/types/logo/Logo.d.ts +10 -1
  31. package/build/types/logo/Logo.d.ts.map +1 -1
  32. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  33. package/package.json +19 -19
  34. package/src/button/_stories/Button.accessibility.docs.mdx +10 -6
  35. package/src/button/_stories/Button.story.tsx +15 -7
  36. package/src/checkboxButton/CheckboxButton.story.tsx +125 -44
  37. package/src/checkboxButton/CheckboxButton.test.story.tsx +236 -0
  38. package/src/chips/Chips.story.tsx +141 -102
  39. package/src/chips/Chips.test.story.tsx +177 -0
  40. package/src/chips/Chips.tsx +1 -1
  41. package/src/circularButton/CircularButton.story.tsx +261 -49
  42. package/src/circularButton/CircularButton.test.story.tsx +192 -2
  43. package/src/common/bottomSheet/BottomSheet.story.tsx +11 -9
  44. package/src/common/bottomSheet/BottomSheet.test.story.tsx +28 -15
  45. package/src/common/commonProps.ts +0 -6
  46. package/src/divider/Divider.accessibility.docs.mdx +1 -10
  47. package/src/divider/Divider.story.tsx +0 -1
  48. package/src/expressiveMoneyInput/ExpressiveMoneyInput.story.tsx +1 -2
  49. package/src/header/Header.accessibility.docs.mdx +9 -5
  50. package/src/iconButton/IconButton.story.tsx +315 -110
  51. package/src/iconButton/IconButton.test.story.tsx +217 -44
  52. package/src/inputs/InputGroup.css +10 -2
  53. package/src/inputs/InputGroup.less +12 -2
  54. package/src/inputs/InputGroup.story.tsx +27 -0
  55. package/src/inputs/InputGroup.tsx +10 -0
  56. package/src/inputs/SelectInput/_stories/SelectInput.story.tsx +0 -1
  57. package/src/label/Label.tsx +1 -2
  58. package/src/legacylistItem/LegacyListItem.test.story.tsx +1 -1
  59. package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.story.tsx +0 -1
  60. package/src/listItem/AvatarLayout/ListItemAvatarLayout.story.tsx +0 -1
  61. package/src/listItem/AvatarView/ListItemAvatarView.story.tsx +0 -1
  62. package/src/listItem/Button/ListItemButton.story.tsx +0 -1
  63. package/src/listItem/Checkbox/ListItemCheckbox.story.tsx +0 -1
  64. package/src/listItem/IconButton/ListItemIconButton.story.tsx +0 -1
  65. package/src/listItem/ListItem.css +4 -4
  66. package/src/listItem/ListItem.grid.css +3 -3
  67. package/src/listItem/ListItem.grid.less +5 -3
  68. package/src/listItem/ListItem.less +1 -1
  69. package/src/listItem/ListItem.vars.less +2 -2
  70. package/src/listItem/Navigation/ListItemNavigation.story.tsx +0 -1
  71. package/src/listItem/Prompt/ListItemPrompt.story.tsx +0 -1
  72. package/src/listItem/Radio/ListItemRadio.story.tsx +0 -1
  73. package/src/listItem/Switch/ListItemSwitch.story.tsx +0 -1
  74. package/src/listItem/_stories/ListItem.layout.test.story.tsx +55 -0
  75. package/src/listItem/_stories/ListItem.story.tsx +1 -0
  76. package/src/logo/Logo.story.tsx +181 -21
  77. package/src/logo/Logo.test.story.tsx +40 -7
  78. package/src/logo/Logo.tsx +10 -1
  79. package/src/main.css +22 -6
  80. package/src/phoneNumberInput/PhoneNumberInput.css +5 -0
  81. package/src/phoneNumberInput/PhoneNumberInput.less +7 -0
  82. package/src/phoneNumberInput/PhoneNumberInput.tsx +10 -1
  83. package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +0 -1
  84. package/src/section/Section.story.tsx +12 -7
  85. package/src/sentimentSurface/SentimentSurface.story.tsx +1 -1
  86. package/src/snackbar/Snackbar.test.story.tsx +16 -104
  87. package/src/summary/Summary.test.story.tsx +1 -1
  88. package/src/switch/Switch.story.tsx +64 -42
  89. package/src/switch/Switch.test.story.tsx +123 -0
  90. package/src/switchOption/SwitchOption.story.tsx +0 -1
@@ -1,11 +1,18 @@
1
- import { Freeze } from '@transferwise/icons';
1
+ import { Freeze, Plus, Send, Convert, Card } from '@transferwise/icons';
2
2
 
3
3
  import { Meta, StoryObj } from '@storybook/react-webpack5';
4
+ import { expect, fn, userEvent, within } from 'storybook/test';
5
+ import { useState } from 'react';
4
6
  import CircularButton from './CircularButton';
5
7
  import Title from '../title';
6
8
  import Body from '../body';
7
9
  import { withVariantConfig } from '../../.storybook/helpers';
8
10
 
11
+ const wait = async (ms: number) =>
12
+ new Promise<void>((resolve) => {
13
+ setTimeout(resolve, ms);
14
+ });
15
+
9
16
  export default {
10
17
  component: CircularButton,
11
18
  title: 'Actions/CircularButton/Tests',
@@ -14,6 +21,188 @@ export default {
14
21
 
15
22
  type Story = StoryObj<typeof CircularButton>;
16
23
 
24
+ /** All priorities, types, and states across all themes. */
25
+ export const Variants: Story = {
26
+ render: () => {
27
+ const rowStyle = {
28
+ display: 'grid',
29
+ gridTemplateColumns: 'repeat(4, minmax(0, 100px))',
30
+ gap: '16px',
31
+ textAlign: 'center' as const,
32
+ };
33
+
34
+ return (
35
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
36
+ <div style={rowStyle}>
37
+ <CircularButton priority="primary" type="default" icon={<Send />} onClick={fn()}>
38
+ Primary
39
+ </CircularButton>
40
+ <CircularButton priority="secondary" type="default" icon={<Plus />} onClick={fn()}>
41
+ Secondary
42
+ </CircularButton>
43
+ <CircularButton disabled priority="primary" type="default" icon={<Card />}>
44
+ Primary disabled
45
+ </CircularButton>
46
+ <CircularButton disabled priority="secondary" type="default" icon={<Card />}>
47
+ Secondary disabled
48
+ </CircularButton>
49
+ </div>
50
+ <div style={rowStyle}>
51
+ <CircularButton priority="primary" type="negative" icon={<Send />} onClick={fn()}>
52
+ Primary
53
+ </CircularButton>
54
+ <CircularButton priority="secondary" type="negative" icon={<Convert />} onClick={fn()}>
55
+ Secondary
56
+ </CircularButton>
57
+ <CircularButton disabled priority="primary" type="negative" icon={<Card />}>
58
+ Primary disabled
59
+ </CircularButton>
60
+ <CircularButton disabled priority="secondary" type="negative" icon={<Card />}>
61
+ Secondary disabled
62
+ </CircularButton>
63
+ </div>
64
+ </div>
65
+ );
66
+ },
67
+ ...withVariantConfig(['default', 'dark', 'bright-green', 'forest-green']),
68
+ };
69
+
70
+ /**
71
+ * `Space` or `Enter` activates when focused. Tab skips disabled buttons.
72
+ */
73
+ export const KeyboardInteraction: Story = {
74
+ render: () => {
75
+ const onClick = fn();
76
+ return (
77
+ <div style={{ display: 'flex', gap: '24px', padding: '16px' }}>
78
+ <CircularButton priority="primary" type="default" icon={<Send />} onClick={onClick}>
79
+ Send
80
+ </CircularButton>
81
+ <CircularButton priority="secondary" type="default" icon={<Plus />} onClick={onClick}>
82
+ Add funds
83
+ </CircularButton>
84
+ <CircularButton priority="primary" type="negative" icon={<Convert />} onClick={onClick}>
85
+ Convert
86
+ </CircularButton>
87
+ <CircularButton
88
+ priority="primary"
89
+ type="default"
90
+ icon={<Card />}
91
+ disabled
92
+ onClick={onClick}
93
+ >
94
+ Disabled
95
+ </CircularButton>
96
+ </div>
97
+ );
98
+ },
99
+ play: async ({ canvasElement, step }) => {
100
+ const canvas = within(canvasElement);
101
+ const buttons = canvas.getAllByRole('button');
102
+
103
+ await step('tab to Send and press Space', async () => {
104
+ await userEvent.tab();
105
+ await expect(buttons[0]).toHaveFocus();
106
+ await wait(400);
107
+ await userEvent.keyboard(' ');
108
+ });
109
+
110
+ await wait(400);
111
+
112
+ await step('tab to Add funds and press Space', async () => {
113
+ await userEvent.tab();
114
+ await expect(buttons[1]).toHaveFocus();
115
+ await wait(400);
116
+ await userEvent.keyboard(' ');
117
+ });
118
+
119
+ await wait(400);
120
+
121
+ await step('tab to Convert and press Space', async () => {
122
+ await userEvent.tab();
123
+ await expect(buttons[2]).toHaveFocus();
124
+ await wait(400);
125
+ await userEvent.keyboard(' ');
126
+ });
127
+
128
+ await wait(400);
129
+
130
+ await step('tab skips Disabled button', async () => {
131
+ await userEvent.tab();
132
+ // Disabled button should be skipped, focus leaves the component
133
+ await expect(buttons[3]).not.toHaveFocus();
134
+ });
135
+ },
136
+ };
137
+
138
+ /** Base variants in right-to-left layout. */
139
+ export const RTL: Story = {
140
+ render: function Render() {
141
+ const [clicks, setClicks] = useState(0);
142
+ const rowStyle = {
143
+ display: 'grid',
144
+ gridTemplateColumns: 'repeat(4, minmax(0, 100px))',
145
+ gap: '16px',
146
+ textAlign: 'center' as const,
147
+ };
148
+
149
+ return (
150
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '24px', padding: '16px' }}>
151
+ <div style={rowStyle}>
152
+ <CircularButton
153
+ priority="primary"
154
+ type="default"
155
+ icon={<Send />}
156
+ onClick={() => setClicks((c) => c + 1)}
157
+ >
158
+ Primary
159
+ </CircularButton>
160
+ <CircularButton
161
+ priority="secondary"
162
+ type="default"
163
+ icon={<Plus />}
164
+ onClick={() => setClicks((c) => c + 1)}
165
+ >
166
+ Secondary
167
+ </CircularButton>
168
+ <CircularButton disabled priority="primary" type="default" icon={<Card />}>
169
+ Primary disabled
170
+ </CircularButton>
171
+ <CircularButton disabled priority="secondary" type="default" icon={<Card />}>
172
+ Secondary disabled
173
+ </CircularButton>
174
+ </div>
175
+ <div style={rowStyle}>
176
+ <CircularButton
177
+ priority="primary"
178
+ type="negative"
179
+ icon={<Send />}
180
+ onClick={() => setClicks((c) => c + 1)}
181
+ >
182
+ Primary
183
+ </CircularButton>
184
+ <CircularButton
185
+ priority="secondary"
186
+ type="negative"
187
+ icon={<Convert />}
188
+ onClick={() => setClicks((c) => c + 1)}
189
+ >
190
+ Secondary
191
+ </CircularButton>
192
+ <CircularButton disabled priority="primary" type="negative" icon={<Card />}>
193
+ Primary disabled
194
+ </CircularButton>
195
+ <CircularButton disabled priority="secondary" type="negative" icon={<Card />}>
196
+ Secondary disabled
197
+ </CircularButton>
198
+ </div>
199
+ </div>
200
+ );
201
+ },
202
+ ...withVariantConfig(['rtl']),
203
+ };
204
+
205
+ /** Long labels are centered beneath the icon. */
17
206
  export const CenteredText: Story = {
18
207
  render: () => {
19
208
  return (
@@ -79,7 +268,8 @@ const All: Story = {
79
268
  },
80
269
  };
81
270
 
82
- export const All400Zoom: Story = {
271
+ /** All variants at 400% zoom for accessibility testing. */
272
+ export const Zoom400: Story = {
83
273
  ...All,
84
274
  ...withVariantConfig(['400%'], All),
85
275
  };
@@ -2,15 +2,13 @@ import { action } from 'storybook/actions';
2
2
  import { Meta, StoryObj } from '@storybook/react-webpack5';
3
3
  import { FastFlag } from '@transferwise/icons';
4
4
  import { useState } from 'react';
5
-
6
- import Body from '../../body/Body';
7
5
  import Button from '../../button';
8
- import NavigationOption from '../../navigationOption';
9
- import { lorem10, lorem500 } from '../../test-utils';
6
+ import { lorem10 } from '../../test-utils';
10
7
  import Title from '../../title/Title';
11
8
  import { Typography } from '../propsValues/typography';
12
9
 
13
10
  import BottomSheet from './BottomSheet';
11
+ import ListItem from '../../listItem';
14
12
 
15
13
  export default {
16
14
  component: BottomSheet,
@@ -48,11 +46,15 @@ export const Basic: Story = {
48
46
  {lorem10}
49
47
  <br />
50
48
  <br />
51
- <NavigationOption
52
- title="Navigation option"
53
- content="Button and icon are vertically centered."
54
- media={<FastFlag size={24} />}
55
- isContainerAligned
49
+ <ListItem
50
+ title="List item"
51
+ subtitle="Button and icon are vertically centered."
52
+ control={<ListItem.Navigation href="#" />}
53
+ media={
54
+ <ListItem.AvatarView>
55
+ <FastFlag />
56
+ </ListItem.AvatarView>
57
+ }
56
58
  />
57
59
  </>
58
60
  ),
@@ -8,8 +8,8 @@ import { Typography } from '../propsValues/typography';
8
8
  import Alert from '../../alert';
9
9
  import Body from '../../body';
10
10
  import Button from '../../button';
11
- import NavigationOption from '../../navigationOption';
12
11
  import Title from '../../title';
12
+ import ListItem from '../../listItem';
13
13
  import BottomSheet from './BottomSheet';
14
14
  import { withVariantConfig } from '../../../.storybook/helpers';
15
15
 
@@ -109,11 +109,15 @@ const Basic: Story = {
109
109
  {lorem10}
110
110
  <br />
111
111
  <br />
112
- <NavigationOption
113
- title="Navigation option"
114
- content="Button and icon are vertically centered."
115
- media={<FastFlag size={24} />}
116
- isContainerAligned
112
+ <ListItem
113
+ title="List item"
114
+ subtitle="Button and icon are vertically centered."
115
+ control={<ListItem.Navigation href="#" />}
116
+ media={
117
+ <ListItem.AvatarView>
118
+ <FastFlag />
119
+ </ListItem.AvatarView>
120
+ }
117
121
  />
118
122
  </>
119
123
  ),
@@ -153,16 +157,25 @@ const WithOverflowContent: Story = {
153
157
  <>
154
158
  <Title type={Typography.TITLE_SECTION}>Money without borders</Title>
155
159
  {lorem10}
156
- <NavigationOption
157
- title="Navigation option"
158
- content="Button and icon are vertically centered."
159
- media={<FastFlag size={24} />}
160
+ <ListItem
161
+ title="List item"
162
+ subtitle="Button and icon are vertically centered."
163
+ control={<ListItem.Navigation href="#" />}
164
+ media={
165
+ <ListItem.AvatarView>
166
+ <FastFlag />
167
+ </ListItem.AvatarView>
168
+ }
160
169
  />
161
- <NavigationOption
162
- title="Navigation option"
163
- content="Button and icon are vertically centered."
164
- media={<FastFlag size={24} />}
165
- isContainerAligned
170
+ <ListItem
171
+ title="List item"
172
+ subtitle="Button and icon are vertically centered."
173
+ control={<ListItem.Navigation href="#" />}
174
+ media={
175
+ <ListItem.AvatarView>
176
+ <FastFlag />
177
+ </ListItem.AvatarView>
178
+ }
166
179
  />
167
180
  {lorem500}
168
181
  <Body type={Typography.BODY_DEFAULT_BOLD}>{lorem10}</Body>
@@ -1,10 +1,4 @@
1
1
  export type CommonProps = {
2
- /**
3
- * Space-separated list of the case-sensitive CSS classes,
4
- * most would be applied to outermost element inside the component
5
- *
6
- * @see https://github.com/transferwise/neptune-web/blob/main/rfc/0001-always-pass-classname.md
7
- */
8
2
  className?: string;
9
3
  };
10
4
 
@@ -1,6 +1,4 @@
1
- import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';
2
- import { NavigationOption } from '..';
3
- import { Bulb } from '@transferwise/icons';
1
+ import { Meta, Source } from '@storybook/addon-docs/blocks';
4
2
 
5
3
  <Meta title="Layouts/Divider/Accessibility" />
6
4
 
@@ -8,13 +6,6 @@ import { Bulb } from '@transferwise/icons';
8
6
 
9
7
  A Divider is used to separate sections of content. While it doesn't directly announce anything to screen readers, there are a few considerations:
10
8
 
11
- <NavigationOption
12
- media={<Bulb size={24} />}
13
- title="Design guidance"
14
- content="Before you start, please review the documentation on how separators should be used, announced or hidden from assistive tech."
15
- href="https://wise.design/components/divider"
16
- />
17
-
18
9
  <br />
19
10
  <br />
20
11
 
@@ -84,7 +84,6 @@ export const Playground: Story = {
84
84
  args: {
85
85
  level: 'section',
86
86
  },
87
- tags: ['!autodocs'],
88
87
  };
89
88
 
90
89
  /**
@@ -52,7 +52,7 @@ const withScrollbarProtector: Decorator = (Story) => (
52
52
  export default {
53
53
  title: 'Forms/ExpressiveMoneyInput',
54
54
  component: ExpressiveMoneyInput,
55
- tags: ['contribution'],
55
+ tags: ['early-access', 'contribution'],
56
56
  parameters: {
57
57
  docs: {
58
58
  canvas: {
@@ -78,7 +78,6 @@ export default {
78
78
  type Story = StoryObj<ExpressiveMoneyInputProps>;
79
79
 
80
80
  export const Playground: Story = {
81
- tags: ['!autodocs'],
82
81
  render: (args: ExpressiveMoneyInputProps) => <ExpressiveMoneyInput {...args} />,
83
82
  };
84
83
 
@@ -1,6 +1,6 @@
1
1
  import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';
2
- import { NavigationOption } from '..';
3
2
  import { Bulb } from '@transferwise/icons';
3
+ import ListItem from '../listItem';
4
4
  import * as stories from './Header.story';
5
5
 
6
6
  <Meta title="Typography/Header/Accessibility" />
@@ -9,11 +9,15 @@ import * as stories from './Header.story';
9
9
 
10
10
  Given the `Header` is a key component for structuring content and conveying hierarchy, ensuring its accessibility is crucial for an inclusive experience.
11
11
 
12
- <NavigationOption
13
- media={<Bulb size={24} />}
12
+ <ListItem
14
13
  title="Design guidance"
15
- content="Before you start, familiarise yourself with the dedicated accessibility documentation."
16
- href="https://wise.design/components/section-header#accessibility"
14
+ subtitle="Before you start, familiarise yourself with the provided guidance."
15
+ control={<ListItem.Navigation href="https://wise.design/components/section-header" />}
16
+ media={
17
+ <ListItem.AvatarView>
18
+ <Bulb />
19
+ </ListItem.AvatarView>
20
+ }
17
21
  />
18
22
 
19
23
  <br />