@transferwise/components 46.158.0 → 46.159.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 (201) hide show
  1. package/build/FlowNavigation/FlowNavigation.js +5 -14
  2. package/build/FlowNavigation/FlowNavigation.js.map +1 -1
  3. package/build/FlowNavigation/FlowNavigation.mjs +5 -14
  4. package/build/FlowNavigation/FlowNavigation.mjs.map +1 -1
  5. package/build/_deprecated/OverlayHeader/OverlayHeader.js +6 -41
  6. package/build/_deprecated/OverlayHeader/OverlayHeader.js.map +1 -1
  7. package/build/_deprecated/OverlayHeader/OverlayHeader.mjs +6 -41
  8. package/build/_deprecated/OverlayHeader/OverlayHeader.mjs.map +1 -1
  9. package/build/i18n/cs.json +5 -0
  10. package/build/i18n/cs.json.js +5 -0
  11. package/build/i18n/cs.json.js.map +1 -1
  12. package/build/i18n/cs.json.mjs +5 -0
  13. package/build/i18n/cs.json.mjs.map +1 -1
  14. package/build/i18n/de.json +5 -0
  15. package/build/i18n/de.json.js +5 -0
  16. package/build/i18n/de.json.js.map +1 -1
  17. package/build/i18n/de.json.mjs +5 -0
  18. package/build/i18n/de.json.mjs.map +1 -1
  19. package/build/i18n/es.json +5 -0
  20. package/build/i18n/es.json.js +5 -0
  21. package/build/i18n/es.json.js.map +1 -1
  22. package/build/i18n/es.json.mjs +5 -0
  23. package/build/i18n/es.json.mjs.map +1 -1
  24. package/build/i18n/fr.json +5 -0
  25. package/build/i18n/fr.json.js +5 -0
  26. package/build/i18n/fr.json.js.map +1 -1
  27. package/build/i18n/fr.json.mjs +5 -0
  28. package/build/i18n/fr.json.mjs.map +1 -1
  29. package/build/i18n/hu.json +5 -0
  30. package/build/i18n/hu.json.js +5 -0
  31. package/build/i18n/hu.json.js.map +1 -1
  32. package/build/i18n/hu.json.mjs +5 -0
  33. package/build/i18n/hu.json.mjs.map +1 -1
  34. package/build/i18n/id.json +5 -0
  35. package/build/i18n/id.json.js +5 -0
  36. package/build/i18n/id.json.js.map +1 -1
  37. package/build/i18n/id.json.mjs +5 -0
  38. package/build/i18n/id.json.mjs.map +1 -1
  39. package/build/i18n/it.json +5 -0
  40. package/build/i18n/it.json.js +5 -0
  41. package/build/i18n/it.json.js.map +1 -1
  42. package/build/i18n/it.json.mjs +5 -0
  43. package/build/i18n/it.json.mjs.map +1 -1
  44. package/build/i18n/ja.json +5 -0
  45. package/build/i18n/ja.json.js +5 -0
  46. package/build/i18n/ja.json.js.map +1 -1
  47. package/build/i18n/ja.json.mjs +5 -0
  48. package/build/i18n/ja.json.mjs.map +1 -1
  49. package/build/i18n/nl.json +5 -0
  50. package/build/i18n/nl.json.js +5 -0
  51. package/build/i18n/nl.json.js.map +1 -1
  52. package/build/i18n/nl.json.mjs +5 -0
  53. package/build/i18n/nl.json.mjs.map +1 -1
  54. package/build/i18n/pl.json +5 -0
  55. package/build/i18n/pl.json.js +5 -0
  56. package/build/i18n/pl.json.js.map +1 -1
  57. package/build/i18n/pl.json.mjs +5 -0
  58. package/build/i18n/pl.json.mjs.map +1 -1
  59. package/build/i18n/pt.json +5 -0
  60. package/build/i18n/pt.json.js +5 -0
  61. package/build/i18n/pt.json.js.map +1 -1
  62. package/build/i18n/pt.json.mjs +5 -0
  63. package/build/i18n/pt.json.mjs.map +1 -1
  64. package/build/i18n/ro.json +5 -0
  65. package/build/i18n/ro.json.js +5 -0
  66. package/build/i18n/ro.json.js.map +1 -1
  67. package/build/i18n/ro.json.mjs +5 -0
  68. package/build/i18n/ro.json.mjs.map +1 -1
  69. package/build/i18n/ru.json +5 -0
  70. package/build/i18n/ru.json.js +5 -0
  71. package/build/i18n/ru.json.js.map +1 -1
  72. package/build/i18n/ru.json.mjs +5 -0
  73. package/build/i18n/ru.json.mjs.map +1 -1
  74. package/build/i18n/th.json +5 -0
  75. package/build/i18n/th.json.js +5 -0
  76. package/build/i18n/th.json.js.map +1 -1
  77. package/build/i18n/th.json.mjs +5 -0
  78. package/build/i18n/th.json.mjs.map +1 -1
  79. package/build/i18n/uk.json +5 -0
  80. package/build/i18n/uk.json.js +5 -0
  81. package/build/i18n/uk.json.js.map +1 -1
  82. package/build/i18n/uk.json.mjs +5 -0
  83. package/build/i18n/uk.json.mjs.map +1 -1
  84. package/build/i18n/zh-HK.json +5 -0
  85. package/build/i18n/zh-HK.json.js +5 -0
  86. package/build/i18n/zh-HK.json.js.map +1 -1
  87. package/build/i18n/zh-HK.json.mjs +5 -0
  88. package/build/i18n/zh-HK.json.mjs.map +1 -1
  89. package/build/main.css +19 -4145
  90. package/build/styles/FlowNavigation/FlowNavigation.css +7 -13
  91. package/build/styles/ListItem/ListItem.css +1 -0
  92. package/build/styles/PocketSurface/PocketSurface.css +2 -11
  93. package/build/styles/SentimentSurface/SentimentSurface.css +0 -23
  94. package/build/styles/css/neptune.css +0 -2821
  95. package/build/styles/main.css +19 -4145
  96. package/build/styles/styles/less/neptune.css +0 -2821
  97. package/build/types/FlowNavigation/FlowNavigation.d.ts +2 -9
  98. package/build/types/FlowNavigation/FlowNavigation.d.ts.map +1 -1
  99. package/build/types/ListItem/_stories/variants/helpers.d.ts.map +1 -1
  100. package/build/types/_deprecated/OverlayHeader/OverlayHeader.d.ts.map +1 -1
  101. package/package.json +10 -10
  102. package/src/Accordion/_stories/Accordion.test.story.tsx +71 -0
  103. package/src/AvatarLayout/_stories/AvatarLayout.test.story.tsx +64 -0
  104. package/src/AvatarView/_stories/AvatarView.test.story.tsx +151 -0
  105. package/src/Button/LegacyButton/_stories/LegacyButton.test.story.tsx +22 -0
  106. package/src/Button/_stories/Button.test.story.tsx +65 -0
  107. package/src/Calendar/_stories/Calendar.test.story.tsx +73 -24
  108. package/src/Carousel/_stories/Carousel.test.story.tsx +59 -0
  109. package/src/Checkbox/_stories/Checkbox.test.story.tsx +20 -0
  110. package/src/CheckboxButton/_stories/CheckboxButton.test.story.tsx +17 -37
  111. package/src/Chevron/_stories/Chevron.test.story.tsx +26 -0
  112. package/src/Chips/_stories/Chips.test.story.tsx +39 -34
  113. package/src/CircularButton/_stories/CircularButton.test.story.tsx +0 -68
  114. package/src/DateInput/_stories/DateInput.test.story.tsx +13 -0
  115. package/src/DateLookup/_stories/DateLookup.rtl.test.story.tsx +88 -0
  116. package/src/Decision/_stories/Decision.test.story.tsx +79 -0
  117. package/src/DefinitionList/_stories/DefinitionList.test.story.tsx +54 -1
  118. package/src/Drawer/_stories/Drawer.rtl.test.story.tsx +58 -0
  119. package/src/ExpressiveMoneyInput/_stories/ExpressiveMoneyInput.rtl.test.story.tsx +118 -0
  120. package/src/Field/_stories/Field.test.story.tsx +46 -0
  121. package/src/FlowNavigation/FlowNavigation.css +7 -13
  122. package/src/FlowNavigation/FlowNavigation.less +6 -15
  123. package/src/FlowNavigation/FlowNavigation.tsx +6 -27
  124. package/src/FlowNavigation/_stories/FlowNavigation.story.tsx +0 -86
  125. package/src/FlowNavigation/_stories/FlowNavigation.test.story.tsx +44 -0
  126. package/src/Header/_stories/Header.test.story.tsx +27 -0
  127. package/src/Info/_stories/Info.rtl.test.story.tsx +64 -0
  128. package/src/Inputs/SelectInput/_stories/SelectInput.rtl.test.story.tsx +135 -0
  129. package/src/Inputs/_stories/InputGroup.test.story.tsx +69 -0
  130. package/src/Inputs/_stories/SearchInput.test.story.tsx +32 -0
  131. package/src/Inputs/_stories/TextArea.test.story.tsx +27 -0
  132. package/src/InstructionsList/_stories/InstructionsList.test.story.tsx +30 -0
  133. package/src/Label/_stories/Label.test.story.tsx +36 -0
  134. package/src/Link/_stories/Link.test.story.tsx +26 -0
  135. package/src/ListItem/ListItem.css +1 -0
  136. package/src/ListItem/_stories/{variants/ListItem.rtl.test.story.tsx → ListItem.rtl.test.story.tsx} +6 -10
  137. package/src/ListItem/_stories/variants/helpers.tsx +2 -6
  138. package/src/Logo/_stories/Logo.test.story.tsx +44 -0
  139. package/src/Modal/_stories/Modal.rtl.test.story.tsx +59 -0
  140. package/src/MoneyInput/_stories/MoneyInput.rtl.test.story.tsx +88 -0
  141. package/src/Nudge/_stories/Nudge.test.story.tsx +37 -0
  142. package/src/PhoneNumberInput/_stories/PhoneNumberInput.test.story.tsx +44 -0
  143. package/src/PocketSurface/PocketSurface.css +2 -11
  144. package/src/PocketSurface/PocketSurface.less +1 -1
  145. package/src/Popover/_stories/Popover.rtl.test.story.tsx +96 -0
  146. package/src/Progress/_stories/Progress.test.story.tsx +27 -0
  147. package/src/ProgressBar/_stories/ProgressBar.test.story.tsx +33 -0
  148. package/src/PromoCard/_stories/PromoCard.test.story.tsx +42 -0
  149. package/src/PromoCard/_stories/PromoCardGroup.test.story.tsx +51 -0
  150. package/src/Prompt/ActionPrompt/_stories/ActionPrompt.test.story.tsx +42 -1
  151. package/src/Prompt/CriticalBanner/_stories/CriticalBanner.test.story.tsx +34 -31
  152. package/src/Prompt/InfoPrompt/_stories/InfoPrompt.test.story.tsx +25 -0
  153. package/src/Prompt/InlinePrompt/_stories/InlinePrompt.test.story.tsx +27 -0
  154. package/src/Radio/_stories/Radio.test.story.tsx +61 -0
  155. package/src/RadioGroup/_stories/RadioGroup.test.story.tsx +56 -0
  156. package/src/Section/_stories/Section.test.story.tsx +29 -0
  157. package/src/SegmentedControl/_stories/SegmentedControl.test.story.tsx +45 -0
  158. package/src/SentimentSurface/SentimentSurface.css +0 -23
  159. package/src/SlidingPanel/_stories/SlidingPanel.rtl.test.story.tsx +70 -0
  160. package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +45 -0
  161. package/src/Snackbar/_stories/Snackbar.test.story.tsx +0 -31
  162. package/src/Stepper/_stories/Stepper.test.story.tsx +17 -0
  163. package/src/Switch/_stories/Switch.test.story.tsx +20 -26
  164. package/src/Table/_stories/Table.test.story.tsx +104 -0
  165. package/src/Tabs/_stories/Tabs.test.story.tsx +72 -0
  166. package/src/TextareaWithDisplayFormat/_stories/TextareaWithDisplayFormat.test.story.tsx +48 -0
  167. package/src/Tooltip/_stories/Tooltip.rtl.test.story.tsx +79 -0
  168. package/src/Typeahead/_stories/Typeahead.rtl.test.story.tsx +90 -0
  169. package/src/Upload/_stories/Upload.rtl.test.story.tsx +53 -0
  170. package/src/UploadInput/_stories/UploadInput.test.story.tsx +47 -0
  171. package/src/_deprecated/Alert/_stories/Alert.test.story.tsx +28 -1
  172. package/src/_deprecated/Card/_stories/Card.test.story.tsx +38 -0
  173. package/src/_deprecated/CriticalBanner/_stories/CriticalCommsBanner.test.story.tsx +18 -0
  174. package/src/_deprecated/InlineAlert/_stories/InlineAlert.test.story.tsx +26 -0
  175. package/src/_deprecated/OverlayHeader/OverlayHeader.tsx +2 -21
  176. package/src/_deprecated/OverlayHeader/_stories/OverlayHeader.test.story.tsx +42 -0
  177. package/src/_deprecated/Select/_stories/Select.rtl.test.story.tsx +71 -0
  178. package/src/common/BottomSheet/_stories/BottomSheet.test.story.tsx +23 -0
  179. package/src/common/Panel/_stories/Panel.story.tsx +107 -36
  180. package/src/i18n/cs.json +5 -0
  181. package/src/i18n/de.json +5 -0
  182. package/src/i18n/es.json +5 -0
  183. package/src/i18n/fr.json +5 -0
  184. package/src/i18n/hu.json +5 -0
  185. package/src/i18n/id.json +5 -0
  186. package/src/i18n/it.json +5 -0
  187. package/src/i18n/ja.json +5 -0
  188. package/src/i18n/nl.json +5 -0
  189. package/src/i18n/pl.json +5 -0
  190. package/src/i18n/pt.json +5 -0
  191. package/src/i18n/ro.json +5 -0
  192. package/src/i18n/ru.json +5 -0
  193. package/src/i18n/th.json +5 -0
  194. package/src/i18n/uk.json +5 -0
  195. package/src/i18n/zh-HK.json +5 -0
  196. package/src/main.css +19 -4145
  197. package/src/main.less +0 -1
  198. package/src/styles/less/neptune.css +0 -2821
  199. package/build/styles/_deprecated/OverlayHeader/OverlayHeader.css +0 -15
  200. package/src/_deprecated/OverlayHeader/OverlayHeader.css +0 -15
  201. package/src/_deprecated/OverlayHeader/OverlayHeader.less +0 -24
