@transferwise/components 46.127.1 → 46.128.0
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/alert/Alert.js +3 -0
- package/build/alert/Alert.js.map +1 -1
- package/build/alert/Alert.mjs +3 -0
- package/build/alert/Alert.mjs.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -1
- package/build/inputs/SelectInput.js +81 -12
- package/build/inputs/SelectInput.js.map +1 -1
- package/build/inputs/SelectInput.mjs +81 -13
- package/build/inputs/SelectInput.mjs.map +1 -1
- package/build/main.css +15 -7
- package/build/prompt/ActionPrompt/ActionPrompt.js +6 -4
- package/build/prompt/ActionPrompt/ActionPrompt.js.map +1 -1
- package/build/prompt/ActionPrompt/ActionPrompt.mjs +6 -4
- package/build/prompt/ActionPrompt/ActionPrompt.mjs.map +1 -1
- package/build/prompt/InfoPrompt/InfoPrompt.js.map +1 -1
- package/build/prompt/InfoPrompt/InfoPrompt.mjs.map +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.js +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.mjs +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
- package/build/styles/main.css +15 -7
- package/build/styles/prompt/ActionPrompt/ActionPrompt.css +4 -0
- package/build/styles/prompt/InfoPrompt/InfoPrompt.css +7 -5
- package/build/styles/prompt/InlinePrompt/InlinePrompt.css +3 -2
- package/build/styles/prompt/PrimitivePrompt/PrimitivePrompt.css +1 -0
- package/build/types/alert/Alert.d.ts +15 -0
- package/build/types/alert/Alert.d.ts.map +1 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/inputs/SelectInput.d.ts +19 -0
- package/build/types/inputs/SelectInput.d.ts.map +1 -1
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts +7 -0
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts.map +1 -1
- package/build/types/prompt/InfoPrompt/InfoPrompt.d.ts +4 -2
- package/build/types/prompt/InfoPrompt/InfoPrompt.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/alert/Alert.story.tsx +4 -0
- package/src/alert/Alert.test.story.tsx +1 -1
- package/src/alert/Alert.tsx +16 -0
- package/src/iconButton/IconButton.story.tsx +173 -48
- package/src/iconButton/IconButton.test.story.tsx +194 -0
- package/src/index.ts +1 -0
- package/src/inputs/SelectInput.story.tsx +33 -20
- package/src/inputs/SelectInput.test.story.tsx +1285 -5
- package/src/inputs/SelectInput.tsx +93 -15
- package/src/listItem/_stories/ListItem.story.tsx +0 -1
- package/src/main.css +15 -7
- package/src/prompt/ActionPrompt/ActionPrompt.accessibility.docs.mdx +2 -18
- package/src/prompt/ActionPrompt/ActionPrompt.css +4 -0
- package/src/prompt/ActionPrompt/ActionPrompt.less +5 -1
- package/src/prompt/ActionPrompt/ActionPrompt.story.tsx +323 -108
- package/src/prompt/ActionPrompt/ActionPrompt.test.story.tsx +86 -3
- package/src/prompt/ActionPrompt/ActionPrompt.tsx +17 -6
- package/src/prompt/InfoPrompt/InfoPrompt.accessibility.docs.mdx +79 -0
- package/src/prompt/InfoPrompt/InfoPrompt.css +7 -5
- package/src/prompt/InfoPrompt/InfoPrompt.less +8 -8
- package/src/prompt/InfoPrompt/InfoPrompt.story.tsx +112 -82
- package/src/prompt/InfoPrompt/InfoPrompt.test.story.tsx +54 -1
- package/src/prompt/InfoPrompt/InfoPrompt.tsx +4 -2
- package/src/prompt/InlinePrompt/InlinePrompt.accessibility.docs.mdx +63 -0
- package/src/prompt/InlinePrompt/InlinePrompt.css +3 -2
- package/src/prompt/InlinePrompt/InlinePrompt.less +2 -2
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +25 -30
- package/src/prompt/InlinePrompt/InlinePrompt.test.story.tsx +21 -0
- package/src/prompt/InlinePrompt/InlinePrompt.test.tsx +10 -3
- package/src/prompt/InlinePrompt/InlinePrompt.tsx +1 -1
- package/src/prompt/PrimitivePrompt/PrimitivePrompt.css +1 -0
- package/src/prompt/PrimitivePrompt/PrimitivePrompt.less +2 -1
- package/src/sentimentSurface/SentimentSurface.docs.mdx +1 -1
- package/src/sentimentSurface/SentimentSurface.story.tsx +1 -1
- package/src/sentimentSurface/SentimentSurface.test.story.tsx +1 -1
package/src/alert/Alert.tsx
CHANGED
|
@@ -19,6 +19,9 @@ import InlineMarkdown from './inlineMarkdown';
|
|
|
19
19
|
import Button from '../button';
|
|
20
20
|
import Link from '../link';
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated `Alert` component is being replaced by the `InfoPrompt` component
|
|
24
|
+
*/
|
|
22
25
|
export type AlertAction = {
|
|
23
26
|
'aria-label'?: string;
|
|
24
27
|
href?: string;
|
|
@@ -37,8 +40,15 @@ type AlertTypeResolved = `${
|
|
|
37
40
|
// remove when all instances of Sentiment.PENDING have been updated to Status.PENDING
|
|
38
41
|
| Sentiment.PENDING
|
|
39
42
|
| Status.PENDING}`;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @deprecated `Alert` component is being replaced by the `InfoPrompt` component
|
|
46
|
+
*/
|
|
40
47
|
export type AlertType = AlertTypeResolved | AlertTypeDeprecated;
|
|
41
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated `Alert` component is being replaced by the `InfoPrompt` component
|
|
51
|
+
*/
|
|
42
52
|
export enum AlertArrowPosition {
|
|
43
53
|
TOP_LEFT = 'up-left',
|
|
44
54
|
TOP = 'up-center',
|
|
@@ -48,6 +58,9 @@ export enum AlertArrowPosition {
|
|
|
48
58
|
BOTTOM_RIGHT = 'down-right',
|
|
49
59
|
}
|
|
50
60
|
|
|
61
|
+
/**
|
|
62
|
+
* @deprecated `Alert` component is being replaced by the `InfoPrompt` component
|
|
63
|
+
*/
|
|
51
64
|
export interface AlertProps {
|
|
52
65
|
/** An optional call to action to sit under the main body of the alert. If your label is short, use aria-label to provide more context */
|
|
53
66
|
action?: AlertAction;
|
|
@@ -90,6 +103,9 @@ function resolveType(type: AlertType): AlertTypeResolved {
|
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @deprecated use [`InfoPrompt`](https://storybook.wise.design/?path=/docs/prompts-infoprompt--docs) component instead
|
|
108
|
+
*/
|
|
93
109
|
export default function Alert({
|
|
94
110
|
action,
|
|
95
111
|
className,
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ArrowLeft,
|
|
4
|
+
Cross,
|
|
5
|
+
Defrost,
|
|
6
|
+
Edit,
|
|
7
|
+
Menu,
|
|
8
|
+
Plus,
|
|
9
|
+
Settings,
|
|
10
|
+
Star,
|
|
11
|
+
Travel,
|
|
12
|
+
Briefcase,
|
|
13
|
+
Bank,
|
|
14
|
+
Freeze,
|
|
15
|
+
} from '@transferwise/icons';
|
|
3
16
|
import IconButton, { Props } from './IconButton';
|
|
4
17
|
import { action } from 'storybook/actions';
|
|
5
18
|
import Body from '../body';
|
|
@@ -114,48 +127,167 @@ export const Basic: Story = {
|
|
|
114
127
|
*/
|
|
115
128
|
export const SentimentAwareness: Story = {
|
|
116
129
|
render: () => {
|
|
130
|
+
const priorities = ['primary', 'secondary', 'tertiary', 'minimal', 'disabled'] as const;
|
|
131
|
+
const sentiments = ['success', 'warning', 'negative', 'neutral', 'proposition'] as const;
|
|
132
|
+
|
|
117
133
|
return (
|
|
118
|
-
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
style={{
|
|
134
|
+
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
|
135
|
+
{/* Header row with priority labels */}
|
|
136
|
+
<div style={{ display: 'flex', alignItems: 'flex-end', marginBottom: '4px', gap: '8px' }}>
|
|
137
|
+
<div style={{ width: '82px', paddingLeft: '8px' }} />
|
|
138
|
+
{priorities.map((priority) => (
|
|
139
|
+
<div
|
|
140
|
+
key={priority}
|
|
141
|
+
style={{
|
|
142
|
+
width: '32px',
|
|
143
|
+
textAlign: 'center',
|
|
144
|
+
fontSize: '11px',
|
|
145
|
+
fontWeight: 'bold',
|
|
146
|
+
writingMode: 'vertical-rl',
|
|
147
|
+
transform: 'rotate(180deg)',
|
|
148
|
+
height: '60px',
|
|
149
|
+
display: 'flex',
|
|
150
|
+
alignItems: 'center',
|
|
151
|
+
justifyContent: 'center',
|
|
152
|
+
}}
|
|
126
153
|
>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
{priority}
|
|
155
|
+
</div>
|
|
156
|
+
))}
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
{/* Rows for each sentiment with base and elevated emphasis */}
|
|
160
|
+
{sentiments.flatMap((sentiment) => [
|
|
161
|
+
<SentimentSurface
|
|
162
|
+
key={`${sentiment}-base`}
|
|
163
|
+
sentiment={sentiment}
|
|
164
|
+
emphasis="base"
|
|
165
|
+
style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
|
|
166
|
+
>
|
|
167
|
+
<div
|
|
168
|
+
style={{
|
|
169
|
+
width: '82px',
|
|
170
|
+
fontSize: '11px',
|
|
171
|
+
fontWeight: 'bold',
|
|
172
|
+
textAlign: 'left',
|
|
173
|
+
paddingLeft: '8px',
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
{sentiment} (base)
|
|
177
|
+
</div>
|
|
178
|
+
<IconButton
|
|
179
|
+
size={32}
|
|
180
|
+
aria-label="Primary action"
|
|
181
|
+
priority="primary"
|
|
182
|
+
type="default"
|
|
183
|
+
onClick={action('button click')}
|
|
184
|
+
>
|
|
185
|
+
<Plus />
|
|
186
|
+
</IconButton>
|
|
187
|
+
<IconButton
|
|
188
|
+
size={32}
|
|
189
|
+
aria-label="Secondary action"
|
|
190
|
+
priority="secondary"
|
|
191
|
+
type="default"
|
|
192
|
+
onClick={action('button click')}
|
|
193
|
+
>
|
|
194
|
+
<Settings />
|
|
195
|
+
</IconButton>
|
|
196
|
+
<IconButton
|
|
197
|
+
size={32}
|
|
198
|
+
aria-label="Tertiary action"
|
|
199
|
+
priority="tertiary"
|
|
200
|
+
type="default"
|
|
201
|
+
onClick={action('button click')}
|
|
202
|
+
>
|
|
203
|
+
<Star />
|
|
204
|
+
</IconButton>
|
|
205
|
+
<IconButton
|
|
206
|
+
size={32}
|
|
207
|
+
aria-label="Minimal action"
|
|
208
|
+
priority="minimal"
|
|
209
|
+
type="default"
|
|
210
|
+
onClick={action('button click')}
|
|
211
|
+
>
|
|
212
|
+
<Travel />
|
|
213
|
+
</IconButton>
|
|
214
|
+
<IconButton
|
|
215
|
+
size={32}
|
|
216
|
+
aria-label="Disabled action"
|
|
217
|
+
priority="primary"
|
|
218
|
+
type="default"
|
|
219
|
+
disabled
|
|
220
|
+
onClick={action('button click')}
|
|
221
|
+
>
|
|
222
|
+
<Menu />
|
|
223
|
+
</IconButton>
|
|
224
|
+
</SentimentSurface>,
|
|
225
|
+
<SentimentSurface
|
|
226
|
+
key={`${sentiment}-elevated`}
|
|
227
|
+
sentiment={sentiment}
|
|
228
|
+
emphasis="elevated"
|
|
229
|
+
style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
|
|
230
|
+
>
|
|
231
|
+
<div
|
|
232
|
+
style={{
|
|
233
|
+
width: '82px',
|
|
234
|
+
fontSize: '11px',
|
|
235
|
+
fontWeight: 'bold',
|
|
236
|
+
textAlign: 'left',
|
|
237
|
+
paddingLeft: '8px',
|
|
238
|
+
}}
|
|
239
|
+
>
|
|
240
|
+
{sentiment} (elevated)
|
|
241
|
+
</div>
|
|
242
|
+
<IconButton
|
|
243
|
+
size={32}
|
|
244
|
+
aria-label="Primary action"
|
|
245
|
+
priority="primary"
|
|
246
|
+
type="default"
|
|
247
|
+
onClick={action('button click')}
|
|
248
|
+
>
|
|
249
|
+
<Briefcase />
|
|
250
|
+
</IconButton>
|
|
251
|
+
<IconButton
|
|
252
|
+
size={32}
|
|
253
|
+
aria-label="Secondary action"
|
|
254
|
+
priority="secondary"
|
|
255
|
+
type="default"
|
|
256
|
+
onClick={action('button click')}
|
|
257
|
+
>
|
|
258
|
+
<Bank />
|
|
259
|
+
</IconButton>
|
|
260
|
+
<IconButton
|
|
261
|
+
size={32}
|
|
262
|
+
aria-label="Tertiary action"
|
|
263
|
+
priority="tertiary"
|
|
264
|
+
type="default"
|
|
265
|
+
onClick={action('button click')}
|
|
266
|
+
>
|
|
267
|
+
<Freeze />
|
|
268
|
+
</IconButton>
|
|
269
|
+
<IconButton
|
|
270
|
+
size={32}
|
|
271
|
+
aria-label="Minimal action"
|
|
272
|
+
priority="minimal"
|
|
273
|
+
type="default"
|
|
274
|
+
onClick={action('button click')}
|
|
275
|
+
>
|
|
276
|
+
<Edit />
|
|
277
|
+
</IconButton>
|
|
278
|
+
<IconButton
|
|
279
|
+
size={32}
|
|
280
|
+
aria-label="Disabled action"
|
|
281
|
+
priority="primary"
|
|
282
|
+
type="default"
|
|
283
|
+
disabled
|
|
284
|
+
onClick={action('button click')}
|
|
285
|
+
>
|
|
286
|
+
<Cross />
|
|
287
|
+
</IconButton>
|
|
288
|
+
</SentimentSurface>,
|
|
289
|
+
])}
|
|
290
|
+
</div>
|
|
159
291
|
);
|
|
160
292
|
},
|
|
161
293
|
parameters: {
|
|
@@ -166,11 +298,4 @@ export const SentimentAwareness: Story = {
|
|
|
166
298
|
},
|
|
167
299
|
},
|
|
168
300
|
},
|
|
169
|
-
decorators: [
|
|
170
|
-
(Story) => (
|
|
171
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
172
|
-
<Story />
|
|
173
|
-
</div>
|
|
174
|
-
),
|
|
175
|
-
],
|
|
176
301
|
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { Menu, Plus, Settings, Star, Travel } from '@transferwise/icons';
|
|
3
|
+
import { action } from 'storybook/actions';
|
|
4
|
+
import IconButton from './IconButton';
|
|
5
|
+
import SentimentSurface from '../sentimentSurface';
|
|
6
|
+
import { allModes } from '../../.storybook/modes';
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
title: 'Actions/IconButton/Tests',
|
|
10
|
+
component: IconButton,
|
|
11
|
+
tags: ['!autodocs', '!manifest'],
|
|
12
|
+
} satisfies Meta<typeof IconButton>;
|
|
13
|
+
|
|
14
|
+
type Story = StoryObj<typeof IconButton>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* IconButton displayed across all themes and sentiments for visual regression testing.
|
|
18
|
+
*/
|
|
19
|
+
export const AllThemesAndSentiments: Story = {
|
|
20
|
+
render: () => {
|
|
21
|
+
const priorities = ['primary', 'secondary', 'tertiary', 'minimal', 'disabled'] as const;
|
|
22
|
+
const sentiments = ['negative', 'warning', 'neutral', 'success', 'proposition'] as const;
|
|
23
|
+
const icons = [Plus, Settings, Star, Travel];
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
|
27
|
+
{/* Header row with priority labels */}
|
|
28
|
+
<div style={{ display: 'flex', alignItems: 'flex-end', marginBottom: '4px', gap: '8px' }}>
|
|
29
|
+
<div style={{ width: '82px', paddingLeft: '8px' }} />
|
|
30
|
+
{priorities.map((priority) => (
|
|
31
|
+
<div
|
|
32
|
+
key={priority}
|
|
33
|
+
style={{
|
|
34
|
+
width: '32px',
|
|
35
|
+
textAlign: 'center',
|
|
36
|
+
fontSize: '11px',
|
|
37
|
+
fontWeight: 'bold',
|
|
38
|
+
writingMode: 'vertical-rl',
|
|
39
|
+
transform: 'rotate(180deg)',
|
|
40
|
+
height: '60px',
|
|
41
|
+
display: 'flex',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
justifyContent: 'center',
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{priority}
|
|
47
|
+
</div>
|
|
48
|
+
))}
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
{/* Rows for each sentiment with base and elevated emphasis */}
|
|
52
|
+
{sentiments.flatMap((sentiment) => [
|
|
53
|
+
<SentimentSurface
|
|
54
|
+
key={`${sentiment}-base`}
|
|
55
|
+
sentiment={sentiment}
|
|
56
|
+
emphasis="base"
|
|
57
|
+
style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
|
|
58
|
+
>
|
|
59
|
+
<div
|
|
60
|
+
style={{
|
|
61
|
+
width: '82px',
|
|
62
|
+
fontSize: '11px',
|
|
63
|
+
fontWeight: 'bold',
|
|
64
|
+
textAlign: 'left',
|
|
65
|
+
paddingLeft: '8px',
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
{sentiment} (base)
|
|
69
|
+
</div>
|
|
70
|
+
<IconButton
|
|
71
|
+
size={32}
|
|
72
|
+
aria-label="Primary action"
|
|
73
|
+
priority="primary"
|
|
74
|
+
type="default"
|
|
75
|
+
onClick={action('button click')}
|
|
76
|
+
>
|
|
77
|
+
<Plus />
|
|
78
|
+
</IconButton>
|
|
79
|
+
<IconButton
|
|
80
|
+
size={32}
|
|
81
|
+
aria-label="Secondary action"
|
|
82
|
+
priority="secondary"
|
|
83
|
+
type="default"
|
|
84
|
+
onClick={action('button click')}
|
|
85
|
+
>
|
|
86
|
+
<Settings />
|
|
87
|
+
</IconButton>
|
|
88
|
+
<IconButton
|
|
89
|
+
size={32}
|
|
90
|
+
aria-label="Tertiary action"
|
|
91
|
+
priority="tertiary"
|
|
92
|
+
type="default"
|
|
93
|
+
onClick={action('button click')}
|
|
94
|
+
>
|
|
95
|
+
<Star />
|
|
96
|
+
</IconButton>
|
|
97
|
+
<IconButton
|
|
98
|
+
size={32}
|
|
99
|
+
aria-label="Minimal action"
|
|
100
|
+
priority="minimal"
|
|
101
|
+
type="default"
|
|
102
|
+
onClick={action('button click')}
|
|
103
|
+
>
|
|
104
|
+
<Travel />
|
|
105
|
+
</IconButton>
|
|
106
|
+
<IconButton
|
|
107
|
+
size={32}
|
|
108
|
+
aria-label="Disabled action"
|
|
109
|
+
priority="primary"
|
|
110
|
+
type="default"
|
|
111
|
+
disabled
|
|
112
|
+
onClick={action('button click')}
|
|
113
|
+
>
|
|
114
|
+
<Menu />
|
|
115
|
+
</IconButton>
|
|
116
|
+
</SentimentSurface>,
|
|
117
|
+
<SentimentSurface
|
|
118
|
+
key={`${sentiment}-elevated`}
|
|
119
|
+
sentiment={sentiment}
|
|
120
|
+
emphasis="elevated"
|
|
121
|
+
style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
|
|
122
|
+
>
|
|
123
|
+
<div
|
|
124
|
+
style={{
|
|
125
|
+
width: '82px',
|
|
126
|
+
fontSize: '11px',
|
|
127
|
+
fontWeight: 'bold',
|
|
128
|
+
textAlign: 'left',
|
|
129
|
+
paddingLeft: '8px',
|
|
130
|
+
}}
|
|
131
|
+
>
|
|
132
|
+
{sentiment} (elevated)
|
|
133
|
+
</div>
|
|
134
|
+
<IconButton
|
|
135
|
+
size={32}
|
|
136
|
+
aria-label="Primary action"
|
|
137
|
+
priority="primary"
|
|
138
|
+
type="default"
|
|
139
|
+
onClick={action('button click')}
|
|
140
|
+
>
|
|
141
|
+
<Plus />
|
|
142
|
+
</IconButton>
|
|
143
|
+
<IconButton
|
|
144
|
+
size={32}
|
|
145
|
+
aria-label="Secondary action"
|
|
146
|
+
priority="secondary"
|
|
147
|
+
type="default"
|
|
148
|
+
onClick={action('button click')}
|
|
149
|
+
>
|
|
150
|
+
<Settings />
|
|
151
|
+
</IconButton>
|
|
152
|
+
<IconButton
|
|
153
|
+
size={32}
|
|
154
|
+
aria-label="Tertiary action"
|
|
155
|
+
priority="tertiary"
|
|
156
|
+
type="default"
|
|
157
|
+
onClick={action('button click')}
|
|
158
|
+
>
|
|
159
|
+
<Star />
|
|
160
|
+
</IconButton>
|
|
161
|
+
<IconButton
|
|
162
|
+
size={32}
|
|
163
|
+
aria-label="Minimal action"
|
|
164
|
+
priority="minimal"
|
|
165
|
+
type="default"
|
|
166
|
+
onClick={action('button click')}
|
|
167
|
+
>
|
|
168
|
+
<Travel />
|
|
169
|
+
</IconButton>
|
|
170
|
+
<IconButton
|
|
171
|
+
size={32}
|
|
172
|
+
aria-label="Disabled action"
|
|
173
|
+
priority="primary"
|
|
174
|
+
type="default"
|
|
175
|
+
disabled
|
|
176
|
+
onClick={action('button click')}
|
|
177
|
+
>
|
|
178
|
+
<Menu />
|
|
179
|
+
</IconButton>
|
|
180
|
+
</SentimentSurface>,
|
|
181
|
+
])}
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
},
|
|
185
|
+
parameters: {
|
|
186
|
+
padding: '16px',
|
|
187
|
+
variants: ['default', 'dark', 'bright-green', 'forest-green'],
|
|
188
|
+
chromatic: {
|
|
189
|
+
dark: allModes.dark,
|
|
190
|
+
brightGreen: allModes.brightGreen,
|
|
191
|
+
forestGreen: allModes.forestGreen,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -181,6 +181,7 @@ export {
|
|
|
181
181
|
SelectInput,
|
|
182
182
|
SelectInputOptionContent,
|
|
183
183
|
SelectInputTriggerButton,
|
|
184
|
+
sortByRelevance,
|
|
184
185
|
} from './inputs/SelectInput';
|
|
185
186
|
export { TextArea } from './inputs/TextArea';
|
|
186
187
|
export { default as InstructionsList } from './instructionsList';
|
|
@@ -624,6 +624,7 @@ interface CountryWithCurrency extends Country {
|
|
|
624
624
|
const countriesWithCurrency: CountryWithCurrency[] = [
|
|
625
625
|
{ code: 'AD', name: 'Andorra', keywords: ['united states dollar'] },
|
|
626
626
|
{ code: 'DE', name: 'Germany', keywords: ['EUR'] },
|
|
627
|
+
{ code: 'NR', name: 'New United Republic', keywords: ['NUR'] },
|
|
627
628
|
{ code: 'US', name: 'United States', keywords: ['USD'] },
|
|
628
629
|
{ code: 'ZM', name: 'Zambia', keywords: ['USD', 'united states dollar'] },
|
|
629
630
|
];
|
|
@@ -649,38 +650,50 @@ export const WithCustomSearchResultSorting: Story<CountryWithCurrency> = {
|
|
|
649
650
|
value: countriesWithCurrency[0],
|
|
650
651
|
filterable: true,
|
|
651
652
|
filterPlaceholder: 'Type a currency / country',
|
|
652
|
-
sortFilteredOptions: (
|
|
653
|
-
const normalizedQuery = searchQuery.toLowerCase();
|
|
654
|
-
const nameA = a.value.name.toLowerCase();
|
|
655
|
-
const nameB = b.value.name.toLowerCase();
|
|
656
|
-
|
|
657
|
-
// Prioritize countries where name contains the search query
|
|
658
|
-
const aNameMatch = nameA.includes(normalizedQuery);
|
|
659
|
-
const bNameMatch = nameB.includes(normalizedQuery);
|
|
660
|
-
|
|
661
|
-
if (aNameMatch && !bNameMatch) return -1;
|
|
662
|
-
if (!aNameMatch && bNameMatch) return 1;
|
|
663
|
-
|
|
664
|
-
// Then sort alphabetically
|
|
665
|
-
return nameA.localeCompare(nameB);
|
|
666
|
-
},
|
|
653
|
+
sortFilteredOptions: SelectInput.sortByRelevance((value) => value.name),
|
|
667
654
|
size: 'lg',
|
|
668
655
|
} satisfies Story<CountryWithCurrency>['args'],
|
|
669
656
|
decorators: [
|
|
670
657
|
(Story) => (
|
|
671
658
|
<div>
|
|
672
659
|
<p className="m-b-3 np-text-body-default" style={{ maxWidth: '600px' }}>
|
|
673
|
-
This example
|
|
660
|
+
This example uses the built-in <code>SelectInput.sortByRelevance</code> helper to sort
|
|
661
|
+
filtered results by relevance. It prioritises: exact matches → starts with → contains →
|
|
662
|
+
alphabetical.
|
|
674
663
|
<br />
|
|
675
664
|
<br />
|
|
676
|
-
Try searching for "united"
|
|
677
|
-
provided options order.
|
|
665
|
+
Try searching for "united" to see the sorting tiers in action:
|
|
678
666
|
<br />
|
|
679
|
-
|
|
680
|
-
|
|
667
|
+
1. <strong>United States</strong> — name starts with "United"
|
|
668
|
+
<br />
|
|
669
|
+
2. <strong>New United Republic</strong> — name contains "United"
|
|
670
|
+
<br />
|
|
671
|
+
3. <strong>Andorra, Zambia</strong> — match only via keywords
|
|
681
672
|
</p>
|
|
682
673
|
<Story />
|
|
683
674
|
</div>
|
|
684
675
|
),
|
|
685
676
|
],
|
|
677
|
+
parameters: {
|
|
678
|
+
docs: {
|
|
679
|
+
source: {
|
|
680
|
+
code: `<SelectInput
|
|
681
|
+
filterable
|
|
682
|
+
filterPlaceholder="Type a currency / country"
|
|
683
|
+
sortFilteredOptions={SelectInput.sortByRelevance((value) => value.name)}
|
|
684
|
+
items={countries.map((country) => ({
|
|
685
|
+
type: 'option',
|
|
686
|
+
value: country,
|
|
687
|
+
filterMatchers: [country.name, country.code, ...country.keywords],
|
|
688
|
+
}))}
|
|
689
|
+
renderValue={(country) => (
|
|
690
|
+
<SelectInputOptionContent
|
|
691
|
+
title={country.name}
|
|
692
|
+
icon={<Flag code={country.code} />}
|
|
693
|
+
/>
|
|
694
|
+
)}
|
|
695
|
+
/>`,
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
},
|
|
686
699
|
};
|