@transferwise/components 0.0.0-experimental-e94d625 → 0.0.0-experimental-8e1de95

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 (69) hide show
  1. package/build/Snackbar/Snackbar.js +97 -101
  2. package/build/Snackbar/Snackbar.js.map +1 -1
  3. package/build/Snackbar/Snackbar.mjs +98 -102
  4. package/build/Snackbar/Snackbar.mjs.map +1 -1
  5. package/build/types/Carousel/_stories/constants.d.ts +25 -0
  6. package/build/types/Carousel/_stories/constants.d.ts.map +1 -1
  7. package/build/types/ListItem/_stories/variants/helpers.d.ts +38 -1
  8. package/build/types/ListItem/_stories/variants/helpers.d.ts.map +1 -1
  9. package/build/types/Snackbar/Snackbar.d.ts +1 -15
  10. package/build/types/Snackbar/Snackbar.d.ts.map +1 -1
  11. package/package.json +1 -1
  12. package/src/Accordion/_stories/Accordion.test.story.tsx +74 -48
  13. package/src/AvatarLayout/_stories/AvatarLayout.test.story.tsx +46 -30
  14. package/src/Button/LegacyButton/_stories/LegacyButton.test.story.tsx +29 -19
  15. package/src/Calendar/_stories/Calendar.test.story.tsx +34 -21
  16. package/src/Carousel/_stories/Carousel.test.story.tsx +18 -8
  17. package/src/Carousel/_stories/constants.tsx +29 -4
  18. package/src/Checkbox/_stories/Checkbox.test.story.tsx +22 -13
  19. package/src/CheckboxButton/_stories/CheckboxButton.test.story.tsx +23 -14
  20. package/src/Chips/_stories/Chips.test.story.tsx +51 -36
  21. package/src/DateInput/_stories/DateInput.rtl.test.story.tsx +62 -12
  22. package/src/Decision/_stories/Decision.test.story.tsx +74 -58
  23. package/src/DefinitionList/_stories/DefinitionList.test.story.tsx +58 -42
  24. package/src/Drawer/_stories/Drawer.rtl.test.story.tsx +65 -38
  25. package/src/ExpressiveMoneyInput/_stories/ExpressiveMoneyInput.rtl.test.story.tsx +107 -74
  26. package/src/Field/_stories/Field.test.story.tsx +1 -1
  27. package/src/FlowNavigation/_stories/FlowNavigation.rtl.test.story.tsx +81 -51
  28. package/src/Header/_stories/Header.test.story.tsx +30 -18
  29. package/src/Info/_stories/Info.rtl.test.story.tsx +124 -50
  30. package/src/Inputs/InputGroup/_stories/InputGroup.test.story.tsx +4 -2
  31. package/src/Inputs/SelectInput/_stories/SelectInput.rtl.test.story.tsx +106 -77
  32. package/src/InstructionsList/_stories/InstructionsList.test.story.tsx +43 -16
  33. package/src/Link/_stories/Link.test.story.tsx +27 -13
  34. package/src/ListItem/_stories/ListItem.rtl.test.story.tsx +126 -6
  35. package/src/ListItem/_stories/variants/helpers.tsx +174 -126
  36. package/src/Loader/_stories/Loader.test.story.tsx +17 -10
  37. package/src/Modal/_stories/Modal.rtl.test.story.tsx +58 -39
  38. package/src/MoneyInput/_stories/MoneyInput.rtl.test.story.tsx +14 -2
  39. package/src/Nudge/_stories/Nudge.test.story.tsx +70 -21
  40. package/src/Popover/_stories/Popover.rtl.test.story.tsx +92 -49
  41. package/src/PromoCard/_stories/PromoCard.test.story.tsx +53 -29
  42. package/src/PromoCard/_stories/PromoCardGroup.test.story.tsx +60 -36
  43. package/src/Prompt/ActionPrompt/_stories/ActionPrompt.test.story.tsx +74 -38
  44. package/src/Prompt/CriticalBanner/_stories/CriticalBanner.test.story.tsx +68 -31
  45. package/src/Prompt/InfoPrompt/_stories/InfoPrompt.test.story.tsx +52 -22
  46. package/src/Prompt/InlinePrompt/_stories/InlinePrompt.test.story.tsx +36 -21
  47. package/src/Radio/_stories/Radio.test.story.tsx +60 -46
  48. package/src/RadioGroup/_stories/RadioGroup.test.story.tsx +70 -51
  49. package/src/Section/_stories/Section.test.story.tsx +30 -14
  50. package/src/SegmentedControl/_stories/SegmentedControl.test.story.tsx +38 -15
  51. package/src/SlidingPanel/_stories/SlidingPanel.rtl.test.story.tsx +58 -34
  52. package/src/Snackbar/Snackbar.tsx +90 -88
  53. package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +24 -12
  54. package/src/Stepper/_stories/Stepper.test.story.tsx +27 -9
  55. package/src/Switch/_stories/Switch.test.story.tsx +20 -12
  56. package/src/Table/_stories/Table.test.story.tsx +107 -86
  57. package/src/Tabs/_stories/Tabs.test.story.tsx +92 -52
  58. package/src/Tag/_stories/Tag.test.story.tsx +27 -16
  59. package/src/Tooltip/_stories/Tooltip.rtl.test.story.tsx +68 -25
  60. package/src/Typeahead/_stories/Typeahead.rtl.test.story.tsx +3 -3
  61. package/src/Upload/_stories/Upload.rtl.test.story.tsx +49 -26
  62. package/src/UploadInput/_stories/UploadInput.test.story.tsx +63 -41
  63. package/src/_deprecated/Alert/_stories/Alert.test.story.tsx +45 -24
  64. package/src/_deprecated/Card/_stories/Card.test.story.tsx +47 -23
  65. package/src/_deprecated/CriticalBanner/_stories/CriticalCommsBanner.test.story.tsx +21 -15
  66. package/src/_deprecated/InlineAlert/_stories/InlineAlert.test.story.tsx +23 -12
  67. package/src/_deprecated/Select/_stories/Select.rtl.test.story.tsx +76 -40
  68. package/src/common/BottomSheet/_stories/BottomSheet.test.story.tsx +38 -20
  69. package/src/common/Panel/_stories/Panel.rtl.test.story.tsx +135 -51