@@ -0,0 +1,44 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import Field from '../../Field/Field';
5
+ import PhoneNumberInput from '..';
6
+
7
+ export default {
8
+ component: PhoneNumberInput,
9
+ title: 'Forms/PhoneNumberInput/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof PhoneNumberInput>;
12
+
13
+ type Story = StoryObj<typeof PhoneNumberInput>;
14
+
15
+ /**
16
+ * The country code selector sits on the inline-start side of the phone number input.
17
+ * In RTL the two elements should swap sides — the selector moves to the right and
18
+ * the text field moves to the left. This diff verifies the flex row reverses correctly.
19
+ *
20
+ * Size variants are included because the size prop changes the input-group class and
21
+ * may affect spacing between the two sub-inputs.
22
+ */
23
+ export const RTLDiff: Story = {
24
+ render: () => (
25
+ <>
26
+ <Field label="Default (md)">
27
+ <PhoneNumberInput onChange={() => {}} />
28
+ </Field>
29
+
30
+ <Field label="Small (sm)">
31
+ <PhoneNumberInput size="sm" onChange={() => {}} />
32
+ </Field>
33
+
34
+ <Field label="Large (lg)">
35
+ <PhoneNumberInput size="lg" onChange={() => {}} />
36
+ </Field>
37
+
38
+ <Field label="With initial value">
39
+ <PhoneNumberInput initialValue="+447573135343" onChange={() => {}} />
40
+ </Field>
41
+ </>
42
+ ),
43
+ ...withRTLDiff(),
44
+ };
@@ -21,7 +21,6 @@
21
21
  --color-background-screen: #a0e1e1;
22
22
  }
