@transferwise/components 0.0.0-experimental-bd2aa28 → 0.0.0-experimental-1664fea
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/i18n/en.json +0 -2
- package/build/i18n/en.json.js +0 -2
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +0 -2
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/index.js +0 -3
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -2
- package/build/index.mjs.map +1 -1
- package/build/main.css +0 -256
- package/build/styles/main.css +0 -256
- package/build/types/index.d.ts +0 -4
- package/build/types/index.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +0 -4
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/i18n/en.json +0 -2
- package/src/index.ts +0 -4
- package/src/main.css +0 -256
- package/src/main.less +0 -2
- package/src/ssr.spec.tsx +0 -1
- package/build/selectOption/SelectOption.js +0 -131
- package/build/selectOption/SelectOption.js.map +0 -1
- package/build/selectOption/SelectOption.messages.js +0 -17
- package/build/selectOption/SelectOption.messages.js.map +0 -1
- package/build/selectOption/SelectOption.messages.mjs +0 -13
- package/build/selectOption/SelectOption.messages.mjs.map +0 -1
- package/build/selectOption/SelectOption.mjs +0 -127
- package/build/selectOption/SelectOption.mjs.map +0 -1
- package/build/styles/listItem/ListItem.css +0 -212
- package/build/styles/selectOption/SelectOption.css +0 -44
- package/build/types/listItem/ListItem.d.ts +0 -50
- package/build/types/listItem/ListItem.d.ts.map +0 -1
- package/build/types/listItem/ListItemAdditionalInfo.d.ts +0 -9
- package/build/types/listItem/ListItemAdditionalInfo.d.ts.map +0 -1
- package/build/types/listItem/ListItemButton.d.ts +0 -6
- package/build/types/listItem/ListItemButton.d.ts.map +0 -1
- package/build/types/listItem/ListItemCheckbox.d.ts +0 -4
- package/build/types/listItem/ListItemCheckbox.d.ts.map +0 -1
- package/build/types/listItem/ListItemIconButton.d.ts +0 -8
- package/build/types/listItem/ListItemIconButton.d.ts.map +0 -1
- package/build/types/listItem/ListItemMedia.d.ts +0 -19
- package/build/types/listItem/ListItemMedia.d.ts.map +0 -1
- package/build/types/listItem/ListItemNavigation.d.ts +0 -4
- package/build/types/listItem/ListItemNavigation.d.ts.map +0 -1
- package/build/types/listItem/ListItemSwitch.d.ts +0 -3
- package/build/types/listItem/ListItemSwitch.d.ts.map +0 -1
- package/build/types/listItem/index.d.ts +0 -6
- package/build/types/listItem/index.d.ts.map +0 -1
- package/build/types/listItem/prompt/Prompt.d.ts +0 -12
- package/build/types/listItem/prompt/Prompt.d.ts.map +0 -1
- package/build/types/listItem/useItemControl.d.ts +0 -5
- package/build/types/listItem/useItemControl.d.ts.map +0 -1
- package/build/types/selectOption/SelectOption.d.ts +0 -21
- package/build/types/selectOption/SelectOption.d.ts.map +0 -1
- package/build/types/selectOption/SelectOption.messages.d.ts +0 -12
- package/build/types/selectOption/SelectOption.messages.d.ts.map +0 -1
- package/build/types/selectOption/index.d.ts +0 -3
- package/build/types/selectOption/index.d.ts.map +0 -1
- package/src/listItem/ListItem.css +0 -212
- package/src/listItem/ListItem.less +0 -210
- package/src/listItem/ListItem.spec.tsx +0 -35
- package/src/listItem/ListItem.story.tsx +0 -461
- package/src/listItem/ListItem.tsx +0 -282
- package/src/listItem/ListItemAdditionalInfo.tsx +0 -31
- package/src/listItem/ListItemButton.spec.tsx +0 -92
- package/src/listItem/ListItemButton.tsx +0 -24
- package/src/listItem/ListItemCheckbox.tsx +0 -14
- package/src/listItem/ListItemIconButton.tsx +0 -16
- package/src/listItem/ListItemMedia.tsx +0 -52
- package/src/listItem/ListItemNavigation.tsx +0 -23
- package/src/listItem/ListItemSwitch.tsx +0 -8
- package/src/listItem/index.ts +0 -10
- package/src/listItem/prompt/Prompt.spec.tsx +0 -77
- package/src/listItem/prompt/Prompt.story.tsx +0 -170
- package/src/listItem/prompt/Prompt.tsx +0 -44
- package/src/listItem/useItemControl.tsx +0 -23
- package/src/selectOption/SelectOption.css +0 -44
- package/src/selectOption/SelectOption.less +0 -40
- package/src/selectOption/SelectOption.messages.ts +0 -12
- package/src/selectOption/SelectOption.spec.tsx +0 -83
- package/src/selectOption/SelectOption.story.tsx +0 -277
- package/src/selectOption/SelectOption.tsx +0 -151
- package/src/selectOption/index.ts +0 -2
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import Link from '../../link';
|
|
2
|
-
import { Sentiment } from '../../common';
|
|
3
|
-
import { Prompt, ListItemPromptProps } from './Prompt';
|
|
4
|
-
import { lorem40 } from '../../test-utils';
|
|
5
|
-
import { StoryObj } from '@storybook/react';
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
component: Prompt,
|
|
9
|
-
title: 'Content/ListItem/Prompt',
|
|
10
|
-
args: {
|
|
11
|
-
type: Sentiment.NEGATIVE,
|
|
12
|
-
children: 'You have done a terrible thing',
|
|
13
|
-
},
|
|
14
|
-
argTypes: {
|
|
15
|
-
type: {
|
|
16
|
-
options: [
|
|
17
|
-
Sentiment.POSITIVE,
|
|
18
|
-
Sentiment.NEGATIVE,
|
|
19
|
-
Sentiment.NEUTRAL,
|
|
20
|
-
Sentiment.WARNING,
|
|
21
|
-
'discount',
|
|
22
|
-
'savings',
|
|
23
|
-
],
|
|
24
|
-
control: { type: 'radio' },
|
|
25
|
-
description: 'The type of prompt to display',
|
|
26
|
-
},
|
|
27
|
-
action: {
|
|
28
|
-
table: {
|
|
29
|
-
disable: true,
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
children: {
|
|
33
|
-
type: {
|
|
34
|
-
name: 'string',
|
|
35
|
-
required: true,
|
|
36
|
-
description: 'The content of the prompt',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
type CustomStory = StoryObj<
|
|
43
|
-
ListItemPromptProps & {
|
|
44
|
-
interactivity?: 'none' | 'full-anchor' | 'full-button' | 'link';
|
|
45
|
-
}
|
|
46
|
-
>;
|
|
47
|
-
|
|
48
|
-
export const Basic: CustomStory = {
|
|
49
|
-
args: {
|
|
50
|
-
interactivity: 'none',
|
|
51
|
-
},
|
|
52
|
-
argTypes: {
|
|
53
|
-
interactivity: {
|
|
54
|
-
options: ['none', 'full-button', 'full-anchor', 'link'],
|
|
55
|
-
control: { type: 'radio' },
|
|
56
|
-
description: 'The type of interactivity to display',
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
render: ({ interactivity, ...args }) => {
|
|
60
|
-
return (
|
|
61
|
-
<div>
|
|
62
|
-
<Prompt
|
|
63
|
-
type={args.type}
|
|
64
|
-
action={
|
|
65
|
-
interactivity === 'full-anchor'
|
|
66
|
-
? { href: 'wise.com' }
|
|
67
|
-
: interactivity === 'full-button'
|
|
68
|
-
? {
|
|
69
|
-
onClick: () => {
|
|
70
|
-
console.log('clicked');
|
|
71
|
-
},
|
|
72
|
-
}
|
|
73
|
-
: undefined
|
|
74
|
-
}
|
|
75
|
-
>
|
|
76
|
-
{args.children} {interactivity === 'link' && <Link href="www.wise.com">with a link</Link>}
|
|
77
|
-
</Prompt>
|
|
78
|
-
</div>
|
|
79
|
-
);
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export const Variants = () => {
|
|
84
|
-
return (
|
|
85
|
-
<>
|
|
86
|
-
<div className="m-b-2">
|
|
87
|
-
<Prompt type={Sentiment.POSITIVE}>
|
|
88
|
-
Positive prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
89
|
-
</Prompt>
|
|
90
|
-
</div>
|
|
91
|
-
<div className="m-b-2">
|
|
92
|
-
<Prompt type={Sentiment.NEGATIVE}>
|
|
93
|
-
Negative prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
94
|
-
</Prompt>
|
|
95
|
-
</div>
|
|
96
|
-
<div className="m-b-2">
|
|
97
|
-
<Prompt type={Sentiment.NEUTRAL}>
|
|
98
|
-
Neutral prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
99
|
-
</Prompt>
|
|
100
|
-
</div>
|
|
101
|
-
<div className="m-b-2">
|
|
102
|
-
<Prompt type={Sentiment.WARNING}>
|
|
103
|
-
Warning prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
104
|
-
</Prompt>
|
|
105
|
-
</div>
|
|
106
|
-
<div className="m-b-2">
|
|
107
|
-
<Prompt type="discount">
|
|
108
|
-
Discount prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
109
|
-
</Prompt>
|
|
110
|
-
</div>
|
|
111
|
-
<div className="m-b-2">
|
|
112
|
-
<Prompt type="savings">
|
|
113
|
-
Savings prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
114
|
-
</Prompt>
|
|
115
|
-
</div>
|
|
116
|
-
<div className="m-b-2">
|
|
117
|
-
<Prompt
|
|
118
|
-
type="discount"
|
|
119
|
-
action={{
|
|
120
|
-
href: 'www.wise.com',
|
|
121
|
-
target: '_self',
|
|
122
|
-
'aria-label': 'hidden anchor tags are accessible, right?',
|
|
123
|
-
}}
|
|
124
|
-
>
|
|
125
|
-
The whole prompt is secretly clickable
|
|
126
|
-
</Prompt>
|
|
127
|
-
</div>
|
|
128
|
-
<div className="m-b-2">
|
|
129
|
-
<Prompt
|
|
130
|
-
type="negative"
|
|
131
|
-
action={{
|
|
132
|
-
href: 'www.wise.com',
|
|
133
|
-
target: '_self',
|
|
134
|
-
'aria-label': 'clickable <a>',
|
|
135
|
-
}}
|
|
136
|
-
>
|
|
137
|
-
The whole prompt is secretly clickable as an anchor tag
|
|
138
|
-
</Prompt>
|
|
139
|
-
</div>
|
|
140
|
-
<div className="m-b-2">
|
|
141
|
-
<Prompt
|
|
142
|
-
type="warning"
|
|
143
|
-
action={{
|
|
144
|
-
onClick: () => {
|
|
145
|
-
console.log('clicked');
|
|
146
|
-
},
|
|
147
|
-
'aria-label': 'clickable button',
|
|
148
|
-
}}
|
|
149
|
-
>
|
|
150
|
-
The whole prompt is secretly clickable as a button
|
|
151
|
-
</Prompt>
|
|
152
|
-
</div>
|
|
153
|
-
<div className="m-b-2">
|
|
154
|
-
<Prompt
|
|
155
|
-
type="neutral"
|
|
156
|
-
action={{
|
|
157
|
-
href: 'www.wise.com',
|
|
158
|
-
target: '_self',
|
|
159
|
-
'aria-label': 'clickable prompt',
|
|
160
|
-
}}
|
|
161
|
-
>
|
|
162
|
-
The whole prompt is secretly clickable
|
|
163
|
-
</Prompt>
|
|
164
|
-
</div>
|
|
165
|
-
<div className="m-b-2" style={{ maxWidth: '300px' }}>
|
|
166
|
-
<Prompt type="warning">The prompt has very long text that wraps {lorem40}</Prompt>
|
|
167
|
-
</div>
|
|
168
|
-
</>
|
|
169
|
-
);
|
|
170
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Confetti, Tags } from '@transferwise/icons';
|
|
2
|
-
import { Sentiment } from '../../common';
|
|
3
|
-
import StatusIcon from '../../statusIcon';
|
|
4
|
-
import { clsx } from 'clsx';
|
|
5
|
-
import { LinkProps } from '../../link';
|
|
6
|
-
import Body from '../../body';
|
|
7
|
-
|
|
8
|
-
export type ListItemPromptProps = {
|
|
9
|
-
type:
|
|
10
|
-
| `${Sentiment.POSITIVE | Sentiment.NEGATIVE | Sentiment.NEUTRAL | Sentiment.WARNING}`
|
|
11
|
-
| 'discount'
|
|
12
|
-
| 'savings';
|
|
13
|
-
children: React.ReactNode;
|
|
14
|
-
action?: Pick<LinkProps, 'href' | 'target' | 'onClick'> & { 'aria-label'?: string };
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const Prompt = ({ type, children, action }: ListItemPromptProps) => {
|
|
18
|
-
const Wrapper = action?.href ? 'a' : action?.onClick ? 'button' : 'span';
|
|
19
|
-
|
|
20
|
-
const icon =
|
|
21
|
-
type === 'discount' ? (
|
|
22
|
-
<Tags size={16} />
|
|
23
|
-
) : type === 'savings' ? (
|
|
24
|
-
<Confetti size={16} />
|
|
25
|
-
) : (
|
|
26
|
-
<StatusIcon size={16} sentiment={type} />
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<Wrapper
|
|
31
|
-
className={clsx(
|
|
32
|
-
'wds-list-item-prompt',
|
|
33
|
-
type,
|
|
34
|
-
(action?.href || action?.onClick) && 'np-prompt-interactive',
|
|
35
|
-
)}
|
|
36
|
-
{...(action ?? {})}
|
|
37
|
-
>
|
|
38
|
-
<div className="np-prompt-icon">{icon}</div>
|
|
39
|
-
<Body>{children}</Body>
|
|
40
|
-
</Wrapper>
|
|
41
|
-
);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export default Prompt;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { useContext, useEffect } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
ListItemContext,
|
|
4
|
-
ListItemContextData,
|
|
5
|
-
ListItemControlProps,
|
|
6
|
-
ListItemTypes,
|
|
7
|
-
} from './ListItem';
|
|
8
|
-
|
|
9
|
-
export function useItemControl(controlType: ListItemTypes, controlProps?: ListItemControlProps) {
|
|
10
|
-
const {
|
|
11
|
-
setControlType,
|
|
12
|
-
setControlProps,
|
|
13
|
-
props: baseItemProps,
|
|
14
|
-
} = useContext<ListItemContextData>(ListItemContext);
|
|
15
|
-
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
setControlType(controlType);
|
|
18
|
-
// @ts-expect-error TODO: fix the type error later
|
|
19
|
-
setControlProps(controlProps);
|
|
20
|
-
}, [controlType, controlProps, setControlType, setControlProps]);
|
|
21
|
-
|
|
22
|
-
return { baseItemProps };
|
|
23
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
.np-select-option {
|
|
2
|
-
border-radius: 10px;
|
|
3
|
-
border-radius: var(--radius-small);
|
|
4
|
-
padding: 16px;
|
|
5
|
-
padding: var(--size-16);
|
|
6
|
-
}
|
|
7
|
-
.np-select-option-placeholder {
|
|
8
|
-
background-color: rgba(134,167,189,0.10196);
|
|
9
|
-
background-color: var(--color-background-neutral);
|
|
10
|
-
}
|
|
11
|
-
.np-select-option-placeholder:not(.disabled):hover {
|
|
12
|
-
background-color: var(--color-background-neutral-hover);
|
|
13
|
-
}
|
|
14
|
-
.np-select-option-placeholder:not(.disabled):focus,
|
|
15
|
-
.np-select-option-placeholder:not(.disabled):active {
|
|
16
|
-
background-color: var(--color-background-neutral-active);
|
|
17
|
-
}
|
|
18
|
-
.np-select-option-selected {
|
|
19
|
-
border: 1px solid #c9cbce;
|
|
20
|
-
border: 1px solid var(--color-interactive-secondary);
|
|
21
|
-
}
|
|
22
|
-
.np-select-option-list {
|
|
23
|
-
max-height: 350px;
|
|
24
|
-
overflow-y: auto;
|
|
25
|
-
}
|
|
26
|
-
.np-select-option-list > .np-section {
|
|
27
|
-
margin-top: 0;
|
|
28
|
-
}
|
|
29
|
-
.has-error * .np-select-option {
|
|
30
|
-
--ring-outline-color: var(--color-sentiment-negative);
|
|
31
|
-
--ring-outline-width: 3px;
|
|
32
|
-
--ring-outline-offset: calc(-1 * var(--ring-outline-width));
|
|
33
|
-
outline: var(--ring-outline-color) solid 3px;
|
|
34
|
-
outline: var(--ring-outline-color) solid var(--ring-outline-width);
|
|
35
|
-
outline-offset: calc(-1 * 3px);
|
|
36
|
-
outline-offset: var(--ring-outline-offset);
|
|
37
|
-
}
|
|
38
|
-
.has-error * .np-select-option:focus {
|
|
39
|
-
outline: none;
|
|
40
|
-
}
|
|
41
|
-
.has-error * .np-select-option:focus-visible {
|
|
42
|
-
outline: var(--ring-outline-color) solid var(--ring-outline-width);
|
|
43
|
-
outline-offset: var(--ring-outline-offset);
|
|
44
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
@import (reference) "../../node_modules/@transferwise/neptune-css/src/less/ring.less";
|
|
2
|
-
|
|
3
|
-
.np-select-option {
|
|
4
|
-
border-radius: var(--radius-small);
|
|
5
|
-
padding: var(--size-16);
|
|
6
|
-
|
|
7
|
-
&-placeholder {
|
|
8
|
-
background-color: var(--color-background-neutral);
|
|
9
|
-
|
|
10
|
-
&:not(.disabled):hover {
|
|
11
|
-
background-color: var(--color-background-neutral-hover);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
&:not(.disabled):focus,
|
|
15
|
-
&:not(.disabled):active {
|
|
16
|
-
background-color: var(--color-background-neutral-active);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
&-selected {
|
|
21
|
-
border: 1px solid var(--color-interactive-secondary);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
&-list {
|
|
25
|
-
max-height: 350px;
|
|
26
|
-
overflow-y: auto;
|
|
27
|
-
|
|
28
|
-
& > .np-section {
|
|
29
|
-
// remove large margin in Section & Header
|
|
30
|
-
margin-top: 0;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.has-error * & {
|
|
35
|
-
.ring-negative();
|
|
36
|
-
.ring-inset();
|
|
37
|
-
.ring();
|
|
38
|
-
.focus-ring();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { defineMessages } from 'react-intl';
|
|
2
|
-
|
|
3
|
-
export default defineMessages({
|
|
4
|
-
actionLabel: {
|
|
5
|
-
id: 'neptune.SelectOption.action.label',
|
|
6
|
-
defaultMessage: 'Choose',
|
|
7
|
-
},
|
|
8
|
-
selectedActionLabel: {
|
|
9
|
-
id: 'neptune.SelectOption.selected.action.label',
|
|
10
|
-
defaultMessage: 'Change chosen option',
|
|
11
|
-
},
|
|
12
|
-
});
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { render, userEvent, screen, within, mockMatchMedia } from '../test-utils';
|
|
2
|
-
import { composeStories } from '@storybook/react';
|
|
3
|
-
import * as stories from './SelectOption.story';
|
|
4
|
-
import { Breakpoint } from '../common';
|
|
5
|
-
import { wait } from '../test-utils/wait';
|
|
6
|
-
|
|
7
|
-
const { Basic: SelectOptionExample } = composeStories(stories);
|
|
8
|
-
|
|
9
|
-
mockMatchMedia();
|
|
10
|
-
|
|
11
|
-
describe('Select Option', () => {
|
|
12
|
-
it('opens dropdown on desktop view', async () => {
|
|
13
|
-
render(<SelectOptionExample />);
|
|
14
|
-
|
|
15
|
-
let dialog = screen.queryByRole('dialog');
|
|
16
|
-
expect(dialog).not.toBeInTheDocument();
|
|
17
|
-
|
|
18
|
-
const button = screen.getByRole('button');
|
|
19
|
-
|
|
20
|
-
await userEvent.click(button);
|
|
21
|
-
|
|
22
|
-
dialog = screen.queryByRole('dialog');
|
|
23
|
-
expect(dialog).toBeInTheDocument();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('opens bottom sheet on mobile view', async () => {
|
|
27
|
-
// mock mobile view
|
|
28
|
-
window.innerWidth = Breakpoint.EXTRA_SMALL;
|
|
29
|
-
|
|
30
|
-
render(<SelectOptionExample />);
|
|
31
|
-
|
|
32
|
-
let dialog = screen.queryByRole('dialog');
|
|
33
|
-
expect(dialog).not.toBeInTheDocument();
|
|
34
|
-
|
|
35
|
-
const button = screen.getByRole('button');
|
|
36
|
-
|
|
37
|
-
await userEvent.click(button);
|
|
38
|
-
|
|
39
|
-
dialog = screen.queryByRole('dialog');
|
|
40
|
-
expect(dialog).toBeInTheDocument();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('shows options', async () => {
|
|
44
|
-
render(<SelectOptionExample />);
|
|
45
|
-
|
|
46
|
-
const button = screen.getByRole('button');
|
|
47
|
-
|
|
48
|
-
await userEvent.click(button);
|
|
49
|
-
|
|
50
|
-
const dialog = screen.getByRole('dialog');
|
|
51
|
-
const sectionHeaders = within(dialog).getAllByRole('heading', { name: /balances|jars/i });
|
|
52
|
-
expect(sectionHeaders).toHaveLength(2);
|
|
53
|
-
|
|
54
|
-
const options = within(dialog).getAllByRole('heading', { level: 4 });
|
|
55
|
-
expect(options).toHaveLength(5);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('choose option', async () => {
|
|
59
|
-
// mock mobile view
|
|
60
|
-
window.innerWidth = Breakpoint.EXTRA_SMALL;
|
|
61
|
-
|
|
62
|
-
render(
|
|
63
|
-
<SelectOptionExample placeholder={{ title: 'Please choose balance', actionLabel: 'Pick' }} />,
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
const button = screen.getByRole('button');
|
|
67
|
-
|
|
68
|
-
expect(button).toHaveTextContent('Pick');
|
|
69
|
-
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
70
|
-
await userEvent.click(button);
|
|
71
|
-
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
72
|
-
|
|
73
|
-
const pickedOption = within(screen.getByRole('dialog')).getByText('Trip to Mars');
|
|
74
|
-
|
|
75
|
-
await userEvent.click(pickedOption);
|
|
76
|
-
|
|
77
|
-
// wait for dialog to close
|
|
78
|
-
await wait(500);
|
|
79
|
-
expect(screen.getByText('Trip to Mars')).toBeInTheDocument();
|
|
80
|
-
expect(screen.queryAllByTestId('chevron-down-icon')).toHaveLength(1);
|
|
81
|
-
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
82
|
-
});
|
|
83
|
-
});
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react';
|
|
2
|
-
import { Flag } from '@wise/art';
|
|
3
|
-
import SelectOption, {
|
|
4
|
-
SelectOptionProps,
|
|
5
|
-
SelectOptionValue,
|
|
6
|
-
SelectOptiopsSection,
|
|
7
|
-
} from './SelectOption';
|
|
8
|
-
import { Bank, BankTransfer, Beach, Briefcase, Card, Plane } from '@transferwise/icons';
|
|
9
|
-
import { Field } from '../field/Field';
|
|
10
|
-
import { lorem10 } from '../test-utils';
|
|
11
|
-
import Badge from '../badge';
|
|
12
|
-
import Avatar from '../avatar';
|
|
13
|
-
import { Sentiment } from '../common';
|
|
14
|
-
import { useState } from 'react';
|
|
15
|
-
|
|
16
|
-
export default {
|
|
17
|
-
title: 'Option/SelectOption',
|
|
18
|
-
tags: ['autodocs'],
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
type Story = StoryObj<typeof SelectOption>;
|
|
22
|
-
|
|
23
|
-
type CustomData = { data?: string };
|
|
24
|
-
|
|
25
|
-
function cardPaymentMethod(index?: number): SelectOptionValue<CustomData> {
|
|
26
|
-
return {
|
|
27
|
-
media: <Card />,
|
|
28
|
-
title: `Credit card ${index}`,
|
|
29
|
-
content: (
|
|
30
|
-
<>
|
|
31
|
-
<div>Transfer the money to Wise using your bank account.</div>
|
|
32
|
-
<div>0.32 GBP in fees, should arrive in seconds</div>
|
|
33
|
-
</>
|
|
34
|
-
),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const recentPaymentMethods: SelectOptionValue<CustomData>[] = [
|
|
39
|
-
cardPaymentMethod(1),
|
|
40
|
-
cardPaymentMethod(2),
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
const allOtherPaymentMethods: SelectOptionValue<CustomData>[] = [
|
|
44
|
-
{
|
|
45
|
-
media: <Flag code="gbp" />,
|
|
46
|
-
title: 'Wise GBP balance',
|
|
47
|
-
content: (
|
|
48
|
-
<>
|
|
49
|
-
<span>300 GBP available</span>
|
|
50
|
-
<span>0 GBP in fees, should arrive in seconds</span>
|
|
51
|
-
</>
|
|
52
|
-
),
|
|
53
|
-
disabled: true,
|
|
54
|
-
value: { data: lorem10 },
|
|
55
|
-
},
|
|
56
|
-
cardPaymentMethod(1),
|
|
57
|
-
{
|
|
58
|
-
media: <Card />,
|
|
59
|
-
title: 'Debit card',
|
|
60
|
-
content: (
|
|
61
|
-
<>
|
|
62
|
-
<span>Send from your Visa or Mastercard.</span>
|
|
63
|
-
<span>0.74 GBP in fees, should arrive in seconds</span>
|
|
64
|
-
</>
|
|
65
|
-
),
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
media: <Bank />,
|
|
69
|
-
title: 'Swift Transfer',
|
|
70
|
-
content: (
|
|
71
|
-
<>
|
|
72
|
-
<span>Send money internationally. Your bank will charge you extra fees.</span>
|
|
73
|
-
<span>0.32 GBP in fees, should arrive by Thursday</span>
|
|
74
|
-
</>
|
|
75
|
-
),
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
media: <BankTransfer />,
|
|
79
|
-
title: 'Bank Transfer',
|
|
80
|
-
content: (
|
|
81
|
-
<>
|
|
82
|
-
<span>Transfer the money to Wise using your bank account.</span>
|
|
83
|
-
<span>0.32 GBP in fees, should arrive in seconds</span>
|
|
84
|
-
</>
|
|
85
|
-
),
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
media: <BankTransfer />,
|
|
89
|
-
title: 'Withdraw from your U.S. bank account (ACH)',
|
|
90
|
-
content: (
|
|
91
|
-
<>
|
|
92
|
-
<span>1.63 USD in total fees.</span>
|
|
93
|
-
<span>
|
|
94
|
-
Pay with ACH using the bank account you’ve connected to Wise. Should arrive in seconds.
|
|
95
|
-
</span>
|
|
96
|
-
</>
|
|
97
|
-
),
|
|
98
|
-
},
|
|
99
|
-
cardPaymentMethod(1),
|
|
100
|
-
cardPaymentMethod(2),
|
|
101
|
-
cardPaymentMethod(3),
|
|
102
|
-
cardPaymentMethod(4),
|
|
103
|
-
cardPaymentMethod(5),
|
|
104
|
-
cardPaymentMethod(6),
|
|
105
|
-
];
|
|
106
|
-
|
|
107
|
-
const paymentMethods: SelectOptiopsSection<CustomData>[] = [
|
|
108
|
-
{
|
|
109
|
-
title: 'Recently used',
|
|
110
|
-
options: recentPaymentMethods,
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
title: 'Payment methods',
|
|
114
|
-
options: allOtherPaymentMethods,
|
|
115
|
-
},
|
|
116
|
-
];
|
|
117
|
-
|
|
118
|
-
const balances: SelectOptiopsSection[] = [
|
|
119
|
-
{
|
|
120
|
-
title: 'Balances',
|
|
121
|
-
options: [
|
|
122
|
-
{
|
|
123
|
-
media: <Flag code="gbp" />,
|
|
124
|
-
title: 'Wise GBP balance',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
media: <Flag code="eur" />,
|
|
128
|
-
title: 'Wise EUR balance',
|
|
129
|
-
},
|
|
130
|
-
],
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
title: 'Jars',
|
|
134
|
-
options: [
|
|
135
|
-
{
|
|
136
|
-
media: (
|
|
137
|
-
<Badge badge={<Flag code="usd" />} size="md">
|
|
138
|
-
<Avatar type="icon" size="md" backgroundColor="var(--color-bright-pink)">
|
|
139
|
-
<Beach size="24" />
|
|
140
|
-
</Avatar>
|
|
141
|
-
</Badge>
|
|
142
|
-
),
|
|
143
|
-
title: 'Hawaii Holiday',
|
|
144
|
-
content: 'Wise USD jar',
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
media: (
|
|
148
|
-
<Badge badge={<Flag code="aed" />} size="md">
|
|
149
|
-
<Avatar type="icon" size="md" backgroundColor="var(--color-bright-yellow)">
|
|
150
|
-
<Briefcase size="24" />
|
|
151
|
-
</Avatar>
|
|
152
|
-
</Badge>
|
|
153
|
-
),
|
|
154
|
-
title: 'Emirates Business Trip',
|
|
155
|
-
content: 'Wise AED jar',
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
media: (
|
|
159
|
-
<Badge badge={<Flag code="jpy" />} size="md">
|
|
160
|
-
<Avatar type="icon" size="md" backgroundColor="var(--color-bright-blue)">
|
|
161
|
-
<Plane size="24" />
|
|
162
|
-
</Avatar>
|
|
163
|
-
</Badge>
|
|
164
|
-
),
|
|
165
|
-
title: 'Trip to Mars',
|
|
166
|
-
content: 'Wise Jpy jar',
|
|
167
|
-
},
|
|
168
|
-
],
|
|
169
|
-
},
|
|
170
|
-
];
|
|
171
|
-
|
|
172
|
-
export const Basic: Story = {
|
|
173
|
-
args: {
|
|
174
|
-
placeholder: { title: 'No balance selected' },
|
|
175
|
-
options: balances,
|
|
176
|
-
},
|
|
177
|
-
render: (args: SelectOptionProps) => {
|
|
178
|
-
const [selected, setSelected] = useState<SelectOptionValue | undefined>(undefined);
|
|
179
|
-
|
|
180
|
-
function onChange(value: SelectOptionValue): void {
|
|
181
|
-
setSelected(value);
|
|
182
|
-
}
|
|
183
|
-
return (
|
|
184
|
-
<div className="row">
|
|
185
|
-
<div className="col-md-8 col-md-offset-2">
|
|
186
|
-
<Field label="Balances">
|
|
187
|
-
<SelectOption {...args} {...{ selected, onChange }} />
|
|
188
|
-
</Field>
|
|
189
|
-
</div>
|
|
190
|
-
</div>
|
|
191
|
-
);
|
|
192
|
-
},
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
export const Variants: Story = {
|
|
196
|
-
render: () => {
|
|
197
|
-
const [selected, setSelected] = useState<SelectOptionValue<CustomData>>({
|
|
198
|
-
...paymentMethods[1].options[1],
|
|
199
|
-
content: null,
|
|
200
|
-
});
|
|
201
|
-
function onChange(value: SelectOptionValue<CustomData>): void {
|
|
202
|
-
setSelected({ ...value, content: null });
|
|
203
|
-
}
|
|
204
|
-
return (
|
|
205
|
-
<div className="row">
|
|
206
|
-
<div className="col-md-8 col-md-offset-2">
|
|
207
|
-
<SelectOption<CustomData>
|
|
208
|
-
className="d-block"
|
|
209
|
-
aria-label="Choose one of payment methods"
|
|
210
|
-
placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
|
|
211
|
-
selected={selected}
|
|
212
|
-
options={paymentMethods}
|
|
213
|
-
onChange={onChange}
|
|
214
|
-
/>
|
|
215
|
-
</div>
|
|
216
|
-
|
|
217
|
-
<div className="col-md-8 col-md-offset-2">
|
|
218
|
-
<Field label={<>Payment method</>}>
|
|
219
|
-
<SelectOption<CustomData>
|
|
220
|
-
aria-label="Choose one of payment methods"
|
|
221
|
-
placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
|
|
222
|
-
selected={selected}
|
|
223
|
-
options={paymentMethods}
|
|
224
|
-
onChange={onChange}
|
|
225
|
-
/>
|
|
226
|
-
</Field>
|
|
227
|
-
</div>
|
|
228
|
-
|
|
229
|
-
<div className="col-md-8 col-md-offset-2">
|
|
230
|
-
<Field
|
|
231
|
-
label={<>Payment method</>}
|
|
232
|
-
sentiment={Sentiment.NEGATIVE}
|
|
233
|
-
message="Just an example of validation message"
|
|
234
|
-
>
|
|
235
|
-
<SelectOption<CustomData>
|
|
236
|
-
aria-label="Choose one of payment methods"
|
|
237
|
-
placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
|
|
238
|
-
selected={selected}
|
|
239
|
-
options={paymentMethods}
|
|
240
|
-
onChange={onChange}
|
|
241
|
-
/>
|
|
242
|
-
</Field>
|
|
243
|
-
</div>
|
|
244
|
-
|
|
245
|
-
<div className="col-md-8 col-md-offset-2">
|
|
246
|
-
<Field
|
|
247
|
-
label={<>Payment method</>}
|
|
248
|
-
sentiment={Sentiment.NEGATIVE}
|
|
249
|
-
message="Just an example of validation message"
|
|
250
|
-
>
|
|
251
|
-
<SelectOption<CustomData>
|
|
252
|
-
aria-label="Choose one of payment methods"
|
|
253
|
-
placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
|
|
254
|
-
options={paymentMethods}
|
|
255
|
-
onChange={onChange}
|
|
256
|
-
/>
|
|
257
|
-
</Field>
|
|
258
|
-
</div>
|
|
259
|
-
|
|
260
|
-
<div className="col-md-8 col-md-offset-2">
|
|
261
|
-
<Field
|
|
262
|
-
label={<>Payment method</>}
|
|
263
|
-
sentiment={Sentiment.NEGATIVE}
|
|
264
|
-
message="Example of disabled select option"
|
|
265
|
-
>
|
|
266
|
-
<SelectOption<CustomData>
|
|
267
|
-
disabled
|
|
268
|
-
placeholder={{ title: 'No method selected' }}
|
|
269
|
-
options={paymentMethods}
|
|
270
|
-
onChange={onChange}
|
|
271
|
-
/>
|
|
272
|
-
</Field>
|
|
273
|
-
</div>
|
|
274
|
-
</div>
|
|
275
|
-
);
|
|
276
|
-
},
|
|
277
|
-
};
|