@@ -5,7 +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
+ import { useRtlDiffI18n, withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
9
9
  import { withVariantConfig } from '../../../../.storybook/helpers';
10
10
 
11
11
  const withComponentGrid =
@@ -556,25 +556,55 @@ export const LiveRegionDismiss: Story = {
556
556
  };
557
557
 
558
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(),
559
+ render: () => {
560
+ const i18n = useRtlDiffI18n();
561
+ return (
562
+ <>
563
+ <InfoPrompt description={i18n.basicDescription} />
564
+ <InfoPrompt title={i18n.withTitleHeading} description={i18n.withTitleDescription} />
565
+ <InfoPrompt description={i18n.dismissibleDescription} onDismiss={() => {}} />
566
+ <InfoPrompt
567
+ title={i18n.withActionHeading}
568
+ description={i18n.withActionDescription}
569
+ action={{ label: i18n.learnMore, href: '#' }}
570
+ />
571
+ <InfoPrompt
572
+ description={i18n.customMediaDescription}
573
+ media={{ asset: <Star title={i18n.starredMedia} /> }}
574
+ />
575
+ <InfoPrompt
576
+ title={i18n.allOptionsHeading}
577
+ description={i18n.allOptionsDescription}
578
+ media={{ asset: <Star title={i18n.starredMedia} /> }}
579
+ action={{ label: i18n.viewDetails, href: '#' }}
580
+ onDismiss={() => {}}
581
+ />
582
+ </>
583
+ );
584
+ },
585
+ ...withRTLDiff({
586
+ i18n: {
587
+ basicDescription: { en: 'Basic description only.', ar: 'الوصف الأساسي فقط.' },
588
+ withTitleHeading: { en: 'With Title', ar: 'مع عنوان' },
589
+ withTitleDescription: {
590
+ en: 'Description with a title above it.',
591
+ ar: 'وصف مع عنوان في الأعلى.',
592
+ },
593
+ dismissibleDescription: { en: 'Dismissible prompt.', ar: 'تنبيه قابل للإغلاق.' },
594
+ withActionHeading: { en: 'With Action', ar: 'مع إجراء' },
595
+ withActionDescription: {
596
+ en: 'Description with an action link below.',
597
+ ar: 'وصف مع رابط إجراء في الأسفل.',
598
+ },
599
+ learnMore: { en: 'Learn more', ar: 'اعرف المزيد' },
600
+ customMediaDescription: { en: 'Custom media icon.', ar: 'أيقونة وسائط مخصصة.' },
601
+ starredMedia: { en: 'Starred', ar: 'مميز بنجمة' },
602
+ allOptionsHeading: { en: 'All Options', ar: 'جميع الخيارات' },
603
+ allOptionsDescription: {
604
+ en: 'Title, action, dismiss, and custom media combined.',
605
+ ar: 'عنوان وإجراء وإغلاق ووسائط مخصصة مجتمعة.',
606
+ },
607
+ viewDetails: { en: 'View details', ar: 'عرض التفاصيل' },
608
+ },
609
+ }),
580
610
  };