23
23
 
24
-
25
24
  .wds-pocket-bright-orange {
26
25
  --color-content-primary: #260a2f;
27
26
  --color-content-secondary: #110415;
@@ -40,7 +39,6 @@
40
39
  --color-background-screen: #ffc091;
41
40
  }
42
41
 
43
-
44
42
  .wds-pocket-bright-pink {
45
43
  --color-content-primary: #320707;
46
44
  --color-content-secondary: #160303;
@@ -59,7 +57,6 @@
59
57
  --color-background-screen: #ffd7ef;
60
58
  }
61
59
 
62
-
63
60
  .wds-pocket-bright-yellow {
64
61
  --color-content-primary: #3a341c;
65
62
  --color-content-secondary: #110f08;
@@ -78,7 +75,6 @@
78
75
  --color-background-screen: #ffeb69;
79
76
  }
80
77
 
81
-
82
78
  .wds-pocket-dark-charcoal {
83
79
  --color-content-primary: #a0e1e1;
84
80
  --color-content-secondary: #ecf9f9;
@@ -97,7 +93,6 @@
97
93
  --color-background-screen: #21231d;
98
94
  }
99
95
 
100
-
101
96
  .wds-pocket-dark-gold {
102
97
  --color-content-primary: #ffeb69;
103
98
  --color-content-secondary: #fffce5;
@@ -116,7 +111,6 @@
116
111
  --color-background-screen: #3a341c;
117
112
  }
