@transferwise/components 46.165.0 → 46.165.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 (86) hide show
  1. package/build/Snackbar/Snackbar.js +98 -101
  2. package/build/Snackbar/Snackbar.js.map +1 -1
  3. package/build/Snackbar/Snackbar.mjs +99 -102
  4. package/build/Snackbar/Snackbar.mjs.map +1 -1
  5. package/build/types/Body/Body.d.ts +2 -2
  6. package/build/types/Carousel/_stories/constants.d.ts +25 -0
  7. package/build/types/Carousel/_stories/constants.d.ts.map +1 -1
  8. package/build/types/IconButton/IconButton.d.ts +1 -1
  9. package/build/types/ListItem/_stories/variants/helpers.d.ts +38 -1
  10. package/build/types/ListItem/_stories/variants/helpers.d.ts.map +1 -1
  11. package/build/types/MoneyInput/MoneyInput.d.ts +1 -1
  12. package/build/types/MoneyInput/MoneyInput.d.ts.map +1 -1
  13. package/build/types/Snackbar/Snackbar.d.ts +1 -15
  14. package/build/types/Snackbar/Snackbar.d.ts.map +1 -1
  15. package/build/types/Title/Title.d.ts +2 -2
  16. package/build/types/Upload/Steps/UploadImageStep/UploadImageStep.d.ts +1 -1
  17. package/build/types/UploadInput/UploadItem/UploadItemLink.d.ts +1 -1
  18. package/package.json +1 -1
  19. package/src/Accordion/_stories/Accordion.test.story.tsx +74 -48
  20. package/src/AvatarLayout/_stories/AvatarLayout.test.story.tsx +46 -30
  21. package/src/Button/LegacyButton/_stories/LegacyButton.test.story.tsx +29 -19
  22. package/src/Button/_stories/Button.test.story.tsx +96 -62
  23. package/src/Calendar/_stories/Calendar.test.story.tsx +34 -21
  24. package/src/Carousel/_stories/Carousel.test.story.tsx +18 -8
  25. package/src/Carousel/_stories/constants.tsx +29 -4
  26. package/src/Checkbox/_stories/Checkbox.test.story.tsx +22 -13
  27. package/src/CheckboxButton/_stories/CheckboxButton.test.story.tsx +23 -14
  28. package/src/Chips/_stories/Chips.test.story.tsx +51 -36
  29. package/src/DateInput/_stories/DateInput.rtl.test.story.tsx +62 -12
  30. package/src/DateLookup/_stories/DateLookup.rtl.test.story.tsx +2 -2
  31. package/src/Decision/_stories/Decision.test.story.tsx +74 -58
  32. package/src/DefinitionList/_stories/DefinitionList.test.story.tsx +58 -42
  33. package/src/Drawer/_stories/Drawer.rtl.test.story.tsx +65 -38
  34. package/src/ExpressiveMoneyInput/_stories/ExpressiveMoneyInput.rtl.test.story.tsx +107 -74
  35. package/src/Field/_stories/Field.test.story.tsx +18 -18
  36. package/src/FlowNavigation/_stories/FlowNavigation.rtl.test.story.tsx +81 -51
  37. package/src/Header/_stories/Header.test.story.tsx +30 -18
  38. package/src/Info/_stories/Info.rtl.test.story.tsx +124 -50
  39. package/src/InputWithDisplayFormat/_stories/InputWithDisplayFormat.test.story.tsx +4 -4
  40. package/src/Inputs/InputGroup/_stories/InputGroup.test.story.tsx +9 -8
  41. package/src/Inputs/SearchInput/_stories/SearchInput.test.story.tsx +5 -3
  42. package/src/Inputs/SelectInput/_stories/SelectInput.rtl.test.story.tsx +108 -79
  43. package/src/Inputs/TextArea/_stories/TextArea.test.story.tsx +10 -10
  44. package/src/InstructionsList/_stories/InstructionsList.test.story.tsx +43 -16
  45. package/src/Label/_stories/Label.test.story.tsx +7 -7
  46. package/src/Link/_stories/Link.test.story.tsx +27 -13
  47. package/src/ListItem/_stories/ListItem.rtl.test.story.tsx +126 -6
  48. package/src/ListItem/_stories/variants/helpers.tsx +174 -126
  49. package/src/Loader/_stories/Loader.test.story.tsx +17 -10
  50. package/src/Modal/_stories/Modal.rtl.test.story.tsx +58 -39
  51. package/src/MoneyInput/_stories/MoneyInput.rtl.test.story.tsx +21 -3
  52. package/src/Nudge/_stories/Nudge.test.story.tsx +70 -21
  53. package/src/PhoneNumberInput/_stories/PhoneNumberInput.rtl.test.story.tsx +1 -1
  54. package/src/Popover/_stories/Popover.rtl.test.story.tsx +92 -49
  55. package/src/ProgressBar/_stories/ProgressBar.test.story.tsx +6 -6
  56. package/src/PromoCard/_stories/PromoCard.test.story.tsx +53 -29
  57. package/src/PromoCard/_stories/PromoCardGroup.test.story.tsx +60 -36
  58. package/src/Prompt/ActionPrompt/_stories/ActionPrompt.test.story.tsx +74 -38
  59. package/src/Prompt/CriticalBanner/_stories/CriticalBanner.test.story.tsx +68 -31
  60. package/src/Prompt/InfoPrompt/_stories/InfoPrompt.test.story.tsx +52 -22
  61. package/src/Prompt/InlinePrompt/_stories/InlinePrompt.test.story.tsx +36 -21
  62. package/src/Radio/_stories/Radio.test.story.tsx +60 -46
  63. package/src/RadioGroup/_stories/RadioGroup.test.story.tsx +70 -51
  64. package/src/Section/_stories/Section.test.story.tsx +30 -14
  65. package/src/SegmentedControl/_stories/SegmentedControl.test.story.tsx +38 -15
  66. package/src/SlidingPanel/_stories/SlidingPanel.rtl.test.story.tsx +58 -34
  67. package/src/Snackbar/Snackbar.test.tsx +16 -0
  68. package/src/Snackbar/Snackbar.tsx +91 -88
  69. package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +24 -12
  70. package/src/Stepper/_stories/Stepper.test.story.tsx +27 -9
  71. package/src/Switch/_stories/Switch.test.story.tsx +20 -12
  72. package/src/Table/_stories/Table.test.story.tsx +107 -86
  73. package/src/Tabs/_stories/Tabs.test.story.tsx +92 -52
  74. package/src/Tag/_stories/Tag.test.story.tsx +27 -16
  75. package/src/TextareaWithDisplayFormat/_stories/TextareaWithDisplayFormat.test.story.tsx +4 -4
  76. package/src/Tooltip/_stories/Tooltip.rtl.test.story.tsx +68 -25
  77. package/src/Typeahead/_stories/Typeahead.rtl.test.story.tsx +4 -4
  78. package/src/Upload/_stories/Upload.rtl.test.story.tsx +49 -26
  79. package/src/UploadInput/_stories/UploadInput.test.story.tsx +63 -41
  80. package/src/_deprecated/Alert/_stories/Alert.test.story.tsx +45 -24
  81. package/src/_deprecated/Card/_stories/Card.test.story.tsx +47 -23
  82. package/src/_deprecated/CriticalBanner/_stories/CriticalCommsBanner.test.story.tsx +21 -15
  83. package/src/_deprecated/InlineAlert/_stories/InlineAlert.test.story.tsx +23 -12
  84. package/src/_deprecated/Select/_stories/Select.rtl.test.story.tsx +78 -42
  85. package/src/common/BottomSheet/_stories/BottomSheet.test.story.tsx +38 -20
  86. package/src/common/Panel/_stories/Panel.rtl.test.story.tsx +135 -51
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { expect } from 'storybook/test';
3
3
 