@@ -2,7 +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
+ import { useRtlDiffI18n, withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
6
6
 
7
7
  export default {
8
8
  title: 'Prompts/InlinePrompt/Tests',
@@ -22,27 +22,42 @@ export const TinyScreen: Story = {
22
22
  };
23
23
 
24
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>
25
+ render: () => {
26
+ const i18n = useRtlDiffI18n();
27
+ return (
28
+ <>
29
+ {/* default icon at inline-start, auto width */}
30
+ <InlinePrompt sentiment="positive">{i18n.defaultIcon}</InlinePrompt>
29
31
 
30
- {/* custom media icon, auto width */}
31
- <InlinePrompt sentiment="positive" media={<Suitcase />}>
32
- Custom icon with auto width.
33
- </InlinePrompt>
32
+ {/* custom media icon, auto width */}
33
+ <InlinePrompt sentiment="positive" media={<Suitcase />}>
34
+ {i18n.customIcon}
35
+ </InlinePrompt>
34
36
 
35
- {/* full width — icon position flips */}
36
- <InlinePrompt sentiment="positive" media={<Suitcase />} width="full">
37
- Custom icon with full width.
38
- </InlinePrompt>
37
+ {/* full width — icon position flips */}
38
+ <InlinePrompt sentiment="positive" media={<Suitcase />} width="full">
39
+ {i18n.fullWidth}
40
+ </InlinePrompt>
39
41
 
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(),
42
+ {/* multi-line content — verifies wrapping alignment */}
43
+ <InlinePrompt sentiment="warning" width="full">
44
+ {i18n.multiLine}
45
+ </InlinePrompt>
46
+ </>
47
+ );
48
+ },
49
+ ...withRTLDiff({
50
+ i18n: {
51
+ defaultIcon: {
52
+ en: 'Short content with default icon.',
53
+ ar: 'محتوى قصير مع الأيقونة الافتراضية.',
54
+ },
55
+ customIcon: { en: 'Custom icon with auto width.', ar: 'أيقونة مخصصة بعرض تلقائي.' },
56
+ fullWidth: { en: 'Custom icon with full width.', ar: 'أيقونة مخصصة بعرض كامل.' },
57
+ multiLine: {
58
+ en: 'This prompt has longer content that may wrap to multiple lines to verify that the icon alignment remains correct in RTL layout.',
59
+ ar: 'يحتوي هذا التنبيه على محتوى أطول قد يمتد على عدة أسطر للتحقق من أن محاذاة الأيقونة تظل صحيحة في التصميم من اليمين إلى اليسار.',
60
+ },
61
+ },
62
+ }),
48
63
  };
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { Flag } from '@wise/art';
3
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
3
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
4
  import AvatarView from '../../AvatarView';
5
5
  import Radio from '../Radio';
6
6
 
@@ -13,49 +13,63 @@ export default {
13
13
  type Story = StoryObj<typeof Radio>;
14
14
 
15
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(),
16
+ render: () => {
17
+ const i18n = useRtlDiffI18n();
18
+ return (
19
+ <>
20
+ <Radio
21
+ label={i18n.standardOption}
22
+ name="radio-rtl"
23
+ id="radio-rtl-basic"
24
+ value="basic"
25
+ onChange={() => {}}
26
+ />
27
+ <Radio
28
+ label={i18n.withSecondary}
29
+ secondary={i18n.secondaryDescription}
30
+ name="radio-rtl"
31
+ id="radio-rtl-secondary"
32
+ value="secondary"
33
+ onChange={() => {}}
34
+ />
35
+ <Radio
36
+ label={i18n.withAvatar}
37
+ name="radio-rtl"
38
+ id="radio-rtl-avatar"
39
+ value="avatar"
40
+ avatar={
41
+ <AvatarView size={40}>
42
+ <Flag code="IM" />
43
+ </AvatarView>
44
+ }
45
+ onChange={() => {}}
46
+ />
47
+ <Radio
48
+ label={i18n.withSecondaryAndAvatar}
49
+ secondary={i18n.secondaryDescription}
50
+ name="radio-rtl"
51
+ id="radio-rtl-secondary-avatar"
52
+ value="secondary-avatar"
53
+ avatar={
54
+ <AvatarView size={40}>
55
+ <Flag code="IM" />
56
+ </AvatarView>
57
+ }
58
+ onChange={() => {}}
59
+ />
60
+ </>
61
+ );
62
+ },
63
+ ...withRTLDiff({
64
+ i18n: {
65
+ standardOption: { en: 'Standard option', ar: 'خيار عادي' },
66
+ withSecondary: { en: 'Option with secondary text', ar: 'خيار مع نص ثانوي' },
67
+ withAvatar: { en: 'Option with avatar', ar: 'خيار مع صورة رمزية' },
68
+ withSecondaryAndAvatar: {
69
+ en: 'Option with secondary text and avatar',
70
+ ar: 'خيار مع نص ثانوي وصورة رمزية',
71
+ },
72
+ secondaryDescription: { en: 'Secondary description', ar: 'وصف ثانوي' },
73
+ },
74
+ }),
61
75
  };
@@ -3,7 +3,7 @@ import Field from '../../Field/Field';
3
3
  import { Meta, StoryObj } from '@storybook/react-webpack5';
4
4
  import { fn } from 'storybook/test';
5
5
  import { Flag } from '@wise/art';
6
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
6
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
7
7
  import AvatarView from '../../AvatarView';
8
8
 
9
9
  const meta = {
@@ -65,54 +65,73 @@ export const FieldsWithoutPrompt = {
65
65
  } satisfies Story;
66
66
 
67
67
  export const RTLDiff: Story<string> = {
68
- render: () => (
69
- <>
70
- <RadioGroup
71
- name="radio-group-rtl-basic"
72
- selectedValue="option-1"
73
- radios={[
74
- { value: 'option-1', label: 'Option one' },
75
- { value: 'option-2', label: 'Option two' },
76
- { value: 'option-3', label: 'Option three' },
77
- ]}
78
- onChange={() => {}}
79
- />
80
- <RadioGroup
81
- name="radio-group-rtl-secondary"
82
- selectedValue="option-a"
83
- radios={[
84
- { value: 'option-a', label: 'Option A', secondary: 'Secondary text for A' },
85
- { value: 'option-b', label: 'Option B', secondary: 'Secondary text for B' },
86
- ]}
87
- onChange={() => {}}
88
- />
89
- <RadioGroup
90
- name="radio-group-rtl-avatar"
91
- selectedValue="option-x"
92
- radios={[
93
- {
94
- value: 'option-x',
95
- label: 'Option X',
96
- avatar: (
97
- <AvatarView size={40}>
98
- <Flag code="IM" />
99
- </AvatarView>
100
- ),
101
- },
102
- {
103
- value: 'option-y',
104
- label: 'Option Y',
105
- secondary: 'With secondary and avatar',
106
- avatar: (
107
- <AvatarView size={40}>
108
- <Flag code="IM" />
109
- </AvatarView>
110
- ),
111
- },
112
- ]}
113
- onChange={() => {}}
114
- />
115
- </>
116
- ),
117
- ...withRTLDiff(),
68
+ render: () => {
69
+ const i18n = useRtlDiffI18n();
70
+ return (
71
+ <>
72
+ <RadioGroup
73
+ name="radio-group-rtl-basic"
74
+ selectedValue="option-1"
75
+ radios={[
76
+ { value: 'option-1', label: i18n.optionOne },
77
+ { value: 'option-2', label: i18n.optionTwo },
78
+ { value: 'option-3', label: i18n.optionThree },
79
+ ]}
80
+ onChange={() => {}}
81
+ />
82
+ <RadioGroup
83
+ name="radio-group-rtl-secondary"
84
+ selectedValue="option-a"
85
+ radios={[
86
+ { value: 'option-a', label: i18n.optionA, secondary: i18n.secondaryA },
87
+ { value: 'option-b', label: i18n.optionB, secondary: i18n.secondaryB },
88
+ ]}
89
+ onChange={() => {}}
90
+ />
91
+ <RadioGroup
92
+ name="radio-group-rtl-avatar"
93
+ selectedValue="option-x"
94
+ radios={[
95
+ {
96
+ value: 'option-x',
97
+ label: i18n.optionX,
98
+ avatar: (
99
+ <AvatarView size={40}>
100
+ <Flag code="IM" />
101
+ </AvatarView>
102
+ ),
103
+ },
104
+ {
105
+ value: 'option-y',
106
+ label: i18n.optionY,
107
+ secondary: i18n.secondaryWithAvatar,
108
+ avatar: (
109
+ <AvatarView size={40}>
110
+ <Flag code="IM" />
111
+ </AvatarView>
112
+ ),
113
+ },
114
+ ]}
115
+ onChange={() => {}}
116
+ />
117
+ </>
118
+ );
119
+ },
120
+ ...withRTLDiff({
121
+ i18n: {
122
+ optionOne: { en: 'Option one', ar: 'الخيار الأول' },
123
+ optionTwo: { en: 'Option two', ar: 'الخيار الثاني' },
124
+ optionThree: { en: 'Option three', ar: 'الخيار الثالث' },
125
+ optionA: { en: 'Option A', ar: 'الخيار أ' },
126
+ optionB: { en: 'Option B', ar: 'الخيار ب' },
127
+ secondaryA: { en: 'Secondary text for A', ar: 'نص ثانوي للخيار أ' },
128
+ secondaryB: { en: 'Secondary text for B', ar: 'نص ثانوي للخيار ب' },
129
+ optionX: { en: 'Option X', ar: 'الخيار س' },
130
+ optionY: { en: 'Option Y', ar: 'الخيار ص' },
131
+ secondaryWithAvatar: {
132
+ en: 'With secondary and avatar',
133
+ ar: 'مع نص ثانوي وصورة رمزية',
134
+ },
135
+ },
136
+ }),
118
137
  };
@@ -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 Header from '../../Header';
5
5
  import Section from '..';
6
6
 
@@ -13,17 +13,33 @@ export default {
13
13
  type Story = StoryObj<typeof Section>;
14
14
 
15
15
  export const RTLDiff: Story = {
16
- render: () => (
17
- <>
18
- <Section>
19
- <Header title="Default section" />
20
- Section content without horizontal padding.
21
- </Section>
22
- <Section withHorizontalPadding>
23
- <Header title="With horizontal padding" />
24
- Section content with horizontal padding applied.
25
- </Section>
26
- </>
27
- ),
28
- ...withRTLDiff(),
16
+ render: () => {
17
+ const i18n = useRtlDiffI18n();
18
+ return (
19
+ <>
20
+ <Section>
21
+ <Header title={i18n.defaultTitle} />
22
+ {i18n.defaultContent}
23
+ </Section>
24
+ <Section withHorizontalPadding>
25
+ <Header title={i18n.paddedTitle} />
26
+ {i18n.paddedContent}
27
+ </Section>
28
+ </>
29
+ );
30
+ },
31
+ ...withRTLDiff({
32
+ i18n: {
33
+ defaultTitle: { en: 'Default section', ar: 'قسم افتراضي' },
34
+ defaultContent: {
35
+ en: 'Section content without horizontal padding.',
36
+ ar: 'محتوى القسم بدون حشو أفقي.',
37
+ },
38
+ paddedTitle: { en: 'With horizontal padding', ar: 'مع حشو أفقي' },
39
+ paddedContent: {
40
+ en: 'Section content with horizontal padding applied.',
41
+ ar: 'محتوى القسم مع تطبيق الحشو الأفقي.',
42
+ },
43
+ },
44
+ }),
29
45
  };
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
3
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
3
+ import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
4
  import SegmentedControl from '../SegmentedControl';
5
5
 
6
6
  export default {
@@ -11,19 +11,15 @@ export default {
11
11
 
12
12
  type Story = StoryObj<typeof SegmentedControl>;
13
13
 
14
- const inputSegments = [
15
- { id: 'seg-one', label: 'One', value: 'one' },
16
- { id: 'seg-two', label: 'Two', value: 'two' },
17
- { id: 'seg-three', label: 'Three', value: 'three' },
18
- ] as const;
19
-
20
- const viewSegments = [
21
- { id: 'seg-alpha', label: 'Alpha', value: 'alpha', controls: 'panel-alpha' },
22
- { id: 'seg-beta', label: 'Beta', value: 'beta', controls: 'panel-beta' },
23
- { id: 'seg-gamma', label: 'Gamma', value: 'gamma', controls: 'panel-gamma' },
24
- ] as const;
14
+ type InteractiveSegmentedControlProps = {
15
+ inputSegments: readonly { id: string; label: string; value: string }[];
16
+ viewSegments: readonly { id: string; label: string; value: string; controls: string }[];
17
+ };
25
18
 
26
- function InteractiveSegmentedControl() {
19
+ function InteractiveSegmentedControl({
20
+ inputSegments,
21
+ viewSegments,
22
+ }: InteractiveSegmentedControlProps) {
27
23
  const [inputValue, setInputValue] = useState('one');
28
24
  const [viewValue, setViewValue] = useState('beta');
29
25
 
@@ -48,6 +44,33 @@ function InteractiveSegmentedControl() {
48
44
  }
49
45
 
50
46
  export const RTLDiff: Story = {
51
- render: () => <InteractiveSegmentedControl />,
52
- ...withRTLDiff({ width: 'stretch', renderAs: 'iframe' }),
47
+ render: () => {
48
+ const i18n = useRtlDiffI18n();
49
+ return (
50
+ <InteractiveSegmentedControl
51
+ inputSegments={[
52
+ { id: 'seg-one', label: i18n.segmentOne, value: 'one' },
53
+ { id: 'seg-two', label: i18n.segmentTwo, value: 'two' },
54
+ { id: 'seg-three', label: i18n.segmentThree, value: 'three' },
55
+ ]}
56
+ viewSegments={[
57
+ { id: 'seg-alpha', label: i18n.segmentAlpha, value: 'alpha', controls: 'panel-alpha' },
58
+ { id: 'seg-beta', label: i18n.segmentBeta, value: 'beta', controls: 'panel-beta' },
59
+ { id: 'seg-gamma', label: i18n.segmentGamma, value: 'gamma', controls: 'panel-gamma' },
60
+ ]}
61
+ />
62
+ );
63
+ },
64
+ ...withRTLDiff({
65
+ width: 'stretch',
66
+ renderAs: 'iframe',
67
+ i18n: {
68
+ segmentOne: { en: 'One', ar: 'واحد' },
69
+ segmentTwo: { en: 'Two', ar: 'اثنان' },
70
+ segmentThree: { en: 'Three', ar: 'ثلاثة' },
71
+ segmentAlpha: { en: 'Alpha', ar: 'ألفا' },
72
+ segmentBeta: { en: 'Beta', ar: 'بيتا' },
73
+ segmentGamma: { en: 'Gamma', ar: 'غاما' },
74
+ },
75
+ }),
53
76
  };
@@ -1,6 +1,10 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
 
3
- import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
3
+ import {
4
+ useRtlDiffI18n,
5
+ withRTLDiff,
6
+ type I18nMap,
7
+ } from '../../../.storybook/decorators/RtlDiffDecorator';
4
8
  import SlidingPanel from '../SlidingPanel';
5
9
 
6
10
  export default {
@@ -11,7 +15,7 @@ export default {
11
15
 
12
16
  type Story = StoryObj<typeof SlidingPanel>;
13
17
 
14
- const iframeDiff = withRTLDiff({ renderAs: 'iframe', width: 'stretch' });
18
+ const iframeDiff = (i18n: I18nMap) => withRTLDiff({ renderAs: 'iframe', width: 'stretch', i18n });
15
19
 
16
20
  const containerStyle: React.CSSProperties = {
17
21
  position: 'relative',
@@ -27,45 +31,65 @@ const panelContentStyle: React.CSSProperties = {
27
31
  };
28
32
 
29
33
  export const PositionLeft: Story = {
30
- render: () => (
31
- <div style={containerStyle}>
32
- <SlidingPanel open position="left">
33
- <div style={panelContentStyle}>Left panel content</div>
34
- </SlidingPanel>
35
- </div>
36
- ),
37
- ...iframeDiff,
34
+ render: () => {
35
+ const i18n = useRtlDiffI18n();
36
+ return (
37
+ <div style={containerStyle}>
38
+ <SlidingPanel open position="left">
39
+ <div style={panelContentStyle}>{i18n.panelContent}</div>
40
+ </SlidingPanel>
41
+ </div>
42
+ );
43
+ },
44
+ ...iframeDiff({
45
+ panelContent: { en: 'Left panel content', ar: 'محتوى اللوحة اليسرى' },
46
+ }),
38
47
  };
39
48
 
40
49
  export const PositionRight: Story = {
41
- render: () => (
42
- <div style={containerStyle}>
43
- <SlidingPanel open position="right">
44
- <div style={panelContentStyle}>Right panel content</div>
45
- </SlidingPanel>
46
- </div>
47
- ),
48
- ...iframeDiff,
50
+ render: () => {
51
+ const i18n = useRtlDiffI18n();
52
+ return (
53
+ <div style={containerStyle}>
54
+ <SlidingPanel open position="right">
55
+ <div style={panelContentStyle}>{i18n.panelContent}</div>
56
+ </SlidingPanel>
57
+ </div>
58
+ );
59
+ },
60
+ ...iframeDiff({
61
+ panelContent: { en: 'Right panel content', ar: 'محتوى اللوحة اليمنى' },
62
+ }),
49
63
  };
50
64
 
51
65
  export const PositionLeftWithBorder: Story = {
52
- render: () => (
53
- <div style={containerStyle}>
54
- <SlidingPanel open position="left" showSlidingPanelBorder>
55
- <div style={panelContentStyle}>Left panel with border</div>
56
- </SlidingPanel>
57
- </div>
58
- ),
59
- ...iframeDiff,
66
+ render: () => {
67
+ const i18n = useRtlDiffI18n();
68
+ return (
69
+ <div style={containerStyle}>
70
+ <SlidingPanel open position="left" showSlidingPanelBorder>
71
+ <div style={panelContentStyle}>{i18n.panelContent}</div>
72
+ </SlidingPanel>
73
+ </div>
74
+ );
75
+ },
76
+ ...iframeDiff({
77
+ panelContent: { en: 'Left panel with border', ar: 'اللوحة اليسرى مع حدود' },
78
+ }),
60
79
  };
61
80
 
62
81
  export const PositionRightWithBorder: Story = {
63
- render: () => (
64
- <div style={containerStyle}>
65
- <SlidingPanel open position="right" showSlidingPanelBorder>
66
- <div style={panelContentStyle}>Right panel with border</div>
67
- </SlidingPanel>
68
- </div>
69
- ),
70
- ...iframeDiff,
82
+ render: () => {
83
+ const i18n = useRtlDiffI18n();
84
+ return (
85
+ <div style={containerStyle}>
86
+ <SlidingPanel open position="right" showSlidingPanelBorder>
87
+ <div style={panelContentStyle}>{i18n.panelContent}</div>
88
+ </SlidingPanel>
89
+ </div>
90
+ );
91
+ },
92
+ ...iframeDiff({
93
+ panelContent: { en: 'Right panel with border', ar: 'اللوحة اليمنى مع حدود' },
94
+ }),
71
95
  };