118
113
 
119
-
120
114
  .wds-pocket-dark-maroon {
121
115
  --color-content-primary: #ffd7ef;
122
116
  --color-content-secondary: #ffe5f5;
@@ -135,7 +129,6 @@
135
129
  --color-background-screen: #320707;
136
130
  }
137
131
 
138
-
139
132
  .wds-pocket-dark-purple {
140
133
  --color-content-primary: #ffc091;
141
134
  --color-content-secondary: #fff0e5;
@@ -153,11 +146,9 @@
153
146
  --color-interactive-control-active: #471358;
154
147
  --color-background-screen: #260a2f;
155
148
  }
156
-
157
-
158
149
  .wds-pocket-surface {
159
150
  background-color: #ffffff;
160
151
  background-color: var(--color-background-screen);
161
- color: #37517e;
162
- color: var(--color-content-primary);
152
+ color: #5d7079;
153
+ color: var(--color-content-secondary);
163
154
  }
@@ -2,5 +2,5 @@
2
2
 
3
3
  .wds-pocket-surface {
4
4
  background-color: var(--color-background-screen);
5
- color: var(--color-content-primary);
5
+ color: var(--color-content-secondary);
6
6
  }
@@ -0,0 +1,96 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { userEvent, within } from 'storybook/test';
3
+
4
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
+ import Button from '../../Button';
6
+ import { Position } from '../../common';
7
+ import Popover from '..';
8
+
9
+ export default {
10
+ component: Popover,
11
+ title: 'Dialogs/Popover/Tests/RTL Diff',
12
+ tags: ['!autodocs', '!manifest'],
13
+ } satisfies Meta<typeof Popover>;
14
+
15
+ type Story = StoryObj<typeof Popover>;
16
+
17
+ const iframeDiff = withRTLDiff({ renderAs: 'iframe' });
18
+
19
+ const containerStyle: React.CSSProperties = {
20
+ display: 'flex',
21
+ justifyContent: 'center',
22
+ alignItems: 'center',
23
+ minHeight: '24rem',
24
+ width: '100%',
25
+ };
26
+
27
+ const clickTrigger = async ({ canvasElement }: { canvasElement: HTMLElement }) => {
28
+ const canvas = within(canvasElement);
29
+ const trigger = canvas.queryByRole('button');
30
+ if (!trigger) return;
31
+ await userEvent.click(trigger);
32
+ };
33
+
34
+ export const PlacementRight: Story = {
35
+ render: () => (
36
+ <div style={containerStyle}>
37
+ <Popover
38
+ preferredPlacement={Position.RIGHT}
39
+ title="Guaranteed rate"
40
+ content="You'll get this rate as long as we receive your 10 EUR within the next 51 hours."
41
+ >
42
+ <Button v2>Placement right</Button>
43
+ </Popover>
44
+ </div>
45
+ ),
46
+ play: clickTrigger,
47
+ ...iframeDiff,
48
+ };
49
+
50
+ export const PlacementLeft: Story = {
51
+ render: () => (
52
+ <div style={containerStyle}>
53
+ <Popover
54
+ preferredPlacement={Position.LEFT}
55
+ title="Guaranteed rate"
56
+ content="You'll get this rate as long as we receive your 10 EUR within the next 51 hours."
57
+ >
58
+ <Button v2>Placement left</Button>
59
+ </Popover>
60
+ </div>
61
+ ),
62
+ play: clickTrigger,
63
+ ...iframeDiff,
64
+ };
65
+
66
+ export const PlacementTop: Story = {
67
+ render: () => (
68
+ <div style={containerStyle}>
69
+ <Popover
70
+ preferredPlacement={Position.TOP}
71
+ title="Guaranteed rate"
72
+ content="You'll get this rate as long as we receive your 10 EUR within the next 51 hours."
73
+ >
74
+ <Button v2>Placement top</Button>
75
+ </Popover>
76
+ </div>
77
+ ),
78
+ play: clickTrigger,
79
+ ...iframeDiff,
80
+ };
81
+
82
+ export const PlacementBottom: Story = {
83
+ render: () => (
84
+ <div style={containerStyle}>
85
+ <Popover
86
+ preferredPlacement={Position.BOTTOM}
87
+ title="Guaranteed rate"
88
+ content="You'll get this rate as long as we receive your 10 EUR within the next 51 hours."
89
+ >
90
+ <Button v2>Placement bottom</Button>
91
+ </Popover>
92
+ </div>
93
+ ),
94
+ play: clickTrigger,
95
+ ...iframeDiff,
96
+ };
@@ -0,0 +1,27 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import Progress from '..';
5
+
6
+ export default {
7
+ component: Progress,
8
+ title: 'Other/Progress/Tests',
9
+ tags: ['!autodocs', '!manifest'],
10
+ } satisfies Meta<typeof Progress>;
11
+
12
+ type Story = StoryObj<typeof Progress>;
13
+
14
+ /**
15
+ * The native <progress> element fills in the inline direction,
16
+ * so partial progress flips from left-to-right to right-to-left in RTL.
17
+ */
18
+ export const RTLDiff: Story = {
19
+ render: () => (
20
+ <>
21
+ <Progress id="progress-quarter" progress={{ value: 25, max: 100 }} />
22
+ <Progress id="progress-half" progress={{ value: 50, max: 100 }} />
23
+ <Progress id="progress-three-quarters" progress={{ value: 75, max: 100 }} />
24
+ </>
25
+ ),
26
+ ...withRTLDiff(),
27
+ };
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import ProgressBar from '..';
5
+
6
+ export default {
7
+ component: ProgressBar,
8
+ title: 'Content/ProgressBar/Tests',
9
+ tags: ['!autodocs', '!manifest'],
10
+ } satisfies Meta<typeof ProgressBar>;
11
+
12
+ type Story = StoryObj<typeof ProgressBar>;
13
+
14
+ export const RTLDiff: Story = {
15
+ render: () => (
16
+ <>
17
+ <ProgressBar
18
+ id="progress-bar-with-description"
19
+ title="Send 5,550 GBP"
20
+ description="You have 3 days to reach your goal."
21
+ progress={{ value: 50, max: 100 }}
22
+ textEnd="200 GBP to go"
23
+ />
24
+ <ProgressBar
25
+ id="progress-bar-without-description"
26
+ title="Total limit"
27
+ progress={{ value: 800, max: 1000 }}
28
+ textEnd="200 GBP remaining"
29
+ />
30
+ </>
31
+ ),
32
+ ...withRTLDiff(),
33
+ };
@@ -0,0 +1,42 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
3
+ import PromoCard from '..';
4
+
5
+ export default {
6
+ component: PromoCard,
7
+ title: 'Layouts/PromoCard/Tests',
8
+ tags: ['!autodocs', '!manifest'],
9
+ } satisfies Meta<typeof PromoCard>;
10
+
11
+ type Story = StoryObj<typeof PromoCard>;
12
+
13
+ export const RTLDiff: Story = {
14
+ render: () => (
15
+ <>
16
+ <PromoCard
17
+ title="Link with arrow"
18
+ description="Indicator arrow icon flips in RTL."
19
+ href="#"
20
+ indicatorLabel="Free"
21
+ imageSource="https://wise.com/web-art/assets/illustrations/digital-card-2-medium@2x.webp"
22
+ />
23
+ <PromoCard
24
+ title="Checkbox checked"
25
+ description="Check icon positioned at the end."
26
+ type="checkbox"
27
+ defaultChecked
28
+ indicatorLabel="Selected"
29
+ imageSource="https://wise.com/web-art/assets/illustrations/digital-card-2-medium@2x.webp"
30
+ />
31
+ <PromoCard
32
+ title="Download indicator"
33
+ description="Download icon in the indicator area."
34
+ href="#"
35
+ download="file.pdf"
36
+ indicatorLabel="Download"
37
+ imageSource="https://wise.com/web-art/assets/illustrations/digital-card-2-medium@2x.webp"
38
+ />
39
+ </>
40
+ ),
41
+ ...withRTLDiff(),
42
+ };
@@ -0,0 +1,51 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import PromoCard from '../PromoCard';
5
+ import PromoCardGroup from '../CardGroup/PromoCardGroup';
6
+
7
+ export default {
8
+ component: PromoCardGroup,
9
+ title: 'Layouts/PromoCardGroup/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof PromoCardGroup>;
12
+
13
+ type Story = StoryObj<typeof PromoCardGroup>;
14
+
15
+ export const RTLDiff: Story = {
16
+ render: () => (
17
+ <PromoCardGroup>
18
+ <PromoCard
19
+ title="Digital"
20
+ description="A card that lives online and works anywhere."
21
+ type="radio"
22
+ value="digital"
23
+ id="digital"
24
+ indicatorLabel="Free"
25
+ imageAlt=""
26
+ imageSource="https://wise.com/web-art/assets/illustrations/digital-card-2-medium@2x.webp"
27
+ />
28
+ <PromoCard
29
+ title="Standard"
30
+ description="Spend and withdraw money around the world."
31
+ type="radio"
32
+ value="standard"
33
+ id="standard"
34
+ indicatorLabel="7 GBP"
35
+ imageAlt=""
36
+ imageSource="https://wise.com/web-art/assets/illustrations/personal-card-medium@2x.webp"
37
+ />
38
+ <PromoCard
39
+ title="Eco"
40
+ description="A debit card made to biodegrade."
41
+ type="radio"
42
+ value="eco"
43
+ id="eco"
44
+ indicatorLabel="9 GBP"
45
+ imageAlt=""
46
+ imageSource="https://wise.com/web-art/assets/illustrations/eco-card-medium@2x.webp"
47
+ />
48
+ </PromoCardGroup>
49
+ ),
50
+ ...withRTLDiff(),
51
+ };
@@ -1,11 +1,12 @@
1
1
  import { ReactElement } from 'react';
2
- import { Freeze, People, Suitcase } from '@transferwise/icons';
2
+ import { Bank, Freeze, People, Suitcase } from '@transferwise/icons';
3
3
  import { action } from 'storybook/actions';
4
4
  import { fn } from 'storybook/test';
5
5
  import { ActionPrompt } from '../ActionPrompt';
6
6
  import { Body, Title } from '../../..';
7
7
  import { StoryObj } from '@storybook/react-webpack5';
8
8
  import { allModes } from '../../../../.storybook/modes';
9
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
9
10
  import { withVariantConfig } from '../../../../.storybook/helpers';
10
11
  import { lorem10 } from '../../../test-utils';
11
12
 
@@ -272,3 +273,43 @@ export const Responsiveness: Story = {
272
273
  },
273
274
  },