4
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
5
  import { Layout } from '../../common';
6
6
 
7
7
  import DefinitionList, { type DefinitionListDefinition, type DefinitionListLayout } from '..';
@@ -168,28 +168,6 @@ export const HORIZONTAL_RIGHT_ALIGNED: Story = {
168
168
  play: verifySharedColumnBoundary,
169
169
  };
170
170
 
171
- const rtlDefinitions: DefinitionListDefinition[] = [
172
- { key: 'name', title: 'Full name', value: 'Alice Smith' },
173
- { key: 'amount', title: 'Amount sent', value: '1,234.56 GBP' },
174
- { key: 'status', title: 'Transfer status', value: 'Completed successfully' },
175
- ];
176
-
177
- const rtlDefinitionsWithAction: DefinitionListDefinition[] = [
178
- { key: 'name', title: 'Full name', value: 'Alice Smith' },
179
- {
180
- key: 'amount',
181
- title: 'Amount sent',
182
- value: '1,234.56 GBP',
183
- action: { label: 'Edit' },
184
- },
185
- {
186
- key: 'status',
187
- title: 'Transfer status',
188
- value: 'Completed successfully',
189
- action: { label: 'View details' },
190
- },
191
- ];
192
-
193
171
  const layouts: DefinitionListLayout[] = [
194
172
  'VERTICAL_TWO_COLUMN',
195
173
  'VERTICAL_ONE_COLUMN',
@@ -199,23 +177,61 @@ const layouts: DefinitionListLayout[] = [
199
177
  ];
200
178
 
201
179
  export const RTLDiff: Story = {
202
- render: () => (
203
- <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--size-48)' }}>
204
- {layouts.map((layout) => (
205
- <section key={layout}>
206
- <h3 style={{ fontSize: 14, margin: '0 0 var(--size-8)' }}>{layout}</h3>
207
- <DefinitionList layout={layout} definitions={rtlDefinitions} />
208
- </section>
209
- ))}
210
- {layouts.map((layout) => (
211
- <section key={`${layout}-action`}>
212
- <h3 style={{ fontSize: 14, margin: '0 0 var(--size-8)' }}>
213
- {layout} with action buttons
214
- </h3>
215
- <DefinitionList layout={layout} definitions={rtlDefinitionsWithAction} />
216
- </section>
217
- ))}
218
- </div>
219
- ),
220
- ...withRTLDiff(),
180
+ render: () => {
181
+ const i18n = useRtlDiffI18n();
182
+
183
+ const rtlDefinitions: DefinitionListDefinition[] = [
184
+ { key: 'name', title: i18n.fullName, value: i18n.customerName },
185
+ { key: 'amount', title: i18n.amountSent, value: i18n.amountValue },
186
+ { key: 'status', title: i18n.transferStatus, value: i18n.statusValue },
187
+ ];
188
+
189
+ const rtlDefinitionsWithAction: DefinitionListDefinition[] = [
190
+ { key: 'name', title: i18n.fullName, value: i18n.customerName },
191
+ {
192
+ key: 'amount',
193
+ title: i18n.amountSent,
194
+ value: i18n.amountValue,
195
+ action: { label: i18n.editAction },
196
+ },
197
+ {
198
+ key: 'status',
199
+ title: i18n.transferStatus,
200
+ value: i18n.statusValue,
201
+ action: { label: i18n.viewDetailsAction },
202
+ },
203
+ ];
204
+
205
+ return (
206
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--size-48)' }}>
207
+ {layouts.map((layout) => (
208
+ <section key={layout}>
209
+ <h3 style={{ fontSize: 14, margin: '0 0 var(--size-8)' }}>{layout}</h3>
210
+ <DefinitionList layout={layout} definitions={rtlDefinitions} />
211
+ </section>
212
+ ))}
213
+ {layouts.map((layout) => (
214
+ <section key={`${layout}-action`}>
215
+ <h3 style={{ fontSize: 14, margin: '0 0 var(--size-8)' }}>
216
+ {layout} {i18n.withActionButtons}
217
+ </h3>
218
+ <DefinitionList layout={layout} definitions={rtlDefinitionsWithAction} />
219
+ </section>
220
+ ))}
221
+ </div>
222
+ );
223
+ },
224
+ ...withRTLDiff({
225
+ i18n: {
226
+ fullName: { en: 'Full name', ar: 'الاسم الكامل' },
227
+ customerName: { en: 'Alice Smith', ar: 'أليس سميث' },
228
+ amountSent: { en: 'Amount sent', ar: 'المبلغ المُرسل' },
229
+ amountValue: { en: '1,234.56 GBP', ar: '1,234.56 جنيه إسترليني' },
230
+ transferStatus: { en: 'Transfer status', ar: 'حالة التحويل' },
231
+ statusValue: { en: 'Completed successfully', ar: 'اكتمل بنجاح' },
232
+ editAction: { en: 'Edit', ar: 'تعديل' },
233
+ viewDetailsAction: { en: 'View details', ar: 'عرض التفاصيل' },
234
+ withActionButtons: { en: 'with action buttons', ar: 'مع أزرار الإجراءات' },
235
+ },
236
+ }),
221
237
  };
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
 
