@transferwise/components 46.158.0 → 46.159.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/FlowNavigation/FlowNavigation.js +5 -14
- package/build/FlowNavigation/FlowNavigation.js.map +1 -1
- package/build/FlowNavigation/FlowNavigation.mjs +5 -14
- package/build/FlowNavigation/FlowNavigation.mjs.map +1 -1
- package/build/_deprecated/OverlayHeader/OverlayHeader.js +6 -41
- package/build/_deprecated/OverlayHeader/OverlayHeader.js.map +1 -1
- package/build/_deprecated/OverlayHeader/OverlayHeader.mjs +6 -41
- package/build/_deprecated/OverlayHeader/OverlayHeader.mjs.map +1 -1
- package/build/i18n/cs.json +5 -0
- package/build/i18n/cs.json.js +5 -0
- package/build/i18n/cs.json.js.map +1 -1
- package/build/i18n/cs.json.mjs +5 -0
- package/build/i18n/cs.json.mjs.map +1 -1
- package/build/i18n/de.json +5 -0
- package/build/i18n/de.json.js +5 -0
- package/build/i18n/de.json.js.map +1 -1
- package/build/i18n/de.json.mjs +5 -0
- package/build/i18n/de.json.mjs.map +1 -1
- package/build/i18n/es.json +5 -0
- package/build/i18n/es.json.js +5 -0
- package/build/i18n/es.json.js.map +1 -1
- package/build/i18n/es.json.mjs +5 -0
- package/build/i18n/es.json.mjs.map +1 -1
- package/build/i18n/fr.json +5 -0
- package/build/i18n/fr.json.js +5 -0
- package/build/i18n/fr.json.js.map +1 -1
- package/build/i18n/fr.json.mjs +5 -0
- package/build/i18n/fr.json.mjs.map +1 -1
- package/build/i18n/hu.json +5 -0
- package/build/i18n/hu.json.js +5 -0
- package/build/i18n/hu.json.js.map +1 -1
- package/build/i18n/hu.json.mjs +5 -0
- package/build/i18n/hu.json.mjs.map +1 -1
- package/build/i18n/id.json +5 -0
- package/build/i18n/id.json.js +5 -0
- package/build/i18n/id.json.js.map +1 -1
- package/build/i18n/id.json.mjs +5 -0
- package/build/i18n/id.json.mjs.map +1 -1
- package/build/i18n/it.json +5 -0
- package/build/i18n/it.json.js +5 -0
- package/build/i18n/it.json.js.map +1 -1
- package/build/i18n/it.json.mjs +5 -0
- package/build/i18n/it.json.mjs.map +1 -1
- package/build/i18n/ja.json +5 -0
- package/build/i18n/ja.json.js +5 -0
- package/build/i18n/ja.json.js.map +1 -1
- package/build/i18n/ja.json.mjs +5 -0
- package/build/i18n/ja.json.mjs.map +1 -1
- package/build/i18n/nl.json +5 -0
- package/build/i18n/nl.json.js +5 -0
- package/build/i18n/nl.json.js.map +1 -1
- package/build/i18n/nl.json.mjs +5 -0
- package/build/i18n/nl.json.mjs.map +1 -1
- package/build/i18n/pl.json +5 -0
- package/build/i18n/pl.json.js +5 -0
- package/build/i18n/pl.json.js.map +1 -1
- package/build/i18n/pl.json.mjs +5 -0
- package/build/i18n/pl.json.mjs.map +1 -1
- package/build/i18n/pt.json +5 -0
- package/build/i18n/pt.json.js +5 -0
- package/build/i18n/pt.json.js.map +1 -1
- package/build/i18n/pt.json.mjs +5 -0
- package/build/i18n/pt.json.mjs.map +1 -1
- package/build/i18n/ro.json +5 -0
- package/build/i18n/ro.json.js +5 -0
- package/build/i18n/ro.json.js.map +1 -1
- package/build/i18n/ro.json.mjs +5 -0
- package/build/i18n/ro.json.mjs.map +1 -1
- package/build/i18n/ru.json +5 -0
- package/build/i18n/ru.json.js +5 -0
- package/build/i18n/ru.json.js.map +1 -1
- package/build/i18n/ru.json.mjs +5 -0
- package/build/i18n/ru.json.mjs.map +1 -1
- package/build/i18n/th.json +5 -0
- package/build/i18n/th.json.js +5 -0
- package/build/i18n/th.json.js.map +1 -1
- package/build/i18n/th.json.mjs +5 -0
- package/build/i18n/th.json.mjs.map +1 -1
- package/build/i18n/uk.json +5 -0
- package/build/i18n/uk.json.js +5 -0
- package/build/i18n/uk.json.js.map +1 -1
- package/build/i18n/uk.json.mjs +5 -0
- package/build/i18n/uk.json.mjs.map +1 -1
- package/build/i18n/zh-HK.json +5 -0
- package/build/i18n/zh-HK.json.js +5 -0
- package/build/i18n/zh-HK.json.js.map +1 -1
- package/build/i18n/zh-HK.json.mjs +5 -0
- package/build/i18n/zh-HK.json.mjs.map +1 -1
- package/build/main.css +19 -4145
- package/build/styles/FlowNavigation/FlowNavigation.css +7 -13
- package/build/styles/ListItem/ListItem.css +1 -0
- package/build/styles/PocketSurface/PocketSurface.css +2 -11
- package/build/styles/SentimentSurface/SentimentSurface.css +0 -23
- package/build/styles/css/neptune.css +0 -2821
- package/build/styles/main.css +19 -4145
- package/build/styles/styles/less/neptune.css +0 -2821
- package/build/types/FlowNavigation/FlowNavigation.d.ts +2 -9
- package/build/types/FlowNavigation/FlowNavigation.d.ts.map +1 -1
- package/build/types/ListItem/_stories/variants/helpers.d.ts.map +1 -1
- package/build/types/_deprecated/OverlayHeader/OverlayHeader.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/Accordion/_stories/Accordion.test.story.tsx +71 -0
- package/src/AvatarLayout/_stories/AvatarLayout.test.story.tsx +64 -0
- package/src/AvatarView/_stories/AvatarView.test.story.tsx +151 -0
- package/src/Button/LegacyButton/_stories/LegacyButton.test.story.tsx +22 -0
- package/src/Button/_stories/Button.test.story.tsx +65 -0
- package/src/Calendar/_stories/Calendar.test.story.tsx +73 -24
- package/src/Carousel/_stories/Carousel.test.story.tsx +59 -0
- package/src/Checkbox/_stories/Checkbox.test.story.tsx +20 -0
- package/src/CheckboxButton/_stories/CheckboxButton.test.story.tsx +17 -37
- package/src/Chevron/_stories/Chevron.test.story.tsx +26 -0
- package/src/Chips/_stories/Chips.test.story.tsx +39 -34
- package/src/CircularButton/_stories/CircularButton.test.story.tsx +0 -68
- package/src/DateInput/_stories/DateInput.test.story.tsx +13 -0
- package/src/DateLookup/_stories/DateLookup.rtl.test.story.tsx +88 -0
- package/src/Decision/_stories/Decision.test.story.tsx +79 -0
- package/src/DefinitionList/_stories/DefinitionList.test.story.tsx +54 -1
- package/src/Drawer/_stories/Drawer.rtl.test.story.tsx +58 -0
- package/src/ExpressiveMoneyInput/_stories/ExpressiveMoneyInput.rtl.test.story.tsx +118 -0
- package/src/Field/_stories/Field.test.story.tsx +46 -0
- package/src/FlowNavigation/FlowNavigation.css +7 -13
- package/src/FlowNavigation/FlowNavigation.less +6 -15
- package/src/FlowNavigation/FlowNavigation.tsx +6 -27
- package/src/FlowNavigation/_stories/FlowNavigation.story.tsx +0 -86
- package/src/FlowNavigation/_stories/FlowNavigation.test.story.tsx +44 -0
- package/src/Header/_stories/Header.test.story.tsx +27 -0
- package/src/Info/_stories/Info.rtl.test.story.tsx +64 -0
- package/src/Inputs/SelectInput/_stories/SelectInput.rtl.test.story.tsx +135 -0
- package/src/Inputs/_stories/InputGroup.test.story.tsx +69 -0
- package/src/Inputs/_stories/SearchInput.test.story.tsx +32 -0
- package/src/Inputs/_stories/TextArea.test.story.tsx +27 -0
- package/src/InstructionsList/_stories/InstructionsList.test.story.tsx +30 -0
- package/src/Label/_stories/Label.test.story.tsx +36 -0
- package/src/Link/_stories/Link.test.story.tsx +26 -0
- package/src/ListItem/ListItem.css +1 -0
- package/src/ListItem/_stories/{variants/ListItem.rtl.test.story.tsx → ListItem.rtl.test.story.tsx} +6 -10
- package/src/ListItem/_stories/variants/helpers.tsx +2 -6
- package/src/Logo/_stories/Logo.test.story.tsx +44 -0
- package/src/Modal/_stories/Modal.rtl.test.story.tsx +59 -0
- package/src/MoneyInput/_stories/MoneyInput.rtl.test.story.tsx +88 -0
- package/src/Nudge/_stories/Nudge.test.story.tsx +37 -0
- package/src/PhoneNumberInput/_stories/PhoneNumberInput.test.story.tsx +44 -0
- package/src/PocketSurface/PocketSurface.css +2 -11
- package/src/PocketSurface/PocketSurface.less +1 -1
- package/src/Popover/_stories/Popover.rtl.test.story.tsx +96 -0
- package/src/Progress/_stories/Progress.test.story.tsx +27 -0
- package/src/ProgressBar/_stories/ProgressBar.test.story.tsx +33 -0
- package/src/PromoCard/_stories/PromoCard.test.story.tsx +42 -0
- package/src/PromoCard/_stories/PromoCardGroup.test.story.tsx +51 -0
- package/src/Prompt/ActionPrompt/_stories/ActionPrompt.test.story.tsx +42 -1
- package/src/Prompt/CriticalBanner/_stories/CriticalBanner.test.story.tsx +34 -31
- package/src/Prompt/InfoPrompt/_stories/InfoPrompt.test.story.tsx +25 -0
- package/src/Prompt/InlinePrompt/_stories/InlinePrompt.test.story.tsx +27 -0
- package/src/Radio/_stories/Radio.test.story.tsx +61 -0
- package/src/RadioGroup/_stories/RadioGroup.test.story.tsx +56 -0
- package/src/Section/_stories/Section.test.story.tsx +29 -0
- package/src/SegmentedControl/_stories/SegmentedControl.test.story.tsx +45 -0
- package/src/SentimentSurface/SentimentSurface.css +0 -23
- package/src/SlidingPanel/_stories/SlidingPanel.rtl.test.story.tsx +70 -0
- package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +45 -0
- package/src/Snackbar/_stories/Snackbar.test.story.tsx +0 -31
- package/src/Stepper/_stories/Stepper.test.story.tsx +17 -0
- package/src/Switch/_stories/Switch.test.story.tsx +20 -26
- package/src/Table/_stories/Table.test.story.tsx +104 -0
- package/src/Tabs/_stories/Tabs.test.story.tsx +72 -0
- package/src/TextareaWithDisplayFormat/_stories/TextareaWithDisplayFormat.test.story.tsx +48 -0
- package/src/Tooltip/_stories/Tooltip.rtl.test.story.tsx +79 -0
- package/src/Typeahead/_stories/Typeahead.rtl.test.story.tsx +90 -0
- package/src/Upload/_stories/Upload.rtl.test.story.tsx +53 -0
- package/src/UploadInput/_stories/UploadInput.test.story.tsx +47 -0
- package/src/_deprecated/Alert/_stories/Alert.test.story.tsx +28 -1
- package/src/_deprecated/Card/_stories/Card.test.story.tsx +38 -0
- package/src/_deprecated/CriticalBanner/_stories/CriticalCommsBanner.test.story.tsx +18 -0
- package/src/_deprecated/InlineAlert/_stories/InlineAlert.test.story.tsx +26 -0
- package/src/_deprecated/OverlayHeader/OverlayHeader.tsx +2 -21
- package/src/_deprecated/OverlayHeader/_stories/OverlayHeader.test.story.tsx +42 -0
- package/src/_deprecated/Select/_stories/Select.rtl.test.story.tsx +71 -0
- package/src/common/BottomSheet/_stories/BottomSheet.test.story.tsx +23 -0
- package/src/common/Panel/_stories/Panel.story.tsx +107 -36
- package/src/i18n/cs.json +5 -0
- package/src/i18n/de.json +5 -0
- package/src/i18n/es.json +5 -0
- package/src/i18n/fr.json +5 -0
- package/src/i18n/hu.json +5 -0
- package/src/i18n/id.json +5 -0
- package/src/i18n/it.json +5 -0
- package/src/i18n/ja.json +5 -0
- package/src/i18n/nl.json +5 -0
- package/src/i18n/pl.json +5 -0
- package/src/i18n/pt.json +5 -0
- package/src/i18n/ro.json +5 -0
- package/src/i18n/ru.json +5 -0
- package/src/i18n/th.json +5 -0
- package/src/i18n/uk.json +5 -0
- package/src/i18n/zh-HK.json +5 -0
- package/src/main.css +19 -4145
- package/src/main.less +0 -1
- package/src/styles/less/neptune.css +0 -2821
- package/build/styles/_deprecated/OverlayHeader/OverlayHeader.css +0 -15
- package/src/_deprecated/OverlayHeader/OverlayHeader.css +0 -15
- package/src/_deprecated/OverlayHeader/OverlayHeader.less +0 -24
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { fn, userEvent, within } from 'storybook/test';
|
|
3
|
+
import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
|
|
4
|
+
import ExpressiveMoneyInput from '..';
|
|
5
|
+
import { Rewards } from '@transferwise/icons';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
component: ExpressiveMoneyInput,
|
|
9
|
+
title: 'Forms/ExpressiveMoneyInput/Tests/RTL Diff',
|
|
10
|
+
tags: ['!autodocs', '!manifest'],
|
|
11
|
+
} satisfies Meta<typeof ExpressiveMoneyInput>;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof ExpressiveMoneyInput>;
|
|
14
|
+
|
|
15
|
+
const currencySelectorOptions = [
|
|
16
|
+
{
|
|
17
|
+
title: 'Popular',
|
|
18
|
+
currencies: [
|
|
19
|
+
{ code: 'GBP', label: 'British Pound', keywords: ['british'] },
|
|
20
|
+
{ code: 'EUR', label: 'Euro', keywords: ['euro'] },
|
|
21
|
+
{ code: 'USD', label: 'US Dollar', keywords: ['dollar'] },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
|
|
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
|
+
/>
|
|
42
|
+
|
|
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
|
+
/>
|
|
57
|
+
|
|
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
|
+
/>
|
|
76
|
+
|
|
77
|
+
{/* Secondary avatar addon in currency selector */}
|
|
78
|
+
<ExpressiveMoneyInput
|
|
79
|
+
label="You send"
|
|
80
|
+
currency="GBP"
|
|
81
|
+
amount={750}
|
|
82
|
+
currencySelector={{
|
|
83
|
+
options: currencySelectorOptions,
|
|
84
|
+
addons: [{ profileName: 'Mikkael Jordan' }],
|
|
85
|
+
onChange: fn(),
|
|
86
|
+
onSearchChange: fn(),
|
|
87
|
+
onOpen: fn(),
|
|
88
|
+
}}
|
|
89
|
+
onAmountChange={fn()}
|
|
90
|
+
/>
|
|
91
|
+
</>
|
|
92
|
+
),
|
|
93
|
+
...withRTLDiff({ 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
|
+
),
|
|
111
|
+
play: async ({ canvasElement }) => {
|
|
112
|
+
const canvas = within(canvasElement);
|
|
113
|
+
const trigger = canvas.queryByRole('combobox');
|
|
114
|
+
if (!trigger) return;
|
|
115
|
+
await userEvent.click(trigger);
|
|
116
|
+
},
|
|
117
|
+
...withRTLDiff({ renderAs: 'iframe', width: '80%' }),
|
|
118
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
3
|
+
import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
|
|
3
4
|
import { Input } from '../../Inputs/Input/Input';
|
|
5
|
+
import { TextArea } from '../../Inputs/TextArea/TextArea';
|
|
6
|
+
import { lorem10 } from '../../test-utils';
|
|
4
7
|
import Field, { FieldProps } from '..';
|
|
5
8
|
import { Sentiment } from '../../common';
|
|
6
9
|
|
|
@@ -54,3 +57,46 @@ export const DeprecatedProps: Story = {
|
|
|
54
57
|
);
|
|
55
58
|
},
|
|
56
59
|
};
|
|
60
|
+
|
|
61
|
+
export const RTLDiff: Story = {
|
|
62
|
+
render: () => (
|
|
63
|
+
<>
|
|
64
|
+
{/* Required label (default) — label text aligns to start */}
|
|
65
|
+
<Field label="Required field">
|
|
66
|
+
<Input defaultValue="Input value" />
|
|
67
|
+
</Field>
|
|
68
|
+
|
|
69
|
+
{/* Optional label — "(optional)" suffix uses directional margin-left */}
|
|
70
|
+
<Field label="Optional field" required={false}>
|
|
71
|
+
<Input defaultValue="Input value" />
|
|
72
|
+
</Field>
|
|
73
|
+
|
|
74
|
+
{/* Label + description + message — full vertical layout with directional icon */}
|
|
75
|
+
<Field
|
|
76
|
+
label="Field with description and message"
|
|
77
|
+
required={false}
|
|
78
|
+
description={lorem10}
|
|
79
|
+
message="This is a validation message"
|
|
80
|
+
sentiment="negative"
|
|
81
|
+
>
|
|
82
|
+
<Input defaultValue="Input value" />
|
|
83
|
+
</Field>
|
|
84
|
+
|
|
85
|
+
{/* Message only (no label) — InlinePrompt icon+text layout visible */}
|
|
86
|
+
<Field message="A helpful message" sentiment="positive">
|
|
87
|
+
<Input defaultValue="Input value" />
|
|
88
|
+
</Field>
|
|
89
|
+
|
|
90
|
+
{/* Loading message — spinner replaces icon but layout structure is identical */}
|
|
91
|
+
<Field label="Field with loading message" message="Saving…" messageLoading>
|
|
92
|
+
<Input defaultValue="Input value" />
|
|
93
|
+
</Field>
|
|
94
|
+
|
|
95
|
+
{/* Textarea with char counter — counter uses text-align:right + margin-left:auto */}
|
|
96
|
+
<Field label="Textarea with char counter" required={false} description="Max 100 characters">
|
|
97
|
+
<TextArea maxLength={100} defaultValue="Textarea value" />
|
|
98
|
+
</Field>
|
|
99
|
+
</>
|
|
100
|
+
),
|
|
101
|
+
...withRTLDiff(),
|
|
102
|
+
};
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
justify-content: center;
|
|
5
5
|
width: 100%;
|
|
6
6
|
box-sizing: border-box;
|
|
7
|
-
min-height:
|
|
7
|
+
min-height: 80px;
|
|
8
|
+
}
|
|
9
|
+
@media (min-width: 320.02px) {
|
|
10
|
+
.np-flow-navigation {
|
|
11
|
+
min-height: 128px;
|
|
12
|
+
}
|
|
8
13
|
}
|
|
9
14
|
.np-flow-navigation--border-bottom {
|
|
10
15
|
border-bottom: 1px solid rgba(0,0,0,0.10196);
|
|
@@ -13,7 +18,7 @@
|
|
|
13
18
|
.np-flow-navigation__content {
|
|
14
19
|
width: 100%;
|
|
15
20
|
min-width: 320px;
|
|
16
|
-
max-width:
|
|
21
|
+
max-width: none;
|
|
17
22
|
}
|
|
18
23
|
.np-flow-navigation__stepper {
|
|
19
24
|
padding-bottom: 0 !important;
|
|
@@ -72,17 +77,6 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
72
77
|
.np-flow-navigation--hidden {
|
|
73
78
|
visibility: hidden;
|
|
74
79
|
}
|
|
75
|
-
.np-flow-navigation--composable {
|
|
76
|
-
min-height: 80px;
|
|
77
|
-
}
|
|
78
|
-
@media (min-width: 320.02px) {
|
|
79
|
-
.np-flow-navigation--composable {
|
|
80
|
-
min-height: 128px;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
.np-flow-navigation--composable .np-flow-navigation__content {
|
|
84
|
-
max-width: none;
|
|
85
|
-
}
|
|
86
80
|
.np-theme-personal--forest-green .np-flow-navigation .np-flow-header__left path,
|
|
87
81
|
.np-theme-personal--bright-green .np-flow-navigation .np-flow-header__left path,
|
|
88
82
|
.np-theme-personal--dark .np-flow-navigation .np-flow-header__left path {
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
box-sizing: border-box;
|
|
10
10
|
|
|
11
11
|
// This is the natural height of FlowNavigation when the Avatar is displayed.
|
|
12
|
-
min-height:
|
|
12
|
+
min-height: 80px;
|
|
13
|
+
|
|
14
|
+
@media (--screen-xs) {
|
|
15
|
+
min-height: 128px;
|
|
16
|
+
}
|
|
13
17
|
|
|
14
18
|
&--border-bottom {
|
|
15
19
|
border-bottom: 1px solid var(--color-border-neutral);
|
|
@@ -18,7 +22,7 @@
|
|
|
18
22
|
&__content {
|
|
19
23
|
width: 100%;
|
|
20
24
|
min-width: 320px;
|
|
21
|
-
max-width:
|
|
25
|
+
max-width: none;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
&__stepper {
|
|
@@ -69,19 +73,6 @@
|
|
|
69
73
|
visibility: hidden;
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
&--composable {
|
|
73
|
-
min-height: 80px;
|
|
74
|
-
|
|
75
|
-
@media (--screen-xs) {
|
|
76
|
-
min-height: 128px;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.np-flow-navigation__content {
|
|
80
|
-
// Remove max-width constraint for fluid layout
|
|
81
|
-
max-width: none;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
76
|
.np-theme-personal--forest-green &,
|
|
86
77
|
.np-theme-personal--bright-green &,
|
|
87
78
|
.np-theme-personal--dark & {
|
|
@@ -26,20 +26,13 @@ export interface FlowNavigationProps {
|
|
|
26
26
|
/** @default false */
|
|
27
27
|
done?: boolean;
|
|
28
28
|
/** Called when the close button is clicked. If not provided the close button won't show */
|
|
29
|
-
onClose?: () => void
|
|
29
|
+
onClose?: (() => void) | React.MouseEventHandler<HTMLButtonElement>;
|
|
30
30
|
/** Called when the back button is clicked. If not provided the back button won't show. The back button only shows on small screens */
|
|
31
31
|
onGoBack?: () => void;
|
|
32
32
|
/** Steps to be displayed in stepper. If not provided, the stepper won't show. */
|
|
33
33
|
steps?: readonly Step[];
|
|
34
|
-
/**
|
|
35
|
-
* When true, renders in composable mode using a fluid Container.
|
|
36
|
-
* This allows the FlowNavigation to be used within custom layout containers.
|
|
37
|
-
* @default false
|
|
38
|
-
*/
|
|
39
|
-
composable?: boolean;
|
|
40
34
|
/**
|
|
41
35
|
* Controls whether the bottom border is displayed.
|
|
42
|
-
* Only applies to the composable variant. Non-composable variant always uses the done state.
|
|
43
36
|
* @default true
|
|
44
37
|
*/
|
|
45
38
|
showBottomBorder?: boolean;
|
|
@@ -53,7 +46,6 @@ const FlowNavigation = ({
|
|
|
53
46
|
onClose,
|
|
54
47
|
onGoBack,
|
|
55
48
|
steps,
|
|
56
|
-
composable = false,
|
|
57
49
|
showBottomBorder = true,
|
|
58
50
|
}: FlowNavigationProps) => {
|
|
59
51
|
const intl = useIntl();
|
|
@@ -69,7 +61,6 @@ const FlowNavigation = ({
|
|
|
69
61
|
<FlowHeader
|
|
70
62
|
className={clsx(
|
|
71
63
|
'np-flow-navigation__content',
|
|
72
|
-
!composable && 'p-x-3',
|
|
73
64
|
screenSm == null
|
|
74
65
|
? 'np-flow-navigation--hidden'
|
|
75
66
|
: {
|
|
@@ -119,27 +110,15 @@ const FlowNavigation = ({
|
|
|
119
110
|
/>
|
|
120
111
|
);
|
|
121
112
|
|
|
122
|
-
if (composable) {
|
|
123
|
-
return (
|
|
124
|
-
<Container
|
|
125
|
-
size="fluid"
|
|
126
|
-
className={clsx('np-flow-navigation np-flow-navigation--composable', {
|
|
127
|
-
'np-flow-navigation--border-bottom': showBottomBorder,
|
|
128
|
-
})}
|
|
129
|
-
>
|
|
130
|
-
{flowHeaderContent}
|
|
131
|
-
</Container>
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
113
|
return (
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
-
|
|
114
|
+
<Container
|
|
115
|
+
size="fluid"
|
|
116
|
+
className={clsx('np-flow-navigation', {
|
|
117
|
+
'np-flow-navigation--border-bottom': showBottomBorder,
|
|
139
118
|
})}
|
|
140
119
|
>
|
|
141
120
|
{flowHeaderContent}
|
|
142
|
-
</
|
|
121
|
+
</Container>
|
|
143
122
|
);
|
|
144
123
|
};
|
|
145
124
|
|
|
@@ -384,89 +384,6 @@ export const WithOverlayHeaderComparison: Story = {
|
|
|
384
384
|
},
|
|
385
385
|
};
|
|
386
386
|
|
|
387
|
-
export const ComposableVariant: Story = {
|
|
388
|
-
args: {
|
|
389
|
-
profileType: ProfileType.PERSONAL,
|
|
390
|
-
showCloseButton: true,
|
|
391
|
-
showMobileBackButton: true,
|
|
392
|
-
done: false,
|
|
393
|
-
avatarURL: '../tapestry-01.png',
|
|
394
|
-
},
|
|
395
|
-
parameters: {
|
|
396
|
-
padding: '0',
|
|
397
|
-
chromatic: {
|
|
398
|
-
viewports,
|
|
399
|
-
},
|
|
400
|
-
},
|
|
401
|
-
render: (args) => {
|
|
402
|
-
const [activeStep, setActiveStep] = useState(2);
|
|
403
|
-
const steps = [
|
|
404
|
-
{
|
|
405
|
-
label: 'Recipient',
|
|
406
|
-
onClick: () => setActiveStep(0),
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
label: 'Amount',
|
|
410
|
-
hoverLabel: (
|
|
411
|
-
<>
|
|
412
|
-
You send 100 GBP <br />
|
|
413
|
-
You get 99.39 GBP{' '}
|
|
414
|
-
</>
|
|
415
|
-
),
|
|
416
|
-
...(activeStep > 1 && { onClick: () => setActiveStep(1) }),
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
label: 'Review',
|
|
420
|
-
...(activeStep > 2 && { onClick: () => setActiveStep(2) }),
|
|
421
|
-
},
|
|
422
|
-
{
|
|
423
|
-
label: 'Pay',
|
|
424
|
-
...(activeStep > 3 && { onClick: () => setActiveStep(3) }),
|
|
425
|
-
},
|
|
426
|
-
];
|
|
427
|
-
return (
|
|
428
|
-
<>
|
|
429
|
-
<FlowNavigation
|
|
430
|
-
composable
|
|
431
|
-
avatar={<AvatarView profileType={args.profileType} />}
|
|
432
|
-
logo={<Logo />}
|
|
433
|
-
activeStep={activeStep}
|
|
434
|
-
steps={steps}
|
|
435
|
-
onClose={args.showCloseButton ? () => alert('close') : undefined}
|
|
436
|
-
onGoBack={
|
|
437
|
-
args.showMobileBackButton
|
|
438
|
-
? () => setActiveStep(activeStep > 0 ? activeStep - 1 : 0)
|
|
439
|
-
: undefined
|
|
440
|
-
}
|
|
441
|
-
/>
|
|
442
|
-
<Container size="narrow">
|
|
443
|
-
<Body className="m-a-3">
|
|
444
|
-
<Display type={Typography.DISPLAY_SMALL}>{steps[activeStep].label} Step</Display>
|
|
445
|
-
<br />
|
|
446
|
-
{lorem10}
|
|
447
|
-
</Body>
|
|
448
|
-
</Container>
|
|
449
|
-
|
|
450
|
-
<Sticky>
|
|
451
|
-
<Container
|
|
452
|
-
size="narrow"
|
|
453
|
-
className="d-flex justify-content-center align-items-center p-y-3"
|
|
454
|
-
>
|
|
455
|
-
<Button
|
|
456
|
-
v2
|
|
457
|
-
disabled={activeStep === 3}
|
|
458
|
-
block
|
|
459
|
-
onClick={() => setActiveStep(activeStep + 1)}
|
|
460
|
-
>
|
|
461
|
-
Continue
|
|
462
|
-
</Button>
|
|
463
|
-
</Container>
|
|
464
|
-
</Sticky>
|
|
465
|
-
</>
|
|
466
|
-
);
|
|
467
|
-
},
|
|
468
|
-
};
|
|
469
|
-
|
|
470
387
|
export const WithoutStepper: Story = {
|
|
471
388
|
args: {
|
|
472
389
|
profileType: ProfileType.PERSONAL,
|
|
@@ -575,7 +492,6 @@ export const BorderControl: Story = {
|
|
|
575
492
|
|
|
576
493
|
{/* Composable: showBottomBorder=true, done=false - SHOWS BORDER */}
|
|
577
494
|
<FlowNavigation
|
|
578
|
-
composable
|
|
579
495
|
avatar={<AvatarView profileType={args.profileType} />}
|
|
580
496
|
logo={<Logo />}
|
|
581
497
|
activeStep={activeStep}
|
|
@@ -591,7 +507,6 @@ export const BorderControl: Story = {
|
|
|
591
507
|
|
|
592
508
|
{/* Composable: showBottomBorder=true, done=true - SHOWS BORDER */}
|
|
593
509
|
<FlowNavigation
|
|
594
|
-
composable
|
|
595
510
|
avatar={<AvatarView profileType={args.profileType} />}
|
|
596
511
|
logo={<Logo />}
|
|
597
512
|
activeStep={activeStep}
|
|
@@ -607,7 +522,6 @@ export const BorderControl: Story = {
|
|
|
607
522
|
|
|
608
523
|
{/* Composable: showBottomBorder=false, done=false - HIDES BORDER */}
|
|
609
524
|
<FlowNavigation
|
|
610
|
-
composable
|
|
611
525
|
avatar={<AvatarView profileType={args.profileType} />}
|
|
612
526
|
logo={<Logo />}
|
|
613
527
|
activeStep={activeStep}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
2
|
|
|
3
|
+
import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
|
|
3
4
|
import AvatarView from '../../AvatarView';
|
|
4
5
|
import { ProfileType } from '../../common';
|
|
5
6
|
import Logo from '../../Logo';
|
|
@@ -76,3 +77,46 @@ export const LongLabel: Story = {
|
|
|
76
77
|
/>
|
|
77
78
|
),
|
|
78
79
|
};
|
|
80
|
+
|
|
81
|
+
const rtlSteps = [
|
|
82
|
+
{ label: 'Amount', hoverLabel: '100 GBP', onClick: noop },
|
|
83
|
+
{ label: 'You', hoverLabel: 'Elena Durante', onClick: noop },
|
|
84
|
+
{ label: 'Review', onClick: noop },
|
|
85
|
+
{ label: 'Pay', onClick: noop },
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* FlowNavigation has directional layout: back button on inline-start,
|
|
90
|
+
* close button and avatar on inline-end, and a stepper progress bar that
|
|
91
|
+
* flows in the reading direction. All of these flip in RTL.
|
|
92
|
+
*/
|
|
93
|
+
export const RTLDiff: Story = {
|
|
94
|
+
render: () => (
|
|
95
|
+
<>
|
|
96
|
+
{/* With stepper, back button, close button, and avatar */}
|
|
97
|
+
<FlowNavigation
|
|
98
|
+
activeStep={2}
|
|
99
|
+
avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
|
|
100
|
+
logo={<Logo />}
|
|
101
|
+
steps={rtlSteps}
|
|
102
|
+
onClose={noop}
|
|
103
|
+
onGoBack={noop}
|
|
104
|
+
/>
|
|
105
|
+
{/* Without stepper — logo left, close button right */}
|
|
106
|
+
<FlowNavigation
|
|
107
|
+
avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
|
|
108
|
+
logo={<Logo />}
|
|
109
|
+
onClose={noop}
|
|
110
|
+
/>
|
|
111
|
+
{/* Done state — no stepper, logo and close button only */}
|
|
112
|
+
<FlowNavigation
|
|
113
|
+
done
|
|
114
|
+
avatar={<AvatarView profileType={ProfileType.PERSONAL} />}
|
|
115
|
+
logo={<Logo />}
|
|
116
|
+
steps={rtlSteps}
|
|
117
|
+
onClose={noop}
|
|
118
|
+
/>
|
|
119
|
+
</>
|
|
120
|
+
),
|
|
121
|
+
...withRTLDiff(),
|
|
122
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
|
|
2
3
|
import Header, { type HeaderProps } from '../Header';
|
|
3
4
|
import { withVariantConfig } from '../../../.storybook/helpers';
|
|
4
5
|
|
|
@@ -122,3 +123,29 @@ export const AllVariants: Story = {
|
|
|
122
123
|
</div>
|
|
123
124
|
),
|
|
124
125
|
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The Header uses a CSS grid layout (1fr auto) that places the action on the
|
|
129
|
+
* inline-end side. In RTL the action should appear on the left instead of the
|
|
130
|
+
* right. Both level variants are included to cover the border-bottom alignment
|
|
131
|
+
* difference.
|
|
132
|
+
*/
|
|
133
|
+
export const RTLDiff: Story = {
|
|
134
|
+
render: () => (
|
|
135
|
+
<>
|
|
136
|
+
<Header title="Group level without action" level="group" />
|
|
137
|
+
<Header
|
|
138
|
+
title="Group level with action"
|
|
139
|
+
level="group"
|
|
140
|
+
action={{ 'aria-label': 'View all', text: 'View all', href: '#' }}
|
|
141
|
+
/>
|
|
142
|
+
<Header title="Section level without action" level="section" />
|
|
143
|
+
<Header
|
|
144
|
+
title="Section level with action"
|
|
145
|
+
level="section"
|
|
146
|
+
action={{ 'aria-label': 'Learn more', text: 'Learn more', href: '#' }}
|
|
147
|
+
/>
|
|
148
|
+
</>
|
|
149
|
+
),
|
|
150
|
+
...withRTLDiff(),
|
|
151
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
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 Info from '..';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
component: Info,
|
|
9
|
+
title: 'Dialogs/Info/Tests/RTL Diff',
|
|
10
|
+
tags: ['!autodocs', '!manifest'],
|
|
11
|
+
} satisfies Meta<typeof Info>;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Info>;
|
|
14
|
+
|
|
15
|
+
const iframeDiff = withRTLDiff({ renderAs: 'iframe' });
|
|
16
|
+
|
|
17
|
+
const openInfo = async ({ canvasElement }: { canvasElement: HTMLElement }) => {
|
|
18
|
+
const canvas = within(canvasElement);
|
|
19
|
+
const button = canvas.queryByRole('button');
|
|
20
|
+
if (!button) return;
|
|
21
|
+
await userEvent.click(button);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Popover: Story = {
|
|
25
|
+
render: () => (
|
|
26
|
+
<Info
|
|
27
|
+
aria-label="Info trigger"
|
|
28
|
+
title="Information"
|
|
29
|
+
content="This is some descriptive content inside the info component."
|
|
30
|
+
presentation="POPOVER"
|
|
31
|
+
size="sm"
|
|
32
|
+
/>
|
|
33
|
+
),
|
|
34
|
+
play: openInfo,
|
|
35
|
+
...iframeDiff,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const PopoverLarge: Story = {
|
|
39
|
+
render: () => (
|
|
40
|
+
<Info
|
|
41
|
+
aria-label="Info trigger"
|
|
42
|
+
title="Information"
|
|
43
|
+
content="This is some descriptive content inside the info component."
|
|
44
|
+
presentation="POPOVER"
|
|
45
|
+
size="lg"
|
|
46
|
+
/>
|
|
47
|
+
),
|
|
48
|
+
play: openInfo,
|
|
49
|
+
...iframeDiff,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const Modal: Story = {
|
|
53
|
+
render: () => (
|
|
54
|
+
<Info
|
|
55
|
+
aria-label="Info trigger"
|
|
56
|
+
title="Information"
|
|
57
|
+
content="This is some descriptive content inside the info component."
|
|
58
|
+
presentation="MODAL"
|
|
59
|
+
size="sm"
|
|
60
|
+
/>
|
|
61
|
+
),
|
|
62
|
+
play: openInfo,
|
|
63
|
+
...iframeDiff,
|
|
64
|
+
};
|