274
275
  };
276
+
277
+ export const RTLDiff: Story = {
278
+ render: () => (
279
+ <>
280
+ <ActionPrompt
281
+ title="Default status icon"
282
+ description="No media provided, uses default sentiment icon."
283
+ action={{ label: 'Continue' }}
284
+ />
285
+ <ActionPrompt
286
+ title="Custom image"
287
+ description="Media with a custom image source."
288
+ media={{ imgSrc: '../../wise-card.svg' }}
289
+ action={{ label: 'View card' }}
290
+ />
291
+ <ActionPrompt
292
+ title="Avatar with icon"
293
+ description="Media with an avatar containing a custom icon."
294
+ media={{ avatar: { asset: <Bank /> } }}
295
+ action={{ label: 'Connect bank' }}
296
+ />
297
+ <ActionPrompt
298
+ title="Primary and secondary actions"
299
+ description="Both action buttons present."
300
+ media={{ avatar: { asset: <Bank /> } }}
301
+ action={{ label: 'Confirm' }}
302
+ actionSecondary={{ label: 'Cancel' }}
303
+ />
304
+ <ActionPrompt
305
+ title="Dismissible with two actions"
306
+ description="Close button and both action buttons."
307
+ media={{ avatar: { asset: <Bank /> } }}
308
+ action={{ label: 'Confirm' }}
309
+ actionSecondary={{ label: 'Cancel' }}
310
+ onDismiss={() => {}}
311
+ />
312
+ </>
313
+ ),
314
+ ...withRTLDiff(),
315
+ };
@@ -3,6 +3,7 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
3
3
  import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
