@transferwise/components 0.0.0-experimental-a12c97e → 0.0.0-experimental-302d967
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/listItem/AvatarLayout/ListItemAvatarLayout.js +2 -0
- package/build/listItem/AvatarLayout/ListItemAvatarLayout.js.map +1 -1
- package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs +2 -0
- package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs.map +1 -1
- package/build/listItem/AvatarView/ListItemAvatarView.js +2 -0
- package/build/listItem/AvatarView/ListItemAvatarView.js.map +1 -1
- package/build/listItem/AvatarView/ListItemAvatarView.mjs +2 -0
- package/build/listItem/AvatarView/ListItemAvatarView.mjs.map +1 -1
- package/build/listItem/Image/ListItemImage.js +6 -2
- package/build/listItem/Image/ListItemImage.js.map +1 -1
- package/build/listItem/Image/ListItemImage.mjs +6 -2
- package/build/listItem/Image/ListItemImage.mjs.map +1 -1
- package/build/listItem/ListItem.js +16 -14
- package/build/listItem/ListItem.js.map +1 -1
- package/build/listItem/ListItem.mjs +16 -14
- package/build/listItem/ListItem.mjs.map +1 -1
- package/build/listItem/ListItemContext.js.map +1 -1
- package/build/listItem/ListItemContext.mjs.map +1 -1
- package/build/listItem/Navigation/ListItemNavigation.js +1 -1
- package/build/listItem/Navigation/ListItemNavigation.js.map +1 -1
- package/build/listItem/Navigation/ListItemNavigation.mjs +1 -1
- package/build/listItem/Navigation/ListItemNavigation.mjs.map +1 -1
- package/build/listItem/_stories/images/landscape.svg +1 -0
- package/build/listItem/_stories/images/portrait.svg +1 -0
- package/build/listItem/useListItemMedia.js +21 -0
- package/build/listItem/useListItemMedia.js.map +1 -0
- package/build/listItem/useListItemMedia.mjs +19 -0
- package/build/listItem/useListItemMedia.mjs.map +1 -0
- package/build/main.css +64 -101
- package/build/styles/avatarView/AvatarView.css +1 -3
- package/build/styles/listItem/ListItem.css +63 -98
- package/build/styles/listItem/ListItem.grid.css +17 -11
- package/build/styles/main.css +64 -101
- package/build/switch/Switch.js.map +1 -1
- package/build/switch/Switch.mjs.map +1 -1
- package/build/types/listItem/AvatarLayout/ListItemAvatarLayout.d.ts.map +1 -1
- package/build/types/listItem/AvatarView/ListItemAvatarView.d.ts.map +1 -1
- package/build/types/listItem/Image/ListItemImage.d.ts +1 -1
- package/build/types/listItem/Image/ListItemImage.d.ts.map +1 -1
- package/build/types/listItem/ListItem.d.ts +1 -1
- package/build/types/listItem/ListItem.d.ts.map +1 -1
- package/build/types/listItem/ListItemContext.d.ts +4 -0
- package/build/types/listItem/ListItemContext.d.ts.map +1 -1
- package/build/types/listItem/test-utils.d.ts +7 -0
- package/build/types/listItem/test-utils.d.ts.map +1 -0
- package/build/types/listItem/useListItemMedia.d.ts +6 -0
- package/build/types/listItem/useListItemMedia.d.ts.map +1 -0
- package/build/types/switch/Switch.d.ts +1 -1
- package/build/types/switch/Switch.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/avatarView/AvatarView.css +1 -3
- package/src/avatarView/AvatarView.less +1 -2
- package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.story.tsx +8 -58
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.story.tsx +0 -3
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.tsx +3 -0
- package/src/listItem/AvatarView/ListItemAvatarView.story.tsx +3 -21
- package/src/listItem/AvatarView/ListItemAvatarView.tsx +3 -0
- package/src/listItem/Button/ListItemButton.spec.tsx +10 -35
- package/src/listItem/Button/ListItemButton.story.tsx +37 -95
- package/src/listItem/Checkbox/ListItemCheckbox.story.tsx +0 -18
- package/src/listItem/IconButton/ListItemIconButton.story.tsx +2 -15
- package/src/listItem/Image/ListItemImage.spec.tsx +8 -5
- package/src/listItem/Image/ListItemImage.story.tsx +23 -6
- package/src/listItem/Image/ListItemImage.tsx +12 -4
- package/src/listItem/ListItem.css +63 -98
- package/src/listItem/ListItem.grid.css +17 -11
- package/src/listItem/ListItem.grid.less +24 -16
- package/src/listItem/ListItem.less +60 -113
- package/src/listItem/ListItem.tsx +24 -18
- package/src/listItem/ListItemContext.tsx +5 -0
- package/src/listItem/Navigation/ListItemNavigation.story.tsx +2 -5
- package/src/listItem/Navigation/ListItemNavigation.tsx +1 -1
- package/src/listItem/Radio/ListItemRadio.story.tsx +0 -10
- package/src/listItem/Switch/ListItemSwitch.story.tsx +0 -8
- package/src/listItem/_stories/ListItem.layout.test.story.tsx +142 -2
- package/src/listItem/_stories/ListItem.story.tsx +141 -243
- package/src/listItem/_stories/ListItem.variants.test.story.tsx +7 -2
- package/src/listItem/_stories/images/landscape.svg +1 -0
- package/src/listItem/_stories/images/portrait.svg +1 -0
- package/src/listItem/test-utils.tsx +33 -0
- package/src/listItem/useListItemMedia.tsx +13 -0
- package/src/main.css +64 -101
- package/src/switch/Switch.tsx +1 -1
- package/build/types/listItem/_stories/helpers.d.ts +0 -27
- package/build/types/listItem/_stories/helpers.d.ts.map +0 -1
- package/src/listItem/_stories/ListItem.scenarios.story.tsx +0 -209
- package/src/listItem/_stories/helpers.tsx +0 -53
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
border-radius: var(--radius-medium);
|
|
8
8
|
background-color: var(--color-background-screen);
|
|
9
9
|
position: relative;
|
|
10
|
-
padding: var(--size-12)
|
|
10
|
+
padding: var(--size-12);
|
|
11
11
|
container-type: inline-size;
|
|
12
12
|
|
|
13
13
|
& + .wds-list-item-spotlight,
|
|
@@ -47,6 +47,12 @@
|
|
|
47
47
|
outline: none;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
&:has(.wds-list-item-control:focus-visible),
|
|
51
|
+
&:has(input[type="checkbox"]:focus-visible) {
|
|
52
|
+
.ring();
|
|
53
|
+
outline-offset: -1px;
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
.wds-list-item-additional-info {
|
|
51
57
|
.ring-offset-0
|
|
52
58
|
}
|
|
@@ -70,102 +76,58 @@
|
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
&:not(.disabled, :disabled) {
|
|
83
|
-
&:hover {
|
|
84
|
-
background-color: var(--color-background-screen-hover);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
&:active {
|
|
88
|
-
background-color: var(--color-background-screen-active);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
&:has(.wds-list-item-prompt:hover a, .wds-list-item-prompt:hover button) {
|
|
93
|
-
&:hover {
|
|
94
|
-
background-color: unset;
|
|
79
|
+
&:not(.disabled, :disabled):hover {
|
|
80
|
+
background-color: var(--color-background-screen-hover);
|
|
81
|
+
|
|
82
|
+
.wds-list-item-control-wrapper {
|
|
83
|
+
.wds-Button {
|
|
84
|
+
background-color: var(--Button-background-hover);
|
|
85
|
+
color: var(--Button-color-hover);
|
|
86
|
+
transition: none;
|
|
87
|
+
}
|
|
95
88
|
}
|
|
96
|
-
}
|
|
97
89
|
}
|
|
98
90
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
&:not(.wds-list-item-spotlight) {
|
|
102
|
-
&:has(.wds-list-item-control:focus-visible),
|
|
103
|
-
&:has(input[type="checkbox"]:focus-visible) {
|
|
104
|
-
&:before {
|
|
105
|
-
.ring();
|
|
106
|
-
content: '';
|
|
107
|
-
position: absolute;
|
|
108
|
-
inset: 0 -8px;
|
|
109
|
-
border-radius: var(--radius-medium);
|
|
110
|
-
outline-offset: -1px;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
&:not(.disabled, :disabled) {
|
|
115
|
-
&:hover,
|
|
116
|
-
&:active {
|
|
117
|
-
&:before {
|
|
118
|
-
content: '';
|
|
119
|
-
position: absolute;
|
|
120
|
-
inset: 0 -8px;
|
|
121
|
-
border-radius: var(--radius-medium);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
&:hover:before {
|
|
126
|
-
background-color: var(--color-background-screen-hover);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
&:active:before {
|
|
130
|
-
background-color: var(--color-background-screen-active);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
&:has(.wds-list-item-prompt:hover a, .wds-list-item-prompt:hover button) {
|
|
135
|
-
&:hover:before {
|
|
136
|
-
background-color: unset;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
91
|
+
&:not(.disabled, :disabled):active {
|
|
92
|
+
background-color: var(--color-background-screen-active);
|
|
139
93
|
}
|
|
140
94
|
|
|
141
|
-
|
|
142
|
-
.wds-list-item-control-wrapper {
|
|
95
|
+
.wds-list-item-button-control {
|
|
143
96
|
.wds-Button {
|
|
144
|
-
background-color: var(--Button-background-hover);
|
|
145
|
-
color: var(--Button-color-hover);
|
|
146
97
|
transition: none;
|
|
147
98
|
}
|
|
148
99
|
}
|
|
149
|
-
}
|
|
150
100
|
|
|
151
|
-
.wds-list-item-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
101
|
+
&:has(.wds-list-item-prompt:hover a, .wds-list-item-prompt:hover button) {
|
|
102
|
+
&:hover {
|
|
103
|
+
background-color: unset;
|
|
104
|
+
}
|
|
155
105
|
}
|
|
156
106
|
}
|
|
157
107
|
|
|
158
108
|
&-media {
|
|
159
109
|
grid-area: media;
|
|
110
|
+
display: flex;
|
|
111
|
+
align-items: center;
|
|
160
112
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
113
|
+
&-image-wrapper {
|
|
114
|
+
width: var(--wds-list-item-media-size);
|
|
115
|
+
height: var(--wds-list-item-media-size);
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: center;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
&-image {
|
|
122
|
+
width: 100%;
|
|
123
|
+
height: 100%;
|
|
124
|
+
object-fit: contain;
|
|
125
|
+
}
|
|
165
126
|
}
|
|
166
127
|
|
|
167
128
|
&-body {
|
|
168
129
|
grid-area: body;
|
|
130
|
+
align-items: center;
|
|
169
131
|
width: 100%;
|
|
170
132
|
display: grid;
|
|
171
133
|
grid-template-columns: var(--wds-list-item-body-left, 1fr) var(--wds-list-item-body-right, max-content);
|
|
@@ -173,8 +135,18 @@
|
|
|
173
135
|
word-break: break-word;
|
|
174
136
|
}
|
|
175
137
|
|
|
176
|
-
&-title
|
|
177
|
-
|
|
138
|
+
&-title {
|
|
139
|
+
color: var(--color-content-primary);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
&-value {
|
|
143
|
+
text-align: right;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
&-body-center {
|
|
147
|
+
display: flex;
|
|
148
|
+
flex-direction: row;
|
|
149
|
+
align-items: center;
|
|
178
150
|
}
|
|
179
151
|
|
|
180
152
|
&-additional-info {
|
|
@@ -183,13 +155,16 @@
|
|
|
183
155
|
margin-top: calc(var(--size-4) * -1);
|
|
184
156
|
}
|
|
185
157
|
|
|
186
|
-
&-value {
|
|
187
|
-
align-items: end;
|
|
188
|
-
text-align: right;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
158
|
&-control-wrapper {
|
|
192
159
|
grid-area: control;
|
|
160
|
+
align-content: center;
|
|
161
|
+
// max-height: var(--wds-list-item-control-wrapper-height);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&-navigation {
|
|
165
|
+
.tw-icon-chevron-right {
|
|
166
|
+
color: var(--color-interactive-secondary);
|
|
167
|
+
}
|
|
193
168
|
}
|
|
194
169
|
|
|
195
170
|
&-control {
|
|
@@ -212,9 +187,6 @@
|
|
|
212
187
|
|
|
213
188
|
|
|
214
189
|
&-spotlight {
|
|
215
|
-
padding-left: var(--size-12);
|
|
216
|
-
padding-right: var(--size-12);
|
|
217
|
-
|
|
218
190
|
&-active {
|
|
219
191
|
background-color: var(--color-background-neutral);
|
|
220
192
|
&:not(.disabled, :disabled):hover {
|
|
@@ -227,7 +199,7 @@
|
|
|
227
199
|
|
|
228
200
|
&-inactive {
|
|
229
201
|
background-color: color-mix(in srgb, var(--color-background-neutral) 25%, transparent);
|
|
230
|
-
|
|
202
|
+
border: 1px dashed var(--color-border-neutral);
|
|
231
203
|
&:not(.disabled, :disabled):hover {
|
|
232
204
|
background-color: color-mix(in srgb, var(--color-background-neutral-hover) 25%, transparent);
|
|
233
205
|
}
|
|
@@ -237,31 +209,6 @@
|
|
|
237
209
|
}
|
|
238
210
|
}
|
|
239
211
|
|
|
240
|
-
.wds-list-item-spotlight__border{
|
|
241
|
-
position: absolute;
|
|
242
|
-
inset:0;
|
|
243
|
-
width: 100%;
|
|
244
|
-
height: 100%;
|
|
245
|
-
|
|
246
|
-
rect {
|
|
247
|
-
--wds-list-item-spotlight-borderWidth: 1px;
|
|
248
|
-
--wds-list-item-spotlight-borderWidthOffset: .5px; // half of the border width to center the border
|
|
249
|
-
--wds-list-item-spotlight-strokeDashSize: calc(var(--size-12) * .5);
|
|
250
|
-
|
|
251
|
-
fill: none;
|
|
252
|
-
stroke: var(--color-border-neutral);
|
|
253
|
-
width: calc(100% - var(--wds-list-item-spotlight-borderWidth));
|
|
254
|
-
height: calc(100% - var(--wds-list-item-spotlight-borderWidth));
|
|
255
|
-
x: var(--wds-list-item-spotlight-borderWidthOffset);
|
|
256
|
-
y: var(--wds-list-item-spotlight-borderWidthOffset);
|
|
257
|
-
rx: calc(var(--radius-medium) - var(--wds-list-item-spotlight-borderWidthOffset));
|
|
258
|
-
ry: calc(var(--radius-medium) - var(--wds-list-item-spotlight-borderWidthOffset));
|
|
259
|
-
stroke-dasharray:
|
|
260
|
-
var(--wds-list-item-spotlight-strokeDashSize)
|
|
261
|
-
var(--wds-list-item-spotlight-strokeDashSize);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
212
|
&-prompt {
|
|
266
213
|
grid-area: prompt;
|
|
267
214
|
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
useId,
|
|
5
5
|
useMemo,
|
|
6
6
|
useState,
|
|
7
|
+
useEffect,
|
|
7
8
|
type PropsWithChildren,
|
|
8
9
|
type ReactNode,
|
|
9
10
|
} from 'react';
|
|
@@ -22,7 +23,11 @@ import { AvatarView } from './AvatarView';
|
|
|
22
23
|
import { Image } from './Image';
|
|
23
24
|
import { Prompt } from './Prompt';
|
|
24
25
|
import { PrimitiveAnchor } from '../primitives';
|
|
25
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
ListItemContext,
|
|
28
|
+
type ListItemContextData,
|
|
29
|
+
type ListItemMediaSize,
|
|
30
|
+
} from './ListItemContext';
|
|
26
31
|
|
|
27
32
|
export type ListItemTypes =
|
|
28
33
|
| 'non-interactive'
|
|
@@ -119,6 +124,8 @@ export const ListItem = ({
|
|
|
119
124
|
const idPrefix = useId();
|
|
120
125
|
const [controlProps, setControlProps] = useState<ListItemControlProps>({});
|
|
121
126
|
const [controlType, setControlType] = useState<ListItemTypes>('non-interactive');
|
|
127
|
+
const [mediaSize, setMediaSize] = useState<ListItemMediaSize | undefined>();
|
|
128
|
+
|
|
122
129
|
const ids: ListItemContextData['ids'] = {
|
|
123
130
|
title: `${idPrefix}_title`,
|
|
124
131
|
...(subtitle ? { subtitle: `${idPrefix}_subtitle` } : {}),
|
|
@@ -156,11 +163,13 @@ export const ListItem = ({
|
|
|
156
163
|
() => ({
|
|
157
164
|
setControlType,
|
|
158
165
|
setControlProps,
|
|
166
|
+
setMediaSize,
|
|
159
167
|
ids,
|
|
160
168
|
props: { disabled, inverted },
|
|
169
|
+
mediaSize,
|
|
161
170
|
describedByIds,
|
|
162
171
|
}),
|
|
163
|
-
[describedByIds],
|
|
172
|
+
[describedByIds, mediaSize],
|
|
164
173
|
);
|
|
165
174
|
const gridColumnsStyle = {
|
|
166
175
|
'--wds-list-item-body-left': valueColumnWidth ? `${100 - valueColumnWidth}fr` : '50fr',
|
|
@@ -227,12 +236,6 @@ export const ListItem = ({
|
|
|
227
236
|
aria-disabled={disabled}
|
|
228
237
|
aria-labelledby={ariaLabelledby}
|
|
229
238
|
>
|
|
230
|
-
{spotlight === 'inactive' && (
|
|
231
|
-
<svg aria-hidden="true" className="wds-list-item-spotlight__border">
|
|
232
|
-
<rect />
|
|
233
|
-
</svg>
|
|
234
|
-
)}
|
|
235
|
-
|
|
236
239
|
<View
|
|
237
240
|
{...{
|
|
238
241
|
isPartiallyInteractive,
|
|
@@ -253,7 +256,11 @@ export const ListItem = ({
|
|
|
253
256
|
style={valueColumnWidth ? gridColumnsStyle : undefined}
|
|
254
257
|
>
|
|
255
258
|
{/* Title + Subtitle + Values - Group */}
|
|
256
|
-
<span
|
|
259
|
+
<span
|
|
260
|
+
className={clsx({
|
|
261
|
+
'wds-list-item-body-center': title && !subtitle,
|
|
262
|
+
})}
|
|
263
|
+
>
|
|
257
264
|
{(() => {
|
|
258
265
|
const titles = [
|
|
259
266
|
<Body
|
|
@@ -280,6 +287,8 @@ export const ListItem = ({
|
|
|
280
287
|
<span
|
|
281
288
|
className={clsx('wds-list-item-value', {
|
|
282
289
|
'flex-column': valueTitle !== undefined || valueSubtitle !== undefined,
|
|
290
|
+
'wds-list-item-body-center':
|
|
291
|
+
(valueTitle && !valueSubtitle) || (!valueTitle && valueSubtitle),
|
|
283
292
|
})}
|
|
284
293
|
>
|
|
285
294
|
{(() => {
|
|
@@ -318,6 +327,11 @@ export const ListItem = ({
|
|
|
318
327
|
className={clsx('wds-list-item-control-wrapper', {
|
|
319
328
|
'wds-list-item-button-control': controlType === 'button',
|
|
320
329
|
})}
|
|
330
|
+
style={
|
|
331
|
+
{
|
|
332
|
+
'--wds-list-item-control-wrapper-height': mediaSize ? `${mediaSize}px` : 'auto',
|
|
333
|
+
} as React.CSSProperties
|
|
334
|
+
}
|
|
321
335
|
>
|
|
322
336
|
{control}
|
|
323
337
|
</Body>
|
|
@@ -370,7 +384,6 @@ function View({
|
|
|
370
384
|
href={(controlProps as ListItemNavigationProps)?.href}
|
|
371
385
|
target={(controlProps as ListItemNavigationProps)?.target}
|
|
372
386
|
className={clsx('wds-list-item-view d-flex flex-row', {
|
|
373
|
-
'align-items-center': !subtitle,
|
|
374
387
|
'wds-list-item-control': controlType === 'navigation',
|
|
375
388
|
})}
|
|
376
389
|
disabled={disabled}
|
|
@@ -386,13 +399,7 @@ function View({
|
|
|
386
399
|
if (isPartiallyInteractive || controlType === 'non-interactive') {
|
|
387
400
|
return (
|
|
388
401
|
<div className={clsx('wds-list-item-gridWrapper', className)}>
|
|
389
|
-
<div
|
|
390
|
-
className={clsx('wds-list-item-view d-flex flex-row', {
|
|
391
|
-
'align-items-center': !subtitle,
|
|
392
|
-
})}
|
|
393
|
-
>
|
|
394
|
-
{children}
|
|
395
|
-
</div>
|
|
402
|
+
<div className={clsx('wds-list-item-view d-flex flex-row')}>{children}</div>
|
|
396
403
|
|
|
397
404
|
{renderExtras()}
|
|
398
405
|
</div>
|
|
@@ -407,7 +414,6 @@ function View({
|
|
|
407
414
|
<label
|
|
408
415
|
htmlFor={ids.control}
|
|
409
416
|
className={clsx('wds-list-item-view', {
|
|
410
|
-
'align-items-center': !subtitle,
|
|
411
417
|
clickable: !disabled,
|
|
412
418
|
fullyInteractive: !isPartiallyInteractive,
|
|
413
419
|
})}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { createContext } from 'react';
|
|
2
2
|
import type { ListItemTypes, ListItemControlProps, Props as ListItemProps } from './ListItem';
|
|
3
|
+
import type { ListItemAvatarViewProps } from './AvatarView';
|
|
4
|
+
|
|
5
|
+
export type ListItemMediaSize = 32 | 40 | 48 | 56 | 72;
|
|
3
6
|
|
|
4
7
|
export type ListItemContextData = {
|
|
5
8
|
setControlType: (type: ListItemTypes) => void;
|
|
6
9
|
setControlProps: (props: ListItemControlProps) => void;
|
|
10
|
+
setMediaSize: (size: ListItemMediaSize | undefined) => void;
|
|
7
11
|
ids: {
|
|
8
12
|
title: string;
|
|
9
13
|
subtitle?: string;
|
|
@@ -14,6 +18,7 @@ export type ListItemContextData = {
|
|
|
14
18
|
prompt?: string;
|
|
15
19
|
};
|
|
16
20
|
props: Pick<ListItemProps, 'disabled' | 'inverted'>;
|
|
21
|
+
mediaSize?: ListItemAvatarViewProps['size'];
|
|
17
22
|
describedByIds: string;
|
|
18
23
|
};
|
|
19
24
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import { fn } from 'storybook/test';
|
|
3
|
-
import { lorem10 } from '../../test-utils';
|
|
4
2
|
import { ListItem } from '../ListItem';
|
|
5
3
|
import {
|
|
6
4
|
SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
|
|
@@ -8,6 +6,8 @@ import {
|
|
|
8
6
|
SB_LIST_ITEM_MEDIA as MEDIA,
|
|
9
7
|
} from '../_stories/subcomponents';
|
|
10
8
|
import type { ListItemNavigationProps } from './ListItemNavigation';
|
|
9
|
+
import { lorem10 } from '../../test-utils';
|
|
10
|
+
import { fn } from 'storybook/test';
|
|
11
11
|
|
|
12
12
|
const meta: Meta<ListItemNavigationProps> = {
|
|
13
13
|
component: ListItem.Navigation,
|
|
@@ -62,9 +62,6 @@ export const AsButton: Story = {
|
|
|
62
62
|
args: {
|
|
63
63
|
onClick: fn(),
|
|
64
64
|
},
|
|
65
|
-
parameters: {
|
|
66
|
-
controls: { disable: true },
|
|
67
|
-
},
|
|
68
65
|
render: (args) => {
|
|
69
66
|
return (
|
|
70
67
|
<ol className="list-unstyled">
|
|
@@ -19,7 +19,7 @@ export const Navigation = function Navigation({ href = '#', ...props }: ListItem
|
|
|
19
19
|
const { baseItemProps } = useListItemControl('navigation', { href, ...props });
|
|
20
20
|
const { ids, describedByIds } = useContext(ListItemContext);
|
|
21
21
|
const isLink = href !== '#';
|
|
22
|
-
const icon = <ChevronRight size={
|
|
22
|
+
const icon = <ChevronRight size={16} />;
|
|
23
23
|
|
|
24
24
|
if (baseItemProps.disabled) return <BackslashCircle size={24} />;
|
|
25
25
|
|
|
@@ -23,13 +23,6 @@ const meta: Meta<ListItemRadioProps> = {
|
|
|
23
23
|
checked: false,
|
|
24
24
|
onChange: fn(),
|
|
25
25
|
},
|
|
26
|
-
argTypes: {
|
|
27
|
-
onChange: {
|
|
28
|
-
table: {
|
|
29
|
-
type: { summary: '(value: string | number) => void' },
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
26
|
} satisfies Meta<ListItemRadioProps>;
|
|
34
27
|
|
|
35
28
|
export default meta;
|
|
@@ -55,9 +48,6 @@ export const Playground: Story = {
|
|
|
55
48
|
* Radio controls follow the native HTML behaviour and can be grouped using the `name` prop.
|
|
56
49
|
*/
|
|
57
50
|
export const RadioGroup: Story = {
|
|
58
|
-
parameters: {
|
|
59
|
-
controls: { disable: true },
|
|
60
|
-
},
|
|
61
51
|
render: function Render() {
|
|
62
52
|
const [selectedValue, setSelectedValue] = useState('2');
|
|
63
53
|
|
|
@@ -25,11 +25,6 @@ const meta: Meta<ListItemSwitchProps> = {
|
|
|
25
25
|
checked: {
|
|
26
26
|
control: 'boolean',
|
|
27
27
|
},
|
|
28
|
-
onClick: {
|
|
29
|
-
table: {
|
|
30
|
-
type: { summary: '(event?: MouseEvent<HTMLButtonElement>) => void' },
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
28
|
},
|
|
34
29
|
} satisfies Meta<ListItemSwitchProps>;
|
|
35
30
|
|
|
@@ -53,9 +48,6 @@ export const Playground: Story = {
|
|
|
53
48
|
};
|
|
54
49
|
|
|
55
50
|
export const States: Story = {
|
|
56
|
-
parameters: {
|
|
57
|
-
controls: { disable: true },
|
|
58
|
-
},
|
|
59
51
|
render: (args) => {
|
|
60
52
|
return (
|
|
61
53
|
<ol className="list-unstyled">
|
|
@@ -2,8 +2,12 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
|
2
2
|
import { Bank, FastFlag, MultiCurrency, Receipt, Savings } from '@transferwise/icons';
|
|
3
3
|
import Link from '../../link';
|
|
4
4
|
import { ListItem, Props as ItemProps } from '../ListItem';
|
|
5
|
-
import { lorem10, lorem5 } from '../../test-utils';
|
|
5
|
+
import { lorem10, lorem20, lorem5 } from '../../test-utils';
|
|
6
6
|
import { SB_LIST_ITEM_CONTROLS as CONTROLS, SB_LIST_ITEM_MEDIA as MEDIA } from './subcomponents';
|
|
7
|
+
import portraitImage from './images/portrait.svg';
|
|
8
|
+
import landscapeImage from './images/landscape.svg';
|
|
9
|
+
import type { ListItemButtonProps } from '../Button';
|
|
10
|
+
import { ListItemMediaSize } from '../ListItemContext';
|
|
7
11
|
|
|
8
12
|
const withSizedContainer = (width: number) => (Story: any) => (
|
|
9
13
|
<ol
|
|
@@ -20,7 +24,6 @@ const withSizedContainer = (width: number) => (Story: any) => (
|
|
|
20
24
|
);
|
|
21
25
|
|
|
22
26
|
export default {
|
|
23
|
-
component: ListItem,
|
|
24
27
|
title: 'Content/ListItem/tests/layout',
|
|
25
28
|
tags: ['!autodocs'],
|
|
26
29
|
parameters: {
|
|
@@ -187,3 +190,140 @@ export const GapsBetweenItems: Story = {
|
|
|
187
190
|
);
|
|
188
191
|
},
|
|
189
192
|
};
|
|
193
|
+
|
|
194
|
+
type PreviewStoryArgs = ItemProps & {
|
|
195
|
+
previewImageSize: ListItemMediaSize;
|
|
196
|
+
previewWithLineGuides: boolean;
|
|
197
|
+
previewPrompt: boolean | ItemProps['prompt'];
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const previewArgGroup = {
|
|
201
|
+
category: 'Preview options',
|
|
202
|
+
type: {
|
|
203
|
+
summary: undefined,
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const previewArgTypes = {
|
|
208
|
+
previewImageSize: {
|
|
209
|
+
options: [32, 40, 48, 56, 72],
|
|
210
|
+
control: {
|
|
211
|
+
type: 'inline-radio',
|
|
212
|
+
},
|
|
213
|
+
name: 'Preview with image size',
|
|
214
|
+
table: previewArgGroup,
|
|
215
|
+
},
|
|
216
|
+
previewWithLineGuides: {
|
|
217
|
+
control: {
|
|
218
|
+
type: 'boolean',
|
|
219
|
+
},
|
|
220
|
+
name: 'Preview with line guides',
|
|
221
|
+
table: previewArgGroup,
|
|
222
|
+
},
|
|
223
|
+
previewPrompt: {
|
|
224
|
+
control: {
|
|
225
|
+
type: 'boolean',
|
|
226
|
+
},
|
|
227
|
+
mapping: {
|
|
228
|
+
true: <ListItem.Prompt sentiment="positive">This is a prompt</ListItem.Prompt>,
|
|
229
|
+
false: null,
|
|
230
|
+
},
|
|
231
|
+
name: 'Preview with `prompt`',
|
|
232
|
+
table: previewArgGroup,
|
|
233
|
+
},
|
|
234
|
+
} as const;
|
|
235
|
+
|
|
236
|
+
const getPropsForPreview = (args: PreviewStoryArgs) => {
|
|
237
|
+
const { previewImageSize, previewWithLineGuides, previewPrompt, ...props } = args as {
|
|
238
|
+
previewImageSize: ListItemMediaSize;
|
|
239
|
+
previewWithLineGuides: boolean;
|
|
240
|
+
previewPrompt: boolean | ItemProps['prompt'];
|
|
241
|
+
[key: string]: any;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
return [
|
|
245
|
+
{
|
|
246
|
+
...props,
|
|
247
|
+
prompt: previewPrompt,
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
previewImageSize,
|
|
251
|
+
previewWithLineGuides,
|
|
252
|
+
},
|
|
253
|
+
] as const;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// Create a completely untyped story object
|
|
257
|
+
const ImageAlignmentStory: StoryObj<PreviewStoryArgs> = {
|
|
258
|
+
parameters: {
|
|
259
|
+
controls: { disable: false },
|
|
260
|
+
},
|
|
261
|
+
args: {
|
|
262
|
+
previewImageSize: 48,
|
|
263
|
+
previewWithLineGuides: true,
|
|
264
|
+
previewPrompt: false,
|
|
265
|
+
},
|
|
266
|
+
argTypes: previewArgTypes,
|
|
267
|
+
decorators: [
|
|
268
|
+
(Story: any, { args }: { args: PreviewStoryArgs }) => (
|
|
269
|
+
<>
|
|
270
|
+
{args.previewWithLineGuides && (
|
|
271
|
+
<style
|
|
272
|
+
dangerouslySetInnerHTML={{
|
|
273
|
+
__html: `
|
|
274
|
+
.wds-list-item-media-image-wrapper::after {
|
|
275
|
+
content: '';
|
|
276
|
+
border: 1px dashed red;
|
|
277
|
+
position: absolute;
|
|
278
|
+
left: 0;
|
|
279
|
+
width: 100%;
|
|
280
|
+
height: ${args.previewImageSize}px;
|
|
281
|
+
}
|
|
282
|
+
`,
|
|
283
|
+
}}
|
|
284
|
+
/>
|
|
285
|
+
)}
|
|
286
|
+
<Story />
|
|
287
|
+
</>
|
|
288
|
+
),
|
|
289
|
+
],
|
|
290
|
+
render: (args: PreviewStoryArgs) => {
|
|
291
|
+
const [props, previewProps] = getPropsForPreview(args);
|
|
292
|
+
|
|
293
|
+
const title = lorem5;
|
|
294
|
+
const subtitle = lorem10;
|
|
295
|
+
const additionalInfo = <ListItem.AdditionalInfo>{lorem20}</ListItem.AdditionalInfo>;
|
|
296
|
+
const control = CONTROLS.button;
|
|
297
|
+
const size = previewProps.previewImageSize;
|
|
298
|
+
|
|
299
|
+
const instances = [
|
|
300
|
+
{ title, ...props },
|
|
301
|
+
{ title, subtitle, ...props },
|
|
302
|
+
{ title, subtitle, additionalInfo, ...props },
|
|
303
|
+
{ title, control, ...props },
|
|
304
|
+
{ title, subtitle, control, ...props },
|
|
305
|
+
{ title, subtitle, additionalInfo, control, ...props },
|
|
306
|
+
] as const;
|
|
307
|
+
|
|
308
|
+
return (
|
|
309
|
+
<ol className="list-unstyled">
|
|
310
|
+
{instances.map((itemProps, index) => (
|
|
311
|
+
<ListItem
|
|
312
|
+
key={`landscape-${index}`}
|
|
313
|
+
{...itemProps}
|
|
314
|
+
media={<ListItem.Image size={size} src={landscapeImage} alt="landscape image" />}
|
|
315
|
+
/>
|
|
316
|
+
))}
|
|
317
|
+
{instances.map((itemProps, index) => (
|
|
318
|
+
<ListItem
|
|
319
|
+
key={`portrait-${index}`}
|
|
320
|
+
{...itemProps}
|
|
321
|
+
media={<ListItem.Image size={size} src={portraitImage} alt="portrait image" />}
|
|
322
|
+
/>
|
|
323
|
+
))}
|
|
324
|
+
</ol>
|
|
325
|
+
);
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
export const ImageAlignment = ImageAlignmentStory;
|