@transferwise/components 0.0.0-experimental-5f7dae1 → 0.0.0-experimental-20085a3

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 (81) hide show
  1. package/build/types/Body/Body.d.ts +2 -2
  2. package/build/types/IconButton/IconButton.d.ts +1 -1
  3. package/build/types/ListItem/_stories/variants/helpers.d.ts.map +1 -1
  4. package/build/types/MoneyInput/MoneyInput.d.ts +1 -1
  5. package/build/types/MoneyInput/MoneyInput.d.ts.map +1 -1
  6. package/build/types/Title/Title.d.ts +2 -2
  7. package/build/types/Upload/Steps/UploadImageStep/UploadImageStep.d.ts +1 -1
  8. package/build/types/UploadInput/UploadItem/UploadItemLink.d.ts +1 -1
  9. package/package.json +1 -1
  10. package/src/Accordion/_stories/Accordion.rtl.test.story.tsx +71 -0
  11. package/src/AvatarLayout/_stories/AvatarLayout.rtl.test.story.tsx +77 -0
  12. package/src/AvatarView/_stories/AvatarView.rtl.test.story.tsx +162 -0
  13. package/src/Button/LegacyButton/_stories/LegacyButton.rtl.test.story.tsx +32 -0
  14. package/src/Calendar/_stories/Calendar.rtl.test.story.tsx +52 -0
  15. package/src/Calendar/_stories/Calendar.test.story.tsx +28 -24
  16. package/src/Carousel/_stories/Carousel.rtl.test.story.tsx +61 -0
  17. package/src/Checkbox/_stories/Checkbox.rtl.test.story.tsx +31 -0
  18. package/src/CheckboxButton/_stories/CheckboxButton.rtl.test.story.tsx +27 -0
  19. package/src/CheckboxButton/_stories/CheckboxButton.test.story.tsx +0 -37
  20. package/src/Chevron/_stories/Chevron.rtl.test.story.tsx +26 -0
  21. package/src/Chips/_stories/Chips.rtl.test.story.tsx +49 -0
  22. package/src/Chips/_stories/Chips.test.story.tsx +0 -34
  23. package/src/CircularButton/_stories/CircularButton.test.story.tsx +0 -68
  24. package/src/DateInput/_stories/DateInput.rtl.test.story.tsx +25 -0
  25. package/src/DateLookup/_stories/DateLookup.rtl.test.story.tsx +88 -0
  26. package/src/Decision/_stories/Decision.rtl.test.story.tsx +79 -0
  27. package/src/DefinitionList/_stories/DefinitionList.rtl.test.story.tsx +63 -0
  28. package/src/Drawer/_stories/Drawer.rtl.test.story.tsx +58 -0
  29. package/src/ExpressiveMoneyInput/_stories/ExpressiveMoneyInput.rtl.test.story.tsx +118 -0
  30. package/src/Field/_stories/Field.rtl.test.story.tsx +58 -0
  31. package/src/FlowNavigation/_stories/FlowNavigation.rtl.test.story.tsx +70 -0
  32. package/src/Header/_stories/Header.rtl.test.story.tsx +37 -0
  33. package/src/Info/_stories/Info.rtl.test.story.tsx +64 -0
  34. package/src/Inputs/SelectInput/_stories/SelectInput.rtl.test.story.tsx +135 -0
  35. package/src/Inputs/_stories/InputGroup.rtl.test.story.tsx +69 -0
  36. package/src/Inputs/_stories/SearchInput.rtl.test.story.tsx +32 -0
  37. package/src/Inputs/_stories/TextArea.rtl.test.story.tsx +38 -0
  38. package/src/InstructionsList/_stories/InstructionsList.rtl.test.story.tsx +30 -0
  39. package/src/Label/_stories/Label.rtl.test.story.tsx +36 -0
  40. package/src/Link/_stories/Link.rtl.test.story.tsx +26 -0
  41. package/src/ListItem/_stories/{variants/ListItem.rtl.test.story.tsx → ListItem.rtl.test.story.tsx} +6 -10
  42. package/src/ListItem/_stories/variants/helpers.tsx +2 -6
  43. package/src/Logo/_stories/Logo.rtl.test.story.tsx +56 -0
  44. package/src/Modal/_stories/Modal.rtl.test.story.tsx +59 -0
  45. package/src/MoneyInput/_stories/MoneyInput.rtl.test.story.tsx +88 -0
  46. package/src/Nudge/_stories/Nudge.rtl.test.story.tsx +37 -0
  47. package/src/PhoneNumberInput/_stories/PhoneNumberInput.rtl.test.story.tsx +44 -0
  48. package/src/Popover/_stories/Popover.rtl.test.story.tsx +96 -0
  49. package/src/Progress/_stories/Progress.rtl.test.story.tsx +27 -0
  50. package/src/ProgressBar/_stories/ProgressBar.rtl.test.story.tsx +33 -0
  51. package/src/PromoCard/_stories/PromoCard.rtl.test.story.tsx +42 -0
  52. package/src/PromoCard/_stories/PromoCardGroup.rtl.test.story.tsx +51 -0
  53. package/src/Prompt/ActionPrompt/_stories/ActionPrompt.rtl.test.story.tsx +53 -0
  54. package/src/Prompt/CriticalBanner/_stories/CriticalBanner.rtl.test.story.tsx +46 -0
  55. package/src/Prompt/CriticalBanner/_stories/CriticalBanner.test.story.tsx +0 -30
  56. package/src/Prompt/InfoPrompt/_stories/InfoPrompt.rtl.test.story.tsx +36 -0
  57. package/src/Prompt/InlinePrompt/_stories/InlinePrompt.rtl.test.story.tsx +38 -0
  58. package/src/Radio/_stories/Radio.rtl.test.story.tsx +61 -0
  59. package/src/RadioGroup/_stories/RadioGroup.rtl.test.story.tsx +66 -0
  60. package/src/Section/_stories/Section.rtl.test.story.tsx +29 -0
  61. package/src/SegmentedControl/_stories/SegmentedControl.rtl.test.story.tsx +45 -0
  62. package/src/SlidingPanel/_stories/SlidingPanel.rtl.test.story.tsx +70 -0
  63. package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +45 -0
  64. package/src/Snackbar/_stories/Snackbar.test.story.tsx +0 -31
  65. package/src/Stepper/_stories/Stepper.rtl.test.story.tsx +24 -0
  66. package/src/Switch/_stories/Switch.rtl.test.story.tsx +32 -0
  67. package/src/Switch/_stories/Switch.test.story.tsx +0 -26
  68. package/src/Table/_stories/Table.rtl.test.story.tsx +104 -0
  69. package/src/Tabs/_stories/Tabs.rtl.test.story.tsx +72 -0
  70. package/src/TextareaWithDisplayFormat/_stories/TextareaWithDisplayFormat.rtl.test.story.tsx +48 -0
  71. package/src/Tooltip/_stories/Tooltip.rtl.test.story.tsx +79 -0
  72. package/src/Typeahead/_stories/Typeahead.rtl.test.story.tsx +90 -0
  73. package/src/Upload/_stories/Upload.rtl.test.story.tsx +53 -0
  74. package/src/UploadInput/_stories/UploadInput.rtl.test.story.tsx +59 -0
  75. package/src/_deprecated/Alert/_stories/Alert.rtl.test.story.tsx +37 -0
  76. package/src/_deprecated/Card/_stories/Card.rtl.test.story.tsx +38 -0
  77. package/src/_deprecated/CriticalBanner/_stories/CriticalCommsBanner.rtl.test.story.tsx +28 -0
  78. package/src/_deprecated/InlineAlert/_stories/InlineAlert.rtl.test.story.tsx +26 -0
  79. package/src/_deprecated/OverlayHeader/_stories/OverlayHeader.rtl.test.story.tsx +42 -0
  80. package/src/_deprecated/Select/_stories/Select.rtl.test.story.tsx +71 -0
  81. package/src/common/BottomSheet/_stories/BottomSheet.rtl.test.story.tsx +39 -0