4
4
  import { Bank } from '@transferwise/icons';
5
5
  import Button from '../../../Button';
6
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
6
7
  import { withVariantConfig } from '../../../../.storybook/helpers';
7
8
  import { CriticalBanner } from '../CriticalBanner';
8
9
 
@@ -325,37 +326,6 @@ export const LiveRegionAnnouncements: Story = {
325
326
  },
326
327
  };
327
328
 
328
- /** Right-to-left layout regression test. */
329
- export const RTL: Story = {
330
- render: function Render() {
331
- const [expanded, setExpanded] = useState(true);
332
- const [collapsed, setCollapsed] = useState(false);
333
-
334
- return (
335
- <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', width: '100%' }}>
336
- <CriticalBanner
337
- sentiment="negative"
338
- title="Your account requires verification"
339
- description="Please verify your identity to continue using all features."
340
- action={{ label: 'Verify now', onClick: fn() }}
341
- actionSecondary={{ label: 'Learn more', onClick: fn() }}
342
- expanded={expanded}
343
- onToggle={() => setExpanded(!expanded)}
344
- />
345
- <CriticalBanner
346
- sentiment="warning"
347
- title="Collapsed state"
348
- description="This banner is collapsed."
349
- action={{ label: 'Take action', onClick: fn() }}
350
- expanded={collapsed}
351
- onToggle={() => setCollapsed(!collapsed)}
352
- />
353
- </div>
354
- );
355
- },
356
- ...withVariantConfig(['rtl']),
357
- };
358
-
359
329
  /** 400% zoom regression test with all variants. */
