@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
@@ -3,7 +3,11 @@ import { expect, waitFor, within, userEvent } from 'storybook/test';
3
3
 
4
4
  import Calendar from '../Calendar';
5
5
  import type { DisabledRules } from '../Calendar.types';
6
- import { forEachColumn, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
6
+ import {
7
+ forEachColumn,
8
+ useRtlDiffI18n,
9
+ withRTLDiff,
10
+ } from '../../../.storybook/decorators/RtlDiffDecorator';
7
11
 
8
12
  export default {
9
13
  component: Calendar,
@@ -125,28 +129,30 @@ const maxDate = new Date(2024, 9, 31);
125
129
  const disabledRulesRtl = {
126
130
  weekdays: ['sat', 'sun'] as ('sat' | 'sun')[],
127
131
  dates: [new Date(2024, 5, 10)],
128
- reason: 'Weekends and specific dates are unavailable.',
129
132
  };
130
133
 
131
134
  export const RTLDiff: Story = {
132
- render: () => (
133
- <>
134
- <div data-testid="day-view">
135
- <Calendar
136
- value={selectedDate}
137
- min={minDate}
138
- max={maxDate}
139
- disabledRules={disabledRulesRtl}
140
- />
141
- </div>
142
- <div data-testid="month-view">
143
- <Calendar value={selectedDate} min={minDate} max={maxDate} />
144
- </div>
145
- <div data-testid="year-view">
146
- <Calendar value={selectedDate} min={minDate} max={maxDate} />
147
- </div>
148
- </>
149
- ),
135
+ render: () => {
136
+ const i18n = useRtlDiffI18n();
137
+ return (
138
+ <>
139
+ <div data-testid="day-view">
140
+ <Calendar
141
+ value={selectedDate}
142
+ min={minDate}
143
+ max={maxDate}
144
+ disabledRules={{ ...disabledRulesRtl, reason: i18n.disabledReason }}
145
+ />
146
+ </div>
147
+ <div data-testid="month-view">
148
+ <Calendar value={selectedDate} min={minDate} max={maxDate} />
149
+ </div>
150
+ <div data-testid="year-view">
151
+ <Calendar value={selectedDate} min={minDate} max={maxDate} />
152
+ </div>
153
+ </>
154
+ );
155
+ },
150
156
  play: async ({ canvasElement }) => {
151
157
  await forEachColumn(canvasElement, async (column) => {
152
158
  const monthContainer = column.querySelector('[data-testid="month-view"]')!;
@@ -159,5 +165,12 @@ export const RTLDiff: Story = {
159
165
  await userEvent.click(yearScope.getByRole('button', { name: /year view/iu }));
160
166
  });
161
167
  },
162
- ...withRTLDiff(),
168
+ ...withRTLDiff({
169
+ i18n: {
170
+ disabledReason: {
171
+ en: 'Weekends and specific dates are unavailable.',
172
+ ar: 'عطلات نهاية الأسبوع وتواريخ محددة غير متاحة.',
173
+ },
174
+ },
175
+ }),
163
176
  };
@@ -1,8 +1,8 @@
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 Carousel from '..';
5
- import { stubbedCarouselCards } from './constants';
5
+ import { carouselCardsI18n, getStubbedCarouselCards } from './constants';
6
6
 
7
7
  export default {
8
8
  component: Carousel,
@@ -12,12 +12,22 @@ export default {
12
12
 
13
13
  type Story = StoryObj<typeof Carousel>;
14
14
 
15
- const manyCards = [
16
- ...stubbedCarouselCards,
17
- ...stubbedCarouselCards.map((card) => ({ ...card, id: `${card.id}_2` })),
18
- ];
15
+ /** Doubled so the track overflows and both scroll buttons render. */
16
+ const getManyCards = (i18n: Record<string, string>) => {
17
+ const cards = getStubbedCarouselCards(i18n);
18
+ return [...cards, ...cards.map((card) => ({ ...card, id: `${card.id}_2` }))];
19
+ };
19
20
 
20
21
  export const RTLDiff: Story = {
21
- render: () => <Carousel cards={manyCards} header="Pretty nifty stuff" />,
22
- ...withRTLDiff({ width: 'stretch' }),
22
+ render: () => {
23
+ const i18n = useRtlDiffI18n();
24
+ return <Carousel cards={getManyCards(i18n)} header={i18n.header} />;
25
+ },
26
+ ...withRTLDiff({
27
+ width: 'stretch',
28
+ i18n: {
29
+ header: { en: 'Pretty nifty stuff', ar: 'أشياء رائعة حقًا' },
30
+ ...carouselCardsI18n,
31
+ },
32
+ }),
23
33
  };
@@ -2,7 +2,26 @@ import { Illustration } from '@wise/art';
2
2
  import Display from '../../Display';
3
3
  import type { CarouselCard } from '../Carousel';
4
4
 
5
- export const stubbedCarouselCards: CarouselCard[] = [
5
+ /**
6
+ * Every string the stubbed cards render, shaped as a `withRTLDiff({ i18n })` map so the RTL diff
7
+ * can spread it — that call site is what type-checks the shape against `I18nMap`. The type is not
8
+ * imported here: this file is part of the Rollup build, which cannot emit declarations that
9
+ * reference `.storybook/`. The promo card's `Wise` title is a brand name and stays in Latin script.
10
+ */
11
+ export const carouselCardsI18n = {
12
+ globeCardTitle: { en: 'Here there, everywhere', ar: 'هنا وهناك وفي كل مكان' },
13
+ promoDescription: {
14
+ en: 'The best way to move money internationally',
15
+ ar: 'أفضل طريقة لتحويل الأموال دوليًا',
16
+ },
17
+ quickPayCardTitle: { en: 'Get Quick Pay', ar: 'احصل على الدفع السريع' },
18
+ };
19
+
20
+ /**
21
+ * Takes copy already resolved for one language — exactly what `useRtlDiffI18n()` returns — so the
22
+ * same fixture serves the single-direction stories and the RTL diff.
23
+ */
24
+ export const getStubbedCarouselCards = (i18n: Record<string, string>): CarouselCard[] => [
6
25
  {
7
26
  id: 'YOUR_INVOICE',
8
27
  type: 'button',
@@ -15,7 +34,7 @@ export const stubbedCarouselCards: CarouselCard[] = [
15
34
  <Illustration disablePadding name="globe" size="small" alt="" />
16
35
  </div>
17
36
  <div style={{ position: 'absolute', zIndex: '2', bottom: '8px', left: '16px' }}>
18
- <Display type="display-small">Here there, everywhere</Display>
37
+ <Display type="display-small">{i18n.globeCardTitle}</Display>
19
38
  </div>
20
39
  </div>
21
40
  ),
@@ -28,7 +47,7 @@ export const stubbedCarouselCards: CarouselCard[] = [
28
47
  },
29
48
  href: 'http://wise.com',
30
49
  title: 'Wise',
31
- description: 'The best way to move money internationally',
50
+ description: i18n.promoDescription,
32
51
  },
33
52
  {
34
53
  id: 'SHOP_OR_STALL',
@@ -41,6 +60,12 @@ export const stubbedCarouselCards: CarouselCard[] = [
41
60
  'url(https://wise.com/public-resources/assets/team-page/tapestry/team_member_tapestry_01.jpg)',
42
61
  backgroundSize: 'cover',
43
62
  },
44
- content: <Display type="display-small">Get Quick Pay</Display>,
63
+ content: <Display type="display-small">{i18n.quickPayCardTitle}</Display>,
45
64
  },
46
65
  ];
66
+
67
+ const englishCopy = Object.fromEntries(
68
+ Object.entries(carouselCardsI18n).map(([key, entry]) => [key, entry.en]),
69
+ );
70
+
71
+ export const stubbedCarouselCards = getStubbedCarouselCards(englishCopy);
@@ -2,7 +2,7 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { fn } from 'storybook/test';
3
3
  import { lorem10 } from '../../test-utils';
4
4
  import Checkbox from '../Checkbox';
5
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
6
6
  import { withVariantConfig } from '../../../.storybook/helpers';
7
7
 
8
8
  const meta: Meta<typeof Checkbox> = {
@@ -39,16 +39,25 @@ export const MultipleMobile: Story = {
39
39
  * so both single-line and two-line layouts are verified here.
40
40
  */
41
41
  export const RTLDiff: Story = {
42
- render: () => (
43
- <>
44
- <Checkbox checked label="Label only" onChange={() => {}} />
45
- <Checkbox
46
- checked
47
- label="Label with secondary"
48
- secondary="Secondary description text"
49
- onChange={() => {}}
50
- />
51
- </>
52
- ),
53
- ...withRTLDiff(),
42
+ render: () => {
43
+ const i18n = useRtlDiffI18n();
44
+ return (
45
+ <>
46
+ <Checkbox checked label={i18n.labelOnly} onChange={() => {}} />
47
+ <Checkbox
48
+ checked
49
+ label={i18n.withSecondary}
50
+ secondary={i18n.secondaryDescription}
51
+ onChange={() => {}}
52
+ />
53
+ </>
54
+ );
55
+ },
56
+ ...withRTLDiff({
57
+ i18n: {
58
+ labelOnly: { en: 'Label only', ar: 'التسمية فقط' },
59
+ withSecondary: { en: 'Label with secondary', ar: 'تسمية مع وصف ثانوي' },
60
+ secondaryDescription: { en: 'Secondary description text', ar: 'نص الوصف الثانوي' },
61
+ },
62
+ }),
54
63
  };
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
3
3
  import { expect, userEvent, within } from 'storybook/test';
4
4
 
5
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
6
6
  import { withVariantConfig } from '../../../.storybook/helpers';
7
7
  import CheckboxButton from '../CheckboxButton';
8
8
 
@@ -200,17 +200,26 @@ export const Zoom400: Story = {
200
200
  };
201
201
 
202
202
  export const RTLDiff: Story = {
203
- render: () => (
204
- <>
205
- <CheckboxButton aria-label="Unchecked" checked={false} onChange={() => {}} />
206
- <CheckboxButton aria-label="Checked" checked onChange={() => {}} />
207
- <CheckboxButton
208
- aria-label="Indeterminate"
209
- checked={false}
210
- indeterminate
211
- onChange={() => {}}
212
- />
213
- </>
214
- ),
215
- ...withRTLDiff(),
203
+ render: () => {
204
+ const i18n = useRtlDiffI18n();
205
+ return (
206
+ <>
207
+ <CheckboxButton aria-label={i18n.unchecked} checked={false} onChange={() => {}} />
208
+ <CheckboxButton aria-label={i18n.checked} checked onChange={() => {}} />
209
+ <CheckboxButton
210
+ aria-label={i18n.indeterminate}
211
+ checked={false}
212
+ indeterminate
213
+ onChange={() => {}}
214
+ />
215
+ </>
216
+ );
217
+ },
218
+ ...withRTLDiff({
219
+ i18n: {
220
+ unchecked: { en: 'Unchecked', ar: 'غير محدد' },
221
+ checked: { en: 'Checked', ar: 'محدد' },
222
+ indeterminate: { en: 'Indeterminate', ar: 'محدد جزئيًا' },
223
+ },
224
+ }),
216
225
  };
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { userEvent } from 'storybook/test';
3
3
  import { useState } from 'react';
4
4
 
5
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
6
6
  import { withVariantConfig } from '../../../.storybook/helpers';
7
7
  import Chips, { type ChipValue } from '../Chips';
8
8
 
@@ -143,40 +143,55 @@ export const Zoom400: Story = {
143
143
  ...withVariantConfig(['400%']),
144
144
  };
145
145
 
146
- const categoryChips = [
147
- { value: 'all', label: 'All' },
148
- { value: 'accounting', label: 'Accounting' },
149
- { value: 'payroll', label: 'Payroll' },
150
- { value: 'payments', label: 'Payments' },
151
- ];
152
-
153
- const amountChips = [
154
- { value: 100, label: '100 GBP' },
155
- { value: 200, label: '200 GBP' },
156
- { value: 300, label: '300 GBP' },
157
- { value: 500, label: '500 GBP+' },
158
- ];
159
-
160
146
  export const RTLDiff: Story = {
161
- render: () => (
162
- <>
163
- {/* Choice mode: chip row order reverses in RTL */}
164
- <Chips
165
- chips={amountChips}
166
- selected={300}
167
- multiple={false}
168
- aria-label="Transfer amount"
169
- onChange={() => undefined}
170
- />
171
- {/* Filter mode: selected chips show close button on trailing end */}
172
- <Chips
173
- chips={categoryChips}
174
- selected={['accounting', 'payments']}
175
- multiple
176
- aria-label="Category filter"
177
- onChange={() => undefined}
178
- />
179
- </>
180
- ),
181
- ...withRTLDiff(),
147
+ render: () => {
148
+ const i18n = useRtlDiffI18n();
149
+ const categoryChips = [
150
+ { value: 'all', label: i18n.all },
151
+ { value: 'accounting', label: i18n.accounting },
152
+ { value: 'payroll', label: i18n.payroll },
153
+ { value: 'payments', label: i18n.payments },
154
+ ];
155
+ const amountChips = [
156
+ { value: 100, label: i18n.amount100 },
157
+ { value: 200, label: i18n.amount200 },
158
+ { value: 300, label: i18n.amount300 },
159
+ { value: 500, label: i18n.amount500Plus },
160
+ ];
161
+
162
+ return (
163
+ <>
164
+ {/* Choice mode: chip row order reverses in RTL */}
165
+ <Chips
166
+ chips={amountChips}
167
+ selected={300}
168
+ multiple={false}
169
+ aria-label={i18n.transferAmount}
170
+ onChange={() => undefined}
171
+ />
172
+ {/* Filter mode: selected chips show close button on trailing end */}
173
+ <Chips
174
+ chips={categoryChips}
175
+ selected={['accounting', 'payments']}
176
+ multiple
177
+ aria-label={i18n.categoryFilter}
178
+ onChange={() => undefined}
179
+ />
180
+ </>
181
+ );
182
+ },
183
+ ...withRTLDiff({
184
+ i18n: {
185
+ all: { en: 'All', ar: 'الكل' },
186
+ accounting: { en: 'Accounting', ar: 'المحاسبة' },
187
+ payroll: { en: 'Payroll', ar: 'الرواتب' },
188
+ payments: { en: 'Payments', ar: 'المدفوعات' },
189
+ amount100: { en: '100 GBP', ar: '100 جنيه إسترليني' },
190
+ amount200: { en: '200 GBP', ar: '200 جنيه إسترليني' },
191
+ amount300: { en: '300 GBP', ar: '300 جنيه إسترليني' },
192
+ amount500Plus: { en: '500 GBP+', ar: '+500 جنيه إسترليني' },
193
+ transferAmount: { en: 'Transfer amount', ar: 'مبلغ التحويل' },
194
+ categoryFilter: { en: 'Category filter', ar: 'تصفية الفئات' },
195
+ },
196
+ }),
182
197
  };
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { fn, userEvent, within } from 'storybook/test';
3
3
 
4
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
5
  import DateInput from '..';
6
6
 
7
7
  export default {
@@ -13,24 +13,74 @@ export default {
13
13
  type Story = StoryObj<typeof DateInput>;
14
14
 
15
15
  export const Sizes: Story = {
16
- render: () => (
17
- <>
18
- <DateInput size="sm" onChange={fn()} />
19
- <DateInput size="md" onChange={fn()} />
20
- <DateInput size="lg" onChange={fn()} />
21
- <DateInput mode="month-year" onChange={fn()} />
22
- </>
23
- ),
24
- ...withRTLDiff({ renderAs: 'iframe' }),
16
+ render: () => {
17
+ const i18n = useRtlDiffI18n();
18
+ return (
19
+ <>
20
+ <DateInput
21
+ size="sm"
22
+ dayLabel={i18n.dayLabel}
23
+ monthLabel={i18n.monthLabel}
24
+ yearLabel={i18n.yearLabel}
25
+ onChange={fn()}
26
+ />
27
+ <DateInput
28
+ size="md"
29
+ dayLabel={i18n.dayLabel}
30
+ monthLabel={i18n.monthLabel}
31
+ yearLabel={i18n.yearLabel}
32
+ onChange={fn()}
33
+ />
34
+ <DateInput
35
+ size="lg"
36
+ dayLabel={i18n.dayLabel}
37
+ monthLabel={i18n.monthLabel}
38
+ yearLabel={i18n.yearLabel}
39
+ onChange={fn()}
40
+ />
41
+ <DateInput
42
+ mode="month-year"
43
+ monthLabel={i18n.monthLabel}
44
+ yearLabel={i18n.yearLabel}
45
+ onChange={fn()}
46
+ />
47
+ </>
48
+ );
49
+ },
50
+ ...withRTLDiff({
51
+ renderAs: 'iframe',
52
+ i18n: {
53
+ dayLabel: { en: 'Day', ar: 'اليوم' },
54
+ monthLabel: { en: 'Month', ar: 'الشهر' },
55
+ yearLabel: { en: 'Year', ar: 'السنة' },
56
+ },
57
+ }),
25
58
  };
26
59
 
27
60
  export const OpenDropdown: Story = {
28
- render: () => <DateInput onChange={() => {}} />,
61
+ render: () => {
62
+ const i18n = useRtlDiffI18n();
63
+ return (
64
+ <DateInput
65
+ dayLabel={i18n.dayLabel}
66
+ monthLabel={i18n.monthLabel}
67
+ yearLabel={i18n.yearLabel}
68
+ onChange={() => {}}
69
+ />
70
+ );
71
+ },
29
72
  play: async ({ canvasElement }) => {
30
73
  const canvas = within(canvasElement);
31
74
  const trigger = canvas.queryByRole('combobox');
32
75
  if (!trigger) return;
33
76
  await userEvent.click(trigger);
34
77
  },
35
- ...withRTLDiff({ renderAs: 'iframe' }),
78
+ ...withRTLDiff({
79
+ renderAs: 'iframe',
80
+ i18n: {
81
+ dayLabel: { en: 'Day', ar: 'اليوم' },
82
+ monthLabel: { en: 'Month', ar: 'الشهر' },
83
+ yearLabel: { en: 'Year', ar: 'السنة' },
84
+ },
85
+ }),
36
86
  };
@@ -15,8 +15,8 @@ type Story = StoryObj<typeof DateLookup>;
15
15
  const selectedDate = new Date(2024, 5, 14);
16
16
 
17
17
  const i18nConfig = {
18
- label: { ltr: 'Select date', rtl: 'اختر التاريخ' },
19
- placeholder: { ltr: 'Choose a date', rtl: 'اختر تاريخًا' },
18
+ label: { en: 'Select date', ar: 'اختر التاريخ' },
19
+ placeholder: { en: 'Choose a date', ar: 'اختر تاريخًا' },
20
20
  };
21
21
 
22
22
  export const TriggerVariants: Story = {
@@ -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 { Size } from '../../common';
5
5
  import Decision, { DecisionPresentation, DecisionType } from '..';
6
6
  import AvatarView from '../../AvatarView';
@@ -13,67 +13,83 @@ export default {
13
13
 
14
14
  type Story = StoryObj<typeof Decision>;
15
15
 
16
- const options = [
17
- {
18
- title: 'Send money',
19
- description: 'Fast international transfers.',
20
- href: '#',
21
- 'aria-label': 'Send money',
22
- media: {
23
- block: <img src="https://wise.com/public-resources/assets/illustrations/globe.svg" alt="" />,
24
- list: <AvatarView profileName="Alice Smith" />,
25
- },
26
- },
27
- {
28
- title: 'Receive money',
29
- description: 'Get paid from abroad.',
30
- href: '#',
31
- 'aria-label': 'Receive money',
32
- media: {
33
- block: <img src="https://wise.com/public-resources/assets/illustrations/globe.svg" alt="" />,
34
- list: <AvatarView profileName="Alice Smith" />,
35
- },
36
- },
37
- ];
38
-
39
16
  /**
40
17
  * NavigationOption renders media on the inline-start side and a chevron on the
41
18
  * inline-end side; these flip in RTL. The LIST_BLOCK and LIST_BLOCK_GRID
42
19
  * presentations use flex-row layout that also reverses direction in RTL.
43
20
  */
44
21
  export const RTLDiff: Story = {
45
- render: () => (
46
- <>
47
- <Decision
48
- options={options}
49
- presentation={DecisionPresentation.LIST}
50
- type={DecisionType.NAVIGATION}
51
- />
52
- <Decision
53
- options={options}
54
- presentation={DecisionPresentation.LIST}
55
- type={DecisionType.NAVIGATION}
56
- isContainerAligned
57
- />
58
- <Decision
59
- options={options}
60
- presentation={DecisionPresentation.LIST_BLOCK}
61
- type={DecisionType.NAVIGATION}
62
- size={Size.MEDIUM}
63
- />
64
- <Decision
65
- options={options}
66
- presentation={DecisionPresentation.LIST_BLOCK}
67
- type={DecisionType.NAVIGATION}
68
- size={Size.SMALL}
69
- />
70
- <Decision
71
- options={[...options, ...options]}
72
- presentation={DecisionPresentation.LIST_BLOCK_GRID}
73
- type={DecisionType.NAVIGATION}
74
- size={Size.MEDIUM}
75
- />
76
- </>
77
- ),
78
- ...withRTLDiff(),
22
+ render: () => {
23
+ const i18n = useRtlDiffI18n();
24
+
25
+ const options = [
26
+ {
27
+ title: i18n.sendTitle,
28
+ description: i18n.sendDescription,
29
+ href: '#',
30
+ 'aria-label': i18n.sendTitle,
31
+ media: {
32
+ block: (
33
+ <img src="https://wise.com/public-resources/assets/illustrations/globe.svg" alt="" />
34
+ ),
35
+ list: <AvatarView profileName={i18n.profileName} />,
36
+ },
37
+ },
38
+ {
39
+ title: i18n.receiveTitle,
40
+ description: i18n.receiveDescription,
41
+ href: '#',
42
+ 'aria-label': i18n.receiveTitle,
43
+ media: {
44
+ block: (
45
+ <img src="https://wise.com/public-resources/assets/illustrations/globe.svg" alt="" />
46
+ ),
47
+ list: <AvatarView profileName={i18n.profileName} />,
48
+ },
49
+ },
50
+ ];
51
+
52
+ return (
53
+ <>
54
+ <Decision
55
+ options={options}
56
+ presentation={DecisionPresentation.LIST}
57
+ type={DecisionType.NAVIGATION}
58
+ />
59
+ <Decision
60
+ options={options}
61
+ presentation={DecisionPresentation.LIST}
62
+ type={DecisionType.NAVIGATION}
63
+ isContainerAligned
64
+ />
65
+ <Decision
66
+ options={options}
67
+ presentation={DecisionPresentation.LIST_BLOCK}
68
+ type={DecisionType.NAVIGATION}
69
+ size={Size.MEDIUM}
70
+ />
71
+ <Decision
72
+ options={options}
73
+ presentation={DecisionPresentation.LIST_BLOCK}
74
+ type={DecisionType.NAVIGATION}
75
+ size={Size.SMALL}
76
+ />
77
+ <Decision
78
+ options={[...options, ...options]}
79
+ presentation={DecisionPresentation.LIST_BLOCK_GRID}
80
+ type={DecisionType.NAVIGATION}
81
+ size={Size.MEDIUM}
82
+ />
83
+ </>
84
+ );
85
+ },
86
+ ...withRTLDiff({
87
+ i18n: {
88
+ sendTitle: { en: 'Send money', ar: 'إرسال الأموال' },
89
+ sendDescription: { en: 'Fast international transfers.', ar: 'تحويلات دولية سريعة.' },
90
+ receiveTitle: { en: 'Receive money', ar: 'استلام الأموال' },
91
+ receiveDescription: { en: 'Get paid from abroad.', ar: 'استلم أموالك من الخارج.' },
92
+ profileName: { en: 'Alice Smith', ar: 'أليس سميث' },
93
+ },
94
+ }),
79
95
  };