3
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
3
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
4
  import Drawer from '..';
5
5
 
6
6
  export default {
@@ -11,48 +11,75 @@ export default {
11
11
 
12
12
  type Story = StoryObj<typeof Drawer>;
13
13
 
14
- const iframeDiff = withRTLDiff({ renderAs: 'iframe' });
15
-
16
14
  export const PositionRight: Story = {
17
- render: () => (
18
- <Drawer
19
- open
20
- position="right"
21
- headerTitle="Drawer title"
22
- footerContent={<button type="button">Done</button>}
23
- onClose={() => {}}
24
- >
25
- <p>Drawer body content.</p>
26
- </Drawer>
27
- ),
28
- ...iframeDiff,
15
+ render: () => {
16
+ const i18n = useRtlDiffI18n();
17
+ return (
18
+ <Drawer
19
+ open
20
+ position="right"
21
+ headerTitle={i18n.title}
22
+ footerContent={<button type="button">{i18n.done}</button>}
23
+ onClose={() => {}}
24
+ >
25
+ <p>{i18n.body}</p>
26
+ </Drawer>
27
+ );
28
+ },
29
+ ...withRTLDiff({
30
+ renderAs: 'iframe',
31
+ i18n: {
32
+ title: { en: 'Drawer title', ar: 'عنوان اللوحة' },
33
+ done: { en: 'Done', ar: 'تم' },
34
+ body: { en: 'Drawer body content.', ar: 'محتوى اللوحة الجانبية.' },
35
+ },
36
+ }),
29
37
  };
30
38
 
31
39
  export const PositionLeft: Story = {
32
- render: () => (
33
- <Drawer
34
- open
35
- position="left"
36
- headerTitle="Left drawer title"
37
- footerContent={<button type="button">Done</button>}
38
- onClose={() => {}}
39
- >
40
- <p>Left drawer body content.</p>
41
- </Drawer>
42
- ),
43
- ...iframeDiff,
40
+ render: () => {
41
+ const i18n = useRtlDiffI18n();
42
+ return (
43
+ <Drawer
44
+ open
45
+ position="left"
46
+ headerTitle={i18n.title}
47
+ footerContent={<button type="button">{i18n.done}</button>}
48
+ onClose={() => {}}
49
+ >
50
+ <p>{i18n.body}</p>
51
+ </Drawer>
52
+ );
53
+ },
54
+ ...withRTLDiff({
55
+ renderAs: 'iframe',
56
+ i18n: {
57
+ title: { en: 'Left drawer title', ar: 'عنوان اللوحة اليسرى' },
58
+ done: { en: 'Done', ar: 'تم' },
59
+ body: { en: 'Left drawer body content.', ar: 'محتوى اللوحة اليسرى.' },
60
+ },
61
+ }),
44
62
  };
45
63
 
46
64
  export const WithoutTitle: Story = {
47
- render: () => (
48
- <Drawer
49
- open
50
- position="right"
51
- footerContent={<button type="button">Done</button>}
52
- onClose={() => {}}
53
- >
54
- <p>No title drawer content.</p>
55
- </Drawer>
56
- ),
57
- ...iframeDiff,
65
+ render: () => {
66
+ const i18n = useRtlDiffI18n();
67
+ return (
68
+ <Drawer
69
+ open
70
+ position="right"
71
+ footerContent={<button type="button">{i18n.done}</button>}
72
+ onClose={() => {}}
73
+ >
74
+ <p>{i18n.body}</p>
75
+ </Drawer>
76
+ );
77
+ },
78
+ ...withRTLDiff({
79
+ renderAs: 'iframe',
80
+ i18n: {
81
+ done: { en: 'Done', ar: 'تم' },
82
+ body: { en: 'No title drawer content.', ar: 'محتوى لوحة بدون عنوان.' },
83
+ },
84
+ }),
58
85
  };
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { fn, userEvent, within } from 'storybook/test';
3
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
3
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
4
  import ExpressiveMoneyInput from '..';
5
5
  import { Rewards } from '@transferwise/icons';
6
6
 
@@ -24,95 +24,128 @@ const currencySelectorOptions = [
24
24
  ];
25
25
 
26
26
  export const TriggerVariants: Story = {
27
- render: () => (
28
- <>
29
- {/* Currency selector on leading side — flips in RTL */}
30
- <ExpressiveMoneyInput
31
- label="You send"
32
- currency="GBP"
33
- amount={1234.56}
34
- currencySelector={{
35
- options: currencySelectorOptions,
36
- onChange: fn(),
37
- onSearchChange: fn(),
38
- onOpen: fn(),
39
- }}
40
- onAmountChange={fn()}
41
- />
27
+ render: () => {
28
+ const i18n = useRtlDiffI18n();
29
+ return (
30
+ <>
31
+ {/* Currency selector on leading side — flips in RTL */}
32
+ <ExpressiveMoneyInput
33
+ label={i18n.youSend}
34
+ currency="GBP"
35
+ amount={1234.56}
36
+ currencySelector={{
37
+ options: currencySelectorOptions,
38
+ onChange: fn(),
39
+ onSearchChange: fn(),
40
+ onOpen: fn(),
41
+ }}
42
+ onAmountChange={fn()}
43
+ />
42
44
 
43
- {/* Chevron on trailing side — flips in RTL */}
44
- <ExpressiveMoneyInput
45
- label="You send"
46
- currency="EUR"
47
- amount={0}
48
- showChevron
49
- currencySelector={{
50
- options: currencySelectorOptions,
51
- onChange: fn(),
52
- onSearchChange: fn(),
53
- onOpen: fn(),
54
- }}
55
- onAmountChange={fn()}
56
- />
45
+ {/* Chevron on trailing side — flips in RTL */}
46
+ <ExpressiveMoneyInput
47
+ label={i18n.youSend}
48
+ currency="EUR"
49
+ amount={0}
50
+ showChevron
51
+ currencySelector={{
52
+ options: currencySelectorOptions,
53
+ onChange: fn(),
54
+ onSearchChange: fn(),
55
+ onOpen: fn(),
56
+ }}
57
+ onAmountChange={fn()}
58
+ />
57
59
 
58
- {/* InlinePrompt with media icon — icon on leading end of prompt */}
59
- <ExpressiveMoneyInput
60
- label="You send"
61
- currency="USD"
62
- amount={500}
63
- currencySelector={{
64
- options: currencySelectorOptions,
65
- onChange: fn(),
66
- onSearchChange: fn(),
67
- onOpen: fn(),
68
- }}
69
- inlinePrompt={{
70
- message: 'Great rate available',
71
- sentiment: 'positive',
72
- media: <Rewards />,
73
- }}
74
- onAmountChange={fn()}
75
- />
60
+ {/* InlinePrompt with media icon — icon on leading end of prompt */}
61
+ <ExpressiveMoneyInput
62
+ label={i18n.youSend}
63
+ currency="USD"
64
+ amount={500}
65
+ currencySelector={{
66
+ options: currencySelectorOptions,
67
+ onChange: fn(),
68
+ onSearchChange: fn(),
69
+ onOpen: fn(),
70
+ }}
71
+ inlinePrompt={{
72
+ message: i18n.greatRate,
73
+ sentiment: 'positive',
74
+ media: <Rewards />,
75
+ }}
76
+ onAmountChange={fn()}
77
+ />
76
78
 
77
- {/* Secondary avatar addon in currency selector */}
79
+ {/* Secondary avatar addon in currency selector */}
80
+ <ExpressiveMoneyInput
81
+ label={i18n.youSend}
82
+ currency="GBP"
83
+ amount={750}
84
+ currencySelector={{
85
+ options: currencySelectorOptions,
86
+ addons: [{ profileName: i18n.profileName }],
87
+ onChange: fn(),
88
+ onSearchChange: fn(),
89
+ onOpen: fn(),
90
+ }}
91
+ onAmountChange={fn()}
92
+ />
93
+ </>
94
+ );
95
+ },
96
+ ...withRTLDiff({
97
+ renderAs: 'iframe',
98
+ width: 'stretch',
99
+ i18n: {
100
+ youSend: { en: 'You send', ar: 'أنت ترسل' },
101
+ greatRate: { en: 'Great rate available', ar: 'سعر تحويل رائع متاح' },
102
+ profileName: { en: 'Mikkael Jordan', ar: 'ميكائيل جوردان' },
103
+ },
104
+ }),
105
+ };
106
+
107
+ export const OpenDropdown: Story = {
108
+ render: () => {
109
+ const i18n = useRtlDiffI18n();
110
+ return (
78
111
  <ExpressiveMoneyInput
79
- label="You send"
112
+ label={i18n.youSend}
80
113
  currency="GBP"
81
- amount={750}
114
+ amount={1234.56}
82
115
  currencySelector={{
83
- options: currencySelectorOptions,
84
- addons: [{ profileName: 'Mikkael Jordan' }],
116
+ options: [
117
+ {
118
+ title: i18n.popularGroup,
119
+ currencies: [
120
+ { code: 'GBP', label: i18n.britishPound, keywords: ['british'] },
121
+ { code: 'EUR', label: i18n.euro, keywords: ['euro'] },
122
+ { code: 'USD', label: i18n.usDollar, keywords: ['dollar'] },
123
+ ],
124
+ },
125
+ ],
85
126
  onChange: fn(),
86
127
  onSearchChange: fn(),
87
128
  onOpen: fn(),
88
129
  }}
89
130
  onAmountChange={fn()}
90
131
  />
91
- </>
92
- ),
93
- ...withRTLDiff({ renderAs: 'iframe', width: 'stretch' }),
94
- };
95
-
96
- export const OpenDropdown: Story = {
97
- render: () => (
98
- <ExpressiveMoneyInput
99
- label="You send"
100
- currency="GBP"
101
- amount={1234.56}
102
- currencySelector={{
103
- options: currencySelectorOptions,
104
- onChange: fn(),
105
- onSearchChange: fn(),
106
- onOpen: fn(),
107
- }}
108
- onAmountChange={fn()}
109
- />
110
- ),
132
+ );
133
+ },
111
134
  play: async ({ canvasElement }) => {
112
135
  const canvas = within(canvasElement);
113
136
  const trigger = canvas.queryByRole('combobox');
114
137
  if (!trigger) return;
115
138
  await userEvent.click(trigger);
116
139
  },
117
- ...withRTLDiff({ renderAs: 'iframe', width: '80%' }),
140
+ ...withRTLDiff({
141
+ renderAs: 'iframe',
142
+ width: '80%',
143
+ i18n: {
144
+ youSend: { en: 'You send', ar: 'أنت ترسل' },
145
+ popularGroup: { en: 'Popular', ar: 'الأكثر شيوعًا' },
146
+ britishPound: { en: 'British Pound', ar: 'الجنيه الإسترليني' },
147
+ euro: { en: 'Euro', ar: 'اليورو' },
148
+ usDollar: { en: 'US Dollar', ar: 'الدولار الأمريكي' },
149
+ },
150
+ }),
118
151
  };
@@ -113,28 +113,28 @@ export const RTLDiff: Story = {
113
113
  ...withRTLDiff({
114
114
  width: 'stretch',
115
115
  i18n: {
116
- placeholder_en: { ltr: 'LTR placeholder...', rtl: 'LTR placeholder...' },
117
- placeholder_ar: { ltr: 'Localised placeholder...', rtl: 'نص بديل مترجم...' },
116
+ placeholder_en: { en: 'LTR placeholder...', ar: 'LTR placeholder...' },
117
+ placeholder_ar: { en: 'Localised placeholder...', ar: 'نص بديل مترجم...' },
118
118
  value_en: {
119
- ltr: 'ltr@value.com',
120
- rtl: 'ltr@value.com',
119
+ en: 'ltr@value.com',
120
+ ar: 'ltr@value.com',
121
121
  },
122
122
  value_ar: {
123
- ltr: 'localised value',
124
- rtl: 'قيمة مُكيَّفة محلياً',
123
+ en: 'localised value',
124
+ ar: 'قيمة مُكيَّفة محليًا',
125
125
  },
126
- requiredLabel: { ltr: 'Required field', rtl: 'حقل مطلوب' },
127
- optionalLabel: { ltr: 'Optional field', rtl: 'حقل اختياري' },
128
- descriptionLabel: { ltr: 'Field with description and message', rtl: 'حقل مع وصف ورسالة' },
129
- description: { ltr: 'A short description of the field', rtl: 'وصف قصير للحقل' },
130
- validationMessage: { ltr: 'This is a validation message', rtl: 'هذه رسالة تحقق' },
131
- helpfulMessage: { ltr: 'A helpful message', rtl: 'رسالة مفيدة' },
132
- loadingLabel: { ltr: 'Field with loading message', rtl: 'حقل مع رسالة تحميل' },
133
- savingMessage: { ltr: 'Saving…', rtl: 'جارٍ الحفظ…' },
134
- textareaLabel: { ltr: 'Textarea with char counter', rtl: 'حقل نص مع عداد الأحرف' },
135
- maxChars: { ltr: 'Max 100 characters', rtl: 'الحد الأقصى 100 حرف' },
136
- inputValue: { ltr: 'Input value', rtl: 'قيمة الإدخال' },
137
- textareaValue: { ltr: 'Textarea value', rtl: 'قيمة حقل النص' },
126
+ requiredLabel: { en: 'Required field', ar: 'حقل مطلوب' },
127
+ optionalLabel: { en: 'Optional field', ar: 'حقل اختياري' },
128
+ descriptionLabel: { en: 'Field with description and message', ar: 'حقل مع وصف ورسالة' },
129
+ description: { en: 'A short description of the field', ar: 'وصف قصير للحقل' },
130
+ validationMessage: { en: 'This is a validation message', ar: 'هذه رسالة تحقق' },
131
+ helpfulMessage: { en: 'A helpful message', ar: 'رسالة مفيدة' },
132
+ loadingLabel: { en: 'Field with loading message', ar: 'حقل مع رسالة تحميل' },
133
+ savingMessage: { en: 'Saving…', ar: 'جارٍ الحفظ…' },
134
+ textareaLabel: { en: 'Textarea with char counter', ar: 'حقل نص مع عداد الأحرف' },
135
+ maxChars: { en: 'Max 100 characters', ar: 'الحد الأقصى 100 حرف' },
136
+ inputValue: { en: 'Input value', ar: 'قيمة الإدخال' },
137
+ textareaValue: { en: 'Textarea value', ar: 'قيمة حقل النص' },
138
138
  },
139
139
  }),
140
140
  };
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
 
3
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
3
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
4
  import AvatarView from '../../AvatarView';
5
5
  import { ProfileType } from '../../common';
6
6
  import Logo from '../../Logo';
@@ -9,13 +9,6 @@ import FlowNavigation from '../FlowNavigation';
9
9
 
10
10
  const noop = () => {};
11
11
 
12
- const steps = [
13
- { label: 'Amount', hoverLabel: '100 GBP', onClick: noop },
14
- { label: 'You', hoverLabel: 'Elena Durante', onClick: noop },
15
- { label: 'Review', onClick: noop },
16
- { label: 'Pay', onClick: noop },
17
- ];
18
-
19
12
  const meta: Meta<typeof FlowNavigation> = {
20
13
  component: FlowNavigation,
21
14
  title: 'Navigation/FlowNavigation/Tests/RTL Diff',
@@ -29,50 +22,87 @@ export default meta;
29
22
  type Story = StoryObj<typeof FlowNavigation>;
30
23
 
31
24
  export const Desktop: Story = {
32
- render: () => (
33
- <>
34
- <FlowNavigation
35
- activeStep={2}
36
- avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
37
- logo={<Logo />}
38
- steps={steps}
39
- onClose={noop}
40
- onGoBack={noop}
41
- />
42
- <FlowNavigation
43
- avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
44
- logo={<Logo />}
45
- onClose={noop}
46
- />
47
- <FlowNavigation
48
- done
49
- avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
50
- logo={<Logo />}
51
- steps={steps}
52
- onClose={noop}
53
- />
54
- </>
55
- ),
56
- ...withRTLDiff(),
25
+ render: () => {
26
+ const i18n = useRtlDiffI18n();
27
+ const steps = [
28
+ { label: i18n.amount, hoverLabel: i18n.amountValue, onClick: noop },
29
+ { label: i18n.you, hoverLabel: i18n.recipientName, onClick: noop },
30
+ { label: i18n.review, onClick: noop },
31
+ { label: i18n.pay, onClick: noop },
32
+ ];
33
+ return (
34
+ <>
35
+ <FlowNavigation
36
+ activeStep={2}
37
+ avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
38
+ logo={<Logo />}
39
+ steps={steps}
40
+ onClose={noop}
41
+ onGoBack={noop}
42
+ />
43
+ <FlowNavigation
44
+ avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
45
+ logo={<Logo />}
46
+ onClose={noop}
47
+ />
48
+ <FlowNavigation
49
+ done
50
+ avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
51
+ logo={<Logo />}
52
+ steps={steps}
53
+ onClose={noop}
54
+ />
55
+ </>
56
+ );
57
+ },
58
+ ...withRTLDiff({
59
+ i18n: {
60
+ amount: { en: 'Amount', ar: 'المبلغ' },
61
+ amountValue: { en: '100 GBP', ar: '100 جنيه إسترليني' },
62
+ you: { en: 'You', ar: 'بياناتك' },
63
+ recipientName: { en: 'Elena Durante', ar: 'إيلينا دورانتي' },
64
+ review: { en: 'Review', ar: 'المراجعة' },
65
+ pay: { en: 'Pay', ar: 'الدفع' },
66
+ },
67
+ }),
57
68
  };
58
69
 
59
70
  export const Mobile: Story = {
60
- render: () => (
61
- <>
62
- <FlowNavigation
63
- activeStep={2}
64
- avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
65
- logo={<Logo />}
66
- steps={steps}
67
- onClose={noop}
68
- onGoBack={noop}
69
- />
70
- <FlowNavigation
71
- avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
72
- logo={<Logo />}
73
- onClose={noop}
74
- />
75
- </>
76
- ),
77
- ...withRTLDiff({ viewport: 'largeMobile' }),
71
+ render: () => {
72
+ const i18n = useRtlDiffI18n();
73
+ const steps = [
74
+ { label: i18n.amount, hoverLabel: i18n.amountValue, onClick: noop },
75
+ { label: i18n.you, hoverLabel: i18n.recipientName, onClick: noop },
76
+ { label: i18n.review, onClick: noop },
77
+ { label: i18n.pay, onClick: noop },
78
+ ];
79
+ return (
80
+ <>
81
+ <FlowNavigation
82
+ activeStep={2}
83
+ avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
84
+ logo={<Logo />}
85
+ steps={steps}
86
+ onClose={noop}
87
+ onGoBack={noop}
88
+ />
89
+ <FlowNavigation
90
+ avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
91
+ logo={<Logo />}
92
+ onClose={noop}
93
+ />
94
+ </>
95
+ );
96
+ },
97
+ ...withRTLDiff({
98
+ viewport: 'largeMobile',
99
+ i18n: {
100
+ amount: { en: 'Amount', ar: 'المبلغ' },
101
+ amountValue: { en: '100 GBP', ar: '100 جنيه إسترليني' },
102
+ you: { en: 'You', ar: 'بياناتك' },
103
+ recipientName: { en: 'Elena Durante', ar: 'إيلينا دورانتي' },
104
+ review: { en: 'Review', ar: 'المراجعة' },
105
+ pay: { en: 'Pay', ar: 'الدفع' },
106
+ },
107
+ }),
78
108
  };