360
330
  export const Zoom400: Story = {
361
331
  render: () => <AllVariants gap="2rem" />,
@@ -489,3 +459,36 @@ export const UncontrolledStateInteraction: Story = {
489
459
  },
490
460
  },
491
461
  };
462
+
463
+ export const RTLDiff: Story = {
464
+ render: () => (
465
+ <>
466
+ <CriticalBanner title="Title only" description="Description without actions or media." />
467
+ <CriticalBanner
468
+ title="With primary action"
469
+ description="Banner with a single action button."
470
+ action={{ label: 'Verify now' }}
471
+ />
472
+ <CriticalBanner
473
+ title="With both actions"
474
+ description="Banner with primary and secondary actions."
475
+ action={{ label: 'Verify now' }}
476
+ actionSecondary={{ label: 'Learn more' }}
477
+ />
478
+ <CriticalBanner
479
+ title="With media image"
480
+ description="Banner with a custom image."
481
+ media={{ imgSrc: '../../wise-card.svg', 'aria-label': 'Wise card' }}
482
+ action={{ label: 'Take action' }}
483
+ />
484
+ <CriticalBanner
485
+ title="With avatar media"
486
+ description="Banner with an avatar icon."
487
+ media={{ avatar: { asset: <Bank /> } }}
488
+ action={{ label: 'Connect bank' }}
489
+ actionSecondary={{ label: 'Learn more' }}
490
+ />
491
+ </>
492
+ ),
493
+ ...withRTLDiff(),
494
+ };
@@ -5,6 +5,7 @@ import { action } from 'storybook/actions';
5
5
  import { Star } from '@transferwise/icons';
6
6
  import { InfoPrompt, type InfoPromptProps } from '../InfoPrompt';