@@ -0,0 +1,104 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { DirectDebits } from '@transferwise/icons';
3
+
4
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
+ import Table from '..';
6
+ import { TableHeaderType } from '../Header/TableHeader';
7
+ import { TableRowType, TableRowClickableType } from '../Row/TableRow';
8
+
9
+ const headers: TableHeaderType[] = [
10
+ { header: 'Employee', width: '200px' },
11
+ { header: 'Location' },
12
+ { header: 'Payment', alignment: 'right' },
13
+ { header: 'Status' },
14
+ ];
15
+
16
+ const rows: TableRowType[] = [
17
+ {
18
+ cells: [
19
+ {
20
+ cell: {
21
+ type: 'leading',
22
+ primaryText: 'Bob Brown',
23
+ secondaryText: 'Software Engineer',
24
+ avatar: { profileName: 'Bob Brown', badge: { flagCode: 'GBP' } },
25
+ },
26
+ },
27
+ { cell: { type: 'text', text: 'FR, Paris' } },
28
+ {
29
+ cell: {
30
+ type: 'currency',
31
+ primaryCurrency: { amount: 12345.67, currency: 'eur' },
32
+ secondaryCurrency: { amount: 11000.0, currency: 'gbp' },
33
+ },
34
+ alignment: 'right',
35
+ },
36
+ {
37
+ cell: {
38
+ type: 'status',
39
+ primaryText: 'Cancelled',
40
+ secondaryText: '1 day ago',
41
+ sentiment: 'negative',
42
+ },
43
+ },
44
+ ],
45
+ },
46
+ {
47
+ cells: [
48
+ {
49
+ cell: {
50
+ type: 'leading',
51
+ primaryText: 'Jan Kowalski',
52
+ secondaryText: 'Product Manager',
53
+ avatar: { asset: <DirectDebits />, badge: { status: 'warning' } },
54
+ },
55
+ },
56
+ { cell: { type: 'text', text: 'US, New York' } },
57
+ {
58
+ cell: {
59
+ type: 'currency',
60
+ primaryCurrency: { amount: 23456.78, currency: 'usd' },
61
+ secondaryCurrency: { amount: 21000.0, currency: 'gbp' },
62
+ },
63
+ alignment: 'right',
64
+ },
65
+ {
66
+ cell: {
67
+ type: 'status',
68
+ primaryText: 'Paid',
69
+ secondaryText: 'Yesterday',
70
+ sentiment: 'positive',
71
+ },
72
+ },
73
+ ],
74
+ },
75
+ ];
76
+
77
+ export default {
78
+ component: Table,
79
+ title: 'Content/Table/Tests',
80
+ tags: ['!autodocs', '!manifest'],
81
+ } satisfies Meta<typeof Table>;
82
+
83
+ type Story = StoryObj<typeof Table>;
84
+
85
+ export const RTLDiff: Story = {
86
+ render: () => (
87
+ <>
88
+ <Table data={{ headers, rows }} />
89
+ <Table
90
+ data={{
91
+ headers,
92
+ rows,
93
+ onRowClick: (rowData: TableRowType | TableRowClickableType) => {
94
+ void rowData;
95
+ },
96
+ }}
97
+ />
98
+ <Table data={{ headers, rows }} fullWidth={false} />
99
+ <Table data={{ headers, rows: [] }} />
100
+ <Table data={{ headers, rows }} loading />
101
+ </>
102
+ ),
103
+ ...withRTLDiff(),
104
+ };
@@ -0,0 +1,72 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import { Width } from '../../common';
5
+ import Tabs from '..';
6
+
7
+ export default {
8
+ component: Tabs,
9
+ title: 'Navigation/Tabs/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof Tabs>;
12
+
13
+ type Story = StoryObj<typeof Tabs>;
14
+
15
+ const defaultTabs = [
16
+ { title: 'First tab', disabled: false, content: <div className="p-a-2">First content</div> },
17
+ { title: 'Second tab', disabled: false, content: <div className="p-a-2">Second content</div> },
18
+ { title: 'Third tab', disabled: false, content: <div className="p-a-2">Third content</div> },
19
+ ];
20
+
21
+ /**
22
+ * The tab list is horizontal: tab order, the active indicator translateX, and
23
+ * swipe direction all flip between LTR and RTL. The indicator uses a negated
24
+ * translateX in RTL mode. This diff verifies the layout mirrors correctly.
25
+ */
26
+ export const RTLDiff: Story = {
27
+ render: () => (
28
+ <>
29
+ <div style={{ marginBottom: 32 }}>
30
+ <h4>Block width — first tab selected</h4>
31
+ <Tabs
32
+ name="rtl-block-first"
33
+ tabs={defaultTabs}
34
+ selected={0}
35
+ headerWidth={Width.BLOCK}
36
+ onTabSelect={() => {}}
37
+ />
38
+ </div>
39
+ <div style={{ marginBottom: 32 }}>
40
+ <h4>Block width — second tab selected</h4>
41
+ <Tabs
42
+ name="rtl-block-second"
43
+ tabs={defaultTabs}
44
+ selected={1}
45
+ headerWidth={Width.BLOCK}
46
+ onTabSelect={() => {}}
47
+ />
48
+ </div>
49
+ <div style={{ marginBottom: 32 }}>
50
+ <h4>Auto width — first tab selected</h4>
51
+ <Tabs
52
+ name="rtl-auto-first"
53
+ tabs={defaultTabs}
54
+ selected={0}
55
+ headerWidth={Width.AUTO}
56
+ onTabSelect={() => {}}
57
+ />
58
+ </div>
59
+ <div style={{ marginBottom: 32 }}>
60
+ <h4>Auto width — second tab selected</h4>
61
+ <Tabs
62
+ name="rtl-auto-second"
63
+ tabs={defaultTabs}
64
+ selected={1}
65
+ headerWidth={Width.AUTO}
66
+ onTabSelect={() => {}}
67
+ />
68
+ </div>
69
+ </>
70
+ ),
71
+ ...withRTLDiff(),
72
+ };
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import TextareaWithDisplayFormat from '..';
5
+ import Field from '../../Field/Field';
6
+
7
+ export default {
8
+ component: TextareaWithDisplayFormat,
9
+ title: 'Forms/TextareaWithDisplayFormat/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof TextareaWithDisplayFormat>;
12
+
13
+ type Story = StoryObj<typeof TextareaWithDisplayFormat>;
14
+
15
+ export const RTLDiff: Story = {
16
+ render: () => (
17
+ <>
18
+ <Field id="card-code" label="Gift card code">
19
+ <TextareaWithDisplayFormat
20
+ id="card-code"
21
+ value="1234567890123456"
22
+ maxLength={16}
23
+ displayPattern="**** - **** - ****"
24
+ onChange={() => {}}
25
+ />
26
+ </Field>
27
+ <Field id="iban" label="IBAN">
28
+ <TextareaWithDisplayFormat
29
+ id="iban"
30
+ value="GB29NWBK60161331926819"
31
+ maxLength={22}
32
+ displayPattern="** **** **** **** **** **"
33
+ onChange={() => {}}
34
+ />
35
+ </Field>
36
+ <Field id="empty" label="Empty with placeholder">
37
+ <TextareaWithDisplayFormat
38
+ id="empty"
39
+ value=""
40
+ displayPattern="**** - **** - ****"
41
+ placeholder="Enter code"
42
+ onChange={() => {}}
43
+ />
44
+ </Field>
45
+ </>
46
+ ),
47
+ ...withRTLDiff(),
48
+ };
@@ -0,0 +1,79 @@
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 Tooltip from '../Tooltip';
7
+
8
+ export default {
9
+ component: Tooltip,
10
+ title: 'Dialogs/Tooltip/Tests/RTL Diff',
11
+ tags: ['!autodocs', '!manifest'],
12
+ } satisfies Meta<typeof Tooltip>;
13
+
14
+ type Story = StoryObj<typeof Tooltip>;
15
+
16
+ const iframeDiff = withRTLDiff({ renderAs: 'iframe' });
17
+
18
+ const containerStyle: React.CSSProperties = {
19
+ display: 'flex',
20
+ justifyContent: 'center',
21
+ alignItems: 'center',
22
+ minHeight: '20rem',
23
+ width: '100%',
24
+ };
25
+
26
+ const hoverTrigger = async ({ canvasElement }: { canvasElement: HTMLElement }) => {
27
+ const canvas = within(canvasElement);
28
+ const button = canvas.queryByRole('button');
29
+ if (!button) return;
30
+ await userEvent.hover(button);
31
+ };
32
+
33
+ export const PositionTop: Story = {
34
+ render: () => (
35
+ <div style={containerStyle}>
36
+ <Tooltip label="Top positioned tooltip" position="top">
37
+ <Button>Top</Button>
38
+ </Tooltip>
39
+ </div>
40
+ ),
41
+ play: hoverTrigger,
42
+ ...iframeDiff,
43
+ };
44
+
45
+ export const PositionBottom: Story = {
46
+ render: () => (
47
+ <div style={containerStyle}>
48
+ <Tooltip label="Bottom positioned tooltip" position="bottom">
49
+ <Button>Bottom</Button>
50
+ </Tooltip>
51
+ </div>
52
+ ),
53
+ play: hoverTrigger,
54
+ ...iframeDiff,
55
+ };
56
+
57
+ export const PositionRight: Story = {
58
+ render: () => (
59
+ <div style={containerStyle}>
60
+ <Tooltip label="Right positioned tooltip" position="right">
61
+ <Button>Right</Button>
62
+ </Tooltip>
63
+ </div>
64
+ ),
65
+ play: hoverTrigger,
66
+ ...iframeDiff,
67
+ };
68
+
69
+ export const PositionLeft: Story = {
70
+ render: () => (
71
+ <div style={containerStyle}>
72
+ <Tooltip label="Left positioned tooltip" position="left">
73
+ <Button>Left</Button>
74
+ </Tooltip>
75
+ </div>
76
+ ),
77
+ play: hoverTrigger,
78
+ ...iframeDiff,
79
+ };
@@ -0,0 +1,90 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { userEvent, within } from 'storybook/test';
3
+ import { Search as SearchIcon } from '@transferwise/icons';
4
+
5
+ import { forEachColumn, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
6
+ import { Size } from '../../common';
7
+ import Typeahead from '..';
8
+
9
+ export default {
10
+ component: Typeahead,
11
+ title: 'Forms/Typeahead/Tests/RTL Diff',
12
+ tags: ['!autodocs', '!manifest'],
13
+ } satisfies Meta<typeof Typeahead>;
14
+
15
+ type Story = StoryObj<typeof Typeahead>;
16
+
17
+ const baseOptions = [
18
+ { label: 'British pound', note: 'GBP' },
19
+ { label: 'Euro', note: 'EUR' },
20
+ { label: 'US Dollar', note: 'USD' },
21
+ ];
22
+
23
+ export const TriggerVariants: Story = {
24
+ render: () => (
25
+ <>
26
+ <Typeahead
27
+ id="rtl-addon-md"
28
+ name="rtl-addon-md"
29
+ placeholder="Search currencies…"
30
+ size={Size.MEDIUM}
31
+ addon={<SearchIcon size={24} />}
32
+ clearable
33
+ options={baseOptions}
34
+ initialValue={[{ label: 'British pound', note: 'GBP' }]}
35
+ onChange={() => {}}
36
+ />
37
+ <Typeahead
38
+ id="rtl-addon-lg"
39
+ name="rtl-addon-lg"
40
+ placeholder="Search currencies…"
41
+ size={Size.LARGE}
42
+ addon={<SearchIcon size={24} />}
43
+ clearable
44
+ options={baseOptions}
45
+ initialValue={[{ label: 'Euro', note: 'EUR' }]}
46
+ onChange={() => {}}
47
+ />
48
+ <Typeahead
49
+ id="rtl-multiple"
50
+ name="rtl-multiple"
51
+ placeholder="Search currencies…"
52
+ size={Size.MEDIUM}
53
+ addon={<SearchIcon size={24} />}
54
+ multiple
55
+ clearable
56
+ options={baseOptions}
57
+ initialValue={[
58
+ { label: 'British pound', note: 'GBP' },
59
+ { label: 'Euro', note: 'EUR' },
60
+ ]}
61
+ onChange={() => {}}
62
+ />
63
+ </>
64
+ ),
65
+ ...withRTLDiff({ width: '80%' }),
66
+ };
67
+
68
+ export const OpenDropdown: Story = {
69
+ render: () => (
70
+ <Typeahead
71
+ id="rtl-open"
72
+ name="rtl-open"
73
+ placeholder="Search currencies…"
74
+ size={Size.LARGE}
75
+ addon={<SearchIcon size={24} />}
76
+ clearable
77
+ options={baseOptions}
78
+ onChange={() => {}}
79
+ />
80
+ ),
81
+ play: async ({ canvasElement }) => {
82
+ await forEachColumn(canvasElement, async (column) => {
83
+ const scope = within(column);
84
+ const input = scope.getByRole('combobox');
85
+ await userEvent.click(input);
86
+ await userEvent.keyboard('Brit');
87
+ });
88
+ },
89
+ ...withRTLDiff({ width: '80%' }),
90
+ };
@@ -0,0 +1,53 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { userEvent, waitFor, within } from 'storybook/test';
3
+
4
+ import { forEachColumn, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
5
+ import Upload from '..';
6
+
7
+ export default {
8
+ component: Upload,
9
+ title: 'Forms/Upload/Tests/RTL Diff',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof Upload>;
12
+
13
+ type Story = StoryObj<typeof Upload>;
14
+
15
+ export const Sizes: Story = {
16
+ render: () => (
17
+ <>
18
+ <Upload usLabel="Small upload" size="sm" />
19
+ <Upload usLabel="Medium upload" size="md" />
20
+ <Upload usLabel="Large upload" size="lg" />
21
+ </>
22
+ ),
23
+ ...withRTLDiff(),
24
+ };
25
+
26
+ export const WithError: Story = {
27
+ render: () => (
28
+ <Upload
29
+ usAccept="*"
30
+ usLabel="Upload a file"
31
+ usPlaceholder="Maximum filesize is 1B"
32
+ maxSize={1}
33
+ size="md"
34
+ httpOptions={{
35
+ url: 'https://httpbin.org/post',
36
+ method: 'POST',
37
+ }}
38
+ />
39
+ ),
40
+ play: async ({ canvasElement }) => {
41
+ await forEachColumn(canvasElement, async (column) => {
42
+ const fileInput = column.querySelector<HTMLInputElement>('input[type="file"]');
43
+ if (!fileInput) return;
44
+ const file = new File(['content larger than 1 byte'], 'test-file.txt', {
45
+ type: 'text/plain',
46
+ });
47
+ await userEvent.upload(fileInput, file);
48
+ const scope = within(column);
49
+ await waitFor(async () => scope.findByText(/Maximum filesize is/i), { timeout: 3000 });
50
+ });
51
+ },
52
+ ...withRTLDiff(),
53
+ };
@@ -0,0 +1,59 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
4
+ import { Status } from '../../common';
5
+ import UploadInput from '../UploadInput';
6
+
7
+ export default {
8
+ component: UploadInput,
9
+ title: 'Forms/UploadInput/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof UploadInput>;
12
+
13
+ type Story = StoryObj<typeof UploadInput>;
14
+
15
+ const noOpUpload = async () => ({ id: 'upload-1' });
16
+ const noOpDelete = async () => {};
17
+
18
+ const mixedFiles = [
19
+ { id: 'file-1', filename: 'document-front.pdf', url: '#' },
20
+ { id: 'file-2', filename: 'succeeded-file.pdf', url: '#' },
21
+ { id: 'file-3', filename: 'failed-file.png', status: Status.FAILED },
22
+ { id: 'file-4', filename: 'valid-document.pdf', url: '#' },
23
+ {
24
+ id: 'file-5',
25
+ filename: 'too-large-image.png',
26
+ status: Status.FAILED,
27
+ errors: [
28
+ 'File size exceeds the 5MB limit',
29
+ 'Please compress the image or choose a smaller file',
30
+ 'Supported formats: JPG, PNG under 5MB',
31
+ ],
32
+ },
33
+ {
34
+ id: 'file-6',
35
+ filename: 'corrupted-file.pdf',
36
+ status: Status.FAILED,
37
+ error: 'File could not be processed',
38
+ },
39
+ ];
40
+
41
+ export const RTLDiff: Story = {
42
+ render: () => (
43
+ <>
44
+ <UploadInput onUploadFile={noOpUpload} />
45
+ <UploadInput
46
+ files={[{ id: 'file-s', filename: 'single-upload.pdf', url: '#' }]}
47
+ onUploadFile={noOpUpload}
48
+ onDeleteFile={noOpDelete}
49
+ />
50
+ <UploadInput
51
+ multiple
52
+ files={mixedFiles}
53
+ onUploadFile={noOpUpload}
54
+ onDeleteFile={noOpDelete}
55
+ />
56
+ </>
57
+ ),
58
+ ...withRTLDiff(),
59
+ };
@@ -0,0 +1,37 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
3
+ import Alert, { AlertArrowPosition } from '../Alert';
4
+
5
+ export default {
6
+ component: Alert,
7
+ title: 'Prompts/Alert/Tests',
8
+ tags: ['!autodocs', '!manifest'],
9
+ } satisfies Meta<typeof Alert>;
10
+
11
+ type Story = StoryObj<typeof Alert>;
12
+
13
+ export const RTLDiff: Story = {
14
+ render: () => (
15
+ <>
16
+ <Alert message="Basic alert without dismiss button." />
17
+ <Alert message="Alert with dismiss button." onDismiss={() => {}} />
18
+ <Alert
19
+ title="With title and link action"
20
+ message="Alert with a link action and dismiss."
21
+ action={{ href: '#', text: 'Read more' }}
22
+ onDismiss={() => {}}
23
+ />
24
+ <Alert
25
+ title="With title and button action"
26
+ message="Alert with a button action."
27
+ action={{ onClick: () => {}, text: 'Open', as: 'button' }}
28
+ onDismiss={() => {}}
29
+ />
30
+ <Alert message="Arrow top left." arrow={AlertArrowPosition.TOP_LEFT} />
31
+ <Alert message="Arrow top right." arrow={AlertArrowPosition.TOP_RIGHT} />
32
+ <Alert message="Arrow bottom left." arrow={AlertArrowPosition.BOTTOM_LEFT} />
33
+ <Alert message="Arrow bottom right." arrow={AlertArrowPosition.BOTTOM_RIGHT} />
34
+ </>
35
+ ),
36
+ ...withRTLDiff(),
37
+ };
@@ -0,0 +1,38 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { FastFlag as FastFlagIcon } from '@transferwise/icons';
3
+
4
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
5
+ import Card from '..';
6
+
7
+ export default {
8
+ component: Card,
9
+ title: 'Layouts/Card/Tests',
10
+ tags: ['!autodocs', '!manifest'],
11
+ } satisfies Meta<typeof Card>;
12
+
13
+ type Story = StoryObj<typeof Card>;
14
+
15
+ export const RTLDiff: Story = {
16
+ render: () => (
17
+ <>
18
+ <Card title="Basic card" details="Some details about this card" />
19
+ <Card
20
+ title="Card with icon"
21
+ details="Details with an icon on the side"
22
+ icon={<FastFlagIcon />}
23
+ />
24
+ <Card
25
+ title="Expanded card with icon"
26
+ details="Expanded card showing content area"
27
+ icon={<FastFlagIcon />}
28
+ isExpanded
29
+ >
30
+ Expanded content with padding affected by icon presence.
31
+ </Card>
32
+ <Card title="Expanded card without icon" details="No icon variant" isExpanded>
33
+ Expanded content without icon padding.
34
+ </Card>
35
+ </>
36
+ ),
37
+ ...withRTLDiff(),
38
+ };
@@ -0,0 +1,28 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
3
+ import CriticalCommsBanner from '..';
4
+
5
+ export default {
6
+ component: CriticalCommsBanner,
7
+ title: 'Prompts/CriticalCommsBanner/Tests',
8
+ tags: ['!autodocs', '!manifest'],
9
+ } satisfies Meta<typeof CriticalCommsBanner>;
10
+
11
+ type Story = StoryObj<typeof CriticalCommsBanner>;
12
+
13
+ export const RTLDiff: Story = {
14
+ render: () => (
15
+ <>
16
+ <CriticalCommsBanner
17
+ title="Your account is overdrawn"
18
+ subtitle="Add money within the next 30 days"
19
+ action={{ label: 'Take action', href: 'https://wise.com' }}
20
+ />
21
+ <CriticalCommsBanner
22
+ title="Your account is overdrawn"
23
+ subtitle="Add money within the next 30 days"
24
+ />
25
+ </>
26
+ ),
27
+ ...withRTLDiff(),
28
+ };
@@ -0,0 +1,26 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
4
+ import InlineAlert from '..';
5
+
6
+ export default {
7
+ component: InlineAlert,
8
+ title: 'Prompts/InlineAlert/Tests',
9
+ tags: ['!autodocs', '!manifest'],
10
+ } satisfies Meta<typeof InlineAlert>;
11
+
12
+ type Story = StoryObj<typeof InlineAlert>;
13
+
14
+ export const RTLDiff: Story = {
15
+ render: () => (
16
+ <>
17
+ <InlineAlert type="neutral">Neutral alert without icon</InlineAlert>
18
+ <InlineAlert type="warning">Warning alert with icon</InlineAlert>
19
+ <InlineAlert type="negative">Negative alert with icon</InlineAlert>
20
+ <InlineAlert type="positive">
21
+ Positive alert with icon and longer content that may wrap to multiple lines
22
+ </InlineAlert>
23
+ </>
24
+ ),
25
+ ...withRTLDiff(),
26
+ };
@@ -0,0 +1,42 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { Person } from '@transferwise/icons';
3
+
4
+ import { withRTLDiff } from '../../../../.storybook/decorators/RtlDiffDecorator';
5
+ import AvatarView from '../../../AvatarView';
6
+ import Logo from '../../../Logo';
7
+ import OverlayHeader from '..';
8
+
9
+ export default {
10
+ component: OverlayHeader,
11
+ title: 'Navigation/OverlayHeader/Tests',
12
+ tags: ['!autodocs', '!manifest'],
13
+ } satisfies Meta<typeof OverlayHeader>;
14
+
15
+ type Story = StoryObj<typeof OverlayHeader>;
16
+
17
+ export const RTLDiff: Story = {
18
+ render: () => (
19
+ <>
20
+ <OverlayHeader logo={<Logo />} onClose={() => {}} />
21
+ <OverlayHeader
22
+ logo={<Logo />}
23
+ avatar={
24
+ <AvatarView>
25
+ <Person size="24" />
26
+ </AvatarView>
27
+ }
28
+ onClose={() => {}}
29
+ />
30
+ <OverlayHeader
31
+ logo={<Logo />}
32
+ avatar={
33
+ <AvatarView>
34
+ <Person size="24" />
35
+ </AvatarView>
36
+ }
37
+ />
38
+ <OverlayHeader logo={<Logo />} />
39
+ </>
40
+ ),
41
+ ...withRTLDiff(),
42
+ };