7
7
  import { allModes } from '../../../../.storybook/modes';
8
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
8
9
  import { withVariantConfig } from '../../../../.storybook/helpers';
9
10
 
10
11
  const withComponentGrid =
@@ -553,3 +554,27 @@ export const LiveRegionDismiss: Story = {
553
554
  );
554
555
  },
555
556
  };
557
+
558
+ export const RTLDiff: Story = {
559
+ render: () => (
560
+ <>
561
+ <InfoPrompt description="Basic description only." />
562
+ <InfoPrompt title="With Title" description="Description with a title above it." />
563
+ <InfoPrompt description="Dismissible prompt." onDismiss={() => {}} />
564
+ <InfoPrompt
565
+ title="With Action"
566
+ description="Description with an action link below."
567
+ action={{ label: 'Learn more', href: '#' }}
568
+ />
569
+ <InfoPrompt description="Custom media icon." media={{ asset: <Star title="Starred" /> }} />
570
+ <InfoPrompt
571
+ title="All Options"
572
+ description="Title, action, dismiss, and custom media combined."
573
+ media={{ asset: <Star title="Starred" /> }}
574
+ action={{ label: 'View details', href: '#' }}
575
+ onDismiss={() => {}}
576
+ />
577
+ </>
578
+ ),
579
+ ...withRTLDiff(),
580
+ };
@@ -2,6 +2,7 @@ import { StoryObj } from '@storybook/react-webpack5';
2
2
  import { Suitcase } from '@transferwise/icons';
3
3
  import { InlinePrompt } from '../InlinePrompt';
4
4
  import { withVariantConfig } from '../../../../.storybook/helpers';
5
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
5
6
 
6
7
  export default {
7
8
  title: 'Prompts/InlinePrompt/Tests',
@@ -19,3 +20,29 @@ export const TinyScreen: Story = {
19
20
  ),
20
21
  ...withVariantConfig(['400%']),
21
22
  };
23
+
24
+ export const RTLDiff: Story = {
25
+ render: () => (
26
+ <>
27
+ {/* default icon at inline-start, auto width */}
28
+ <InlinePrompt sentiment="positive">Short content with default icon.</InlinePrompt>
29
+
30
+ {/* custom media icon, auto width */}
31
+ <InlinePrompt sentiment="positive" media={<Suitcase />}>
32
+ Custom icon with auto width.
33
+ </InlinePrompt>
34
+
35
+ {/* full width — icon position flips */}
36
+ <InlinePrompt sentiment="positive" media={<Suitcase />} width="full">
37
+ Custom icon with full width.
38
+ </InlinePrompt>
39
+
40
+ {/* multi-line content — verifies wrapping alignment */}
41
+ <InlinePrompt sentiment="warning" width="full">
42
+ This prompt has longer content that may wrap to multiple lines to verify that the icon
43
+ alignment remains correct in RTL layout.
44
+ </InlinePrompt>
45
+ </>
46
+ ),
47
+ ...withRTLDiff(),
48
+ };
@@ -0,0 +1,61 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { Flag } from '@wise/art';
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import AvatarView from '../../AvatarView';
5
+ import Radio from '../Radio';
6
+
7
+ export default {
8
+ component: Radio,
9
+ title: 'Forms/Radio/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof Radio>;
12
+
13
+ type Story = StoryObj<typeof Radio>;
14
+
15
+ export const RTLDiff: Story = {
16
+ render: () => (
17
+ <>
18
+ <Radio
19
+ label="Standard option"
20
+ name="radio-rtl"
21
+ id="radio-rtl-basic"
22
+ value="basic"
23
+ onChange={() => {}}
24
+ />
25
+ <Radio
26
+ label="Option with secondary text"
27
+ secondary="Secondary description"
28
+ name="radio-rtl"
29
+ id="radio-rtl-secondary"
30
+ value="secondary"
31
+ onChange={() => {}}
32
+ />
33
+ <Radio
34
+ label="Option with avatar"
35
+ name="radio-rtl"
36
+ id="radio-rtl-avatar"
37
+ value="avatar"
38
+ avatar={
39
+ <AvatarView size={40}>
40
+ <Flag code="IM" />
41
+ </AvatarView>
42
+ }
43
+ onChange={() => {}}
44
+ />
45
+ <Radio
46
+ label="Option with secondary text and avatar"
47
+ secondary="Secondary description"
48
+ name="radio-rtl"
49
+ id="radio-rtl-secondary-avatar"
50
+ value="secondary-avatar"
51
+ avatar={
52
+ <AvatarView size={40}>
53
+ <Flag code="IM" />
54
+ </AvatarView>
55
+ }
56
+ onChange={() => {}}
57
+ />
58
+ </>
59
+ ),
60
+ ...withRTLDiff(),
61
+ };