@transferwise/components 0.0.0-experimental-e1870f3 → 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/flowNavigation/animatedLabel/AnimatedLabel.js +2 -2
- package/build/flowNavigation/animatedLabel/AnimatedLabel.js.map +1 -1
- package/build/flowNavigation/animatedLabel/AnimatedLabel.mjs +2 -2
- package/build/flowNavigation/animatedLabel/AnimatedLabel.mjs.map +1 -1
- package/build/index.js +2 -2
- package/build/index.mjs +1 -1
- package/build/{listItem → legacylistItem}/List.js +2 -3
- package/build/legacylistItem/List.js.map +1 -0
- package/build/{listItem → legacylistItem}/List.mjs +2 -3
- package/build/legacylistItem/List.mjs.map +1 -0
- 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/types/index.d.ts +4 -4
- package/build/types/index.d.ts.map +1 -1
- package/build/types/legacylistItem/List.d.ts +6 -0
- package/build/types/legacylistItem/List.d.ts.map +1 -0
- package/build/types/legacylistItem/index.d.ts +2 -0
- package/build/types/legacylistItem/index.d.ts.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/index.d.ts +0 -2
- package/build/types/listItem/index.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/package.json +1 -1
- package/src/avatarView/AvatarView.css +1 -3
- package/src/avatarView/AvatarView.less +1 -2
- package/src/flowNavigation/animatedLabel/AnimatedLabel.tsx +1 -1
- package/src/index.ts +4 -9
- package/src/legacylistItem/LegacyListItem.story.tsx +2 -2
- package/src/legacylistItem/LegacyListItem.tests.story.tsx +1 -2
- package/src/legacylistItem/List.tsx +10 -0
- package/src/legacylistItem/index.ts +2 -0
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.story.tsx +4 -5
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.tsx +3 -0
- package/src/listItem/AvatarView/ListItemAvatarView.story.tsx +4 -5
- package/src/listItem/AvatarView/ListItemAvatarView.tsx +3 -0
- package/src/listItem/Button/ListItemButton.spec.tsx +10 -35
- package/src/listItem/Button/ListItemButton.story.tsx +8 -9
- package/src/listItem/IconButton/ListItemIconButton.story.tsx +8 -8
- 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.tsx +1 -1
- package/src/listItem/Prompt/ListItemPrompt.story.tsx +7 -7
- package/src/listItem/Switch/ListItemSwitch.story.tsx +2 -3
- package/src/listItem/_stories/ListItem.layout.test.story.tsx +142 -2
- package/src/listItem/_stories/ListItem.story.tsx +7 -45
- package/src/listItem/_stories/ListItem.variants.test.story.tsx +11 -7
- package/src/listItem/_stories/images/landscape.svg +1 -0
- package/src/listItem/_stories/images/portrait.svg +1 -0
- package/src/listItem/index.ts +0 -3
- package/src/listItem/test-utils.tsx +33 -0
- package/src/listItem/useListItemMedia.tsx +13 -0
- package/src/main.css +64 -101
- package/build/listItem/List.js.map +0 -1
- package/build/listItem/List.mjs.map +0 -1
- package/build/types/listItem/List.d.ts +0 -7
- package/build/types/listItem/List.d.ts.map +0 -1
- package/src/listItem/List.tsx +0 -11
- package/src/listItem/_stories/ListItem.scenarios.story.tsx +0 -226
package/package.json
CHANGED
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
right: 0;
|
|
20
20
|
}
|
|
21
21
|
.np-avatar-view .np-avatar-view-content {
|
|
22
|
-
color:
|
|
23
|
-
color: var(--color-content-primary);
|
|
22
|
+
color: var(--color-interactive-primary);
|
|
24
23
|
}
|
|
25
24
|
.np-avatar-view-interactive {
|
|
26
25
|
cursor: pointer;
|
|
@@ -28,7 +27,6 @@
|
|
|
28
27
|
.np-avatar-view-interactive .np-circle {
|
|
29
28
|
background-color: rgba(134,167,189,0.10196);
|
|
30
29
|
background-color: var(--color-background-neutral);
|
|
31
|
-
color: var(--color-interactive-primary);
|
|
32
30
|
}
|
|
33
31
|
.np-avatar-view-non-interactive .np-circle {
|
|
34
32
|
background-color: transparent;
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
.np-avatar-view {
|
|
4
4
|
.np-avatar-view-content {
|
|
5
|
-
color: var(--color-
|
|
5
|
+
color: var(--color-interactive-primary);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
&-interactive {
|
|
9
9
|
cursor: pointer;
|
|
10
10
|
.np-circle {
|
|
11
11
|
background-color: var(--color-background-neutral);
|
|
12
|
-
color: var(--color-interactive-primary);
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -6,7 +6,7 @@ import BottomSheet from '../../common/bottomSheet';
|
|
|
6
6
|
import Option from '../../common/Option';
|
|
7
7
|
import { Check, ChevronDown } from '@transferwise/icons';
|
|
8
8
|
import { OverlayIdContext, OverlayIdProvider } from '../../provider/overlay/OverlayIdProvider';
|
|
9
|
-
import { List } from '../../
|
|
9
|
+
import { List } from '../../legacylistItem';
|
|
10
10
|
|
|
11
11
|
export interface AnimatedLabelProps {
|
|
12
12
|
activeLabel: number;
|
package/src/index.ts
CHANGED
|
@@ -50,7 +50,7 @@ export type {
|
|
|
50
50
|
export type { TextAreaProps } from './inputs/TextArea';
|
|
51
51
|
export type { InstructionsListProps } from './instructionsList';
|
|
52
52
|
export type { LabelProps, LabelOptionalProps, LabelDescriptionProps } from './label/Label';
|
|
53
|
-
export type { LegacyListItemProps } from './legacylistItem';
|
|
53
|
+
export type { ListProps, LegacyListItemProps } from './legacylistItem';
|
|
54
54
|
export type { LoaderProps } from './loader';
|
|
55
55
|
export type { MarkdownProps } from './markdown';
|
|
56
56
|
export type { ModalProps } from './modal';
|
|
@@ -108,12 +108,7 @@ export type {
|
|
|
108
108
|
TableCellStatus,
|
|
109
109
|
TableCellType,
|
|
110
110
|
} from './table';
|
|
111
|
-
export type {
|
|
112
|
-
ListItemProps,
|
|
113
|
-
ListProps,
|
|
114
|
-
ListItemAdditionalInfoProps,
|
|
115
|
-
ListItemCheckboxProps,
|
|
116
|
-
} from './listItem';
|
|
111
|
+
export type { ListItemProps, ListItemAdditionalInfoProps, ListItemCheckboxProps } from './listItem';
|
|
117
112
|
|
|
118
113
|
/**
|
|
119
114
|
* Components
|
|
@@ -171,7 +166,7 @@ export { TextArea } from './inputs/TextArea';
|
|
|
171
166
|
export { default as InstructionsList } from './instructionsList';
|
|
172
167
|
export { Label } from './label/Label';
|
|
173
168
|
export { default as Link } from './link';
|
|
174
|
-
export { default as LegacyListItem } from './legacylistItem';
|
|
169
|
+
export { List, default as LegacyListItem } from './legacylistItem';
|
|
175
170
|
export { default as Loader } from './loader';
|
|
176
171
|
export { default as Logo } from './logo';
|
|
177
172
|
export { default as Markdown } from './markdown';
|
|
@@ -215,7 +210,7 @@ export { default as Typeahead } from './typeahead';
|
|
|
215
210
|
export { default as Upload } from './upload';
|
|
216
211
|
export { default as UploadInput } from './uploadInput';
|
|
217
212
|
export { default as Table } from './table';
|
|
218
|
-
export { default as ListItem
|
|
213
|
+
export { default as ListItem } from './listItem';
|
|
219
214
|
|
|
220
215
|
/**
|
|
221
216
|
* Hooks
|
|
@@ -2,11 +2,11 @@ import { action } from 'storybook/actions';
|
|
|
2
2
|
import { Documents, FastFlag } from '@transferwise/icons';
|
|
3
3
|
import { ComponentProps } from 'react';
|
|
4
4
|
|
|
5
|
-
import { Button, IconButton
|
|
5
|
+
import { Button, IconButton } from '..';
|
|
6
6
|
import AvatarView from '../avatarView';
|
|
7
7
|
import Info from '../info';
|
|
8
8
|
import Title from '../title/Title';
|
|
9
|
-
import LegacyListItem from '.';
|
|
9
|
+
import LegacyListItem, { List } from '.';
|
|
10
10
|
|
|
11
11
|
export default {
|
|
12
12
|
component: LegacyListItem,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { FastFlag } from '@transferwise/icons';
|
|
2
2
|
import Button from '../button';
|
|
3
3
|
import AvatarView from '../avatarView';
|
|
4
|
-
import LegacyListItem, { type LegacyListItemProps } from '.';
|
|
5
|
-
import { List } from '../listItem';
|
|
4
|
+
import LegacyListItem, { List, type LegacyListItemProps } from '.';
|
|
6
5
|
|
|
7
6
|
export default {
|
|
8
7
|
component: LegacyListItem,
|
|
@@ -2,7 +2,6 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
|
2
2
|
import { Flag } from '@wise/art';
|
|
3
3
|
import { lorem10 } from '../../test-utils';
|
|
4
4
|
import { ListItem } from '../ListItem';
|
|
5
|
-
import { List } from '../List';
|
|
6
5
|
import {
|
|
7
6
|
SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
|
|
8
7
|
SB_LIST_ITEM_CONTROLS as CONTROLS,
|
|
@@ -66,7 +65,7 @@ export const Playground: Story = {
|
|
|
66
65
|
export const Orientations: Story = {
|
|
67
66
|
render: (args) => {
|
|
68
67
|
return (
|
|
69
|
-
<
|
|
68
|
+
<ol className="list-unstyled">
|
|
70
69
|
<ListItem
|
|
71
70
|
title="Horizontal orientation"
|
|
72
71
|
subtitle={lorem10}
|
|
@@ -80,7 +79,7 @@ export const Orientations: Story = {
|
|
|
80
79
|
media={<ListItem.AvatarLayout {...args} orientation="diagonal" />}
|
|
81
80
|
control={CONTROLS.iconButton}
|
|
82
81
|
/>
|
|
83
|
-
</
|
|
82
|
+
</ol>
|
|
84
83
|
);
|
|
85
84
|
},
|
|
86
85
|
};
|
|
@@ -101,7 +100,7 @@ export const Sizes: Story = {
|
|
|
101
100
|
const orientations = ['horizontal', 'diagonal'] as const;
|
|
102
101
|
|
|
103
102
|
return (
|
|
104
|
-
<
|
|
103
|
+
<ol className="list-unstyled">
|
|
105
104
|
{orientations.map((orientation) =>
|
|
106
105
|
sizes.map((size) => (
|
|
107
106
|
<ListItem
|
|
@@ -113,7 +112,7 @@ export const Sizes: Story = {
|
|
|
113
112
|
/>
|
|
114
113
|
)),
|
|
115
114
|
)}
|
|
116
|
-
</
|
|
115
|
+
</ol>
|
|
117
116
|
);
|
|
118
117
|
},
|
|
119
118
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import AvatarLayoutComp, { type AvatarLayoutProps } from '../../avatarLayout';
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
|
+
import { useListItemMedia } from '../useListItemMedia';
|
|
3
4
|
|
|
4
5
|
type SizeProp = { size?: 32 | 40 | 48 | 56 | 72 };
|
|
5
6
|
|
|
@@ -13,6 +14,8 @@ export type ListItemAvatarLayoutProps = Omit<AvatarLayoutProps, 'size' | 'intera
|
|
|
13
14
|
* Please refer to the [Design documentation](https://wise.design/components/list-item#avatar) for details.
|
|
14
15
|
*/
|
|
15
16
|
export const AvatarLayout = ({ className, size = 48, ...props }: ListItemAvatarLayoutProps) => {
|
|
17
|
+
useListItemMedia(size);
|
|
18
|
+
|
|
16
19
|
return (
|
|
17
20
|
<AvatarLayoutComp
|
|
18
21
|
{...props}
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
import { ListItemAvatarViewProps } from './ListItemAvatarView';
|
|
9
9
|
import { lorem10 } from '../../test-utils';
|
|
10
10
|
import { ProfileType } from '../../common';
|
|
11
|
-
import { List } from '../List';
|
|
12
11
|
|
|
13
12
|
const SIZES = [32, 40, 48, 56, 72] as const;
|
|
14
13
|
const BADGES = {
|
|
@@ -213,7 +212,7 @@ export const Sizes: Story = {
|
|
|
213
212
|
},
|
|
214
213
|
render: (args) => {
|
|
215
214
|
return (
|
|
216
|
-
<
|
|
215
|
+
<ol className="list-unstyled">
|
|
217
216
|
{SIZES.map((size) => (
|
|
218
217
|
<ListItem
|
|
219
218
|
key={size}
|
|
@@ -227,7 +226,7 @@ export const Sizes: Story = {
|
|
|
227
226
|
control={CONTROLS.iconButton}
|
|
228
227
|
/>
|
|
229
228
|
))}
|
|
230
|
-
</
|
|
229
|
+
</ol>
|
|
231
230
|
);
|
|
232
231
|
},
|
|
233
232
|
};
|
|
@@ -249,7 +248,7 @@ export const Notification: Story = {
|
|
|
249
248
|
},
|
|
250
249
|
render: (args) => {
|
|
251
250
|
return (
|
|
252
|
-
<
|
|
251
|
+
<ol className="list-unstyled">
|
|
253
252
|
{SIZES.map((size) => (
|
|
254
253
|
<ListItem
|
|
255
254
|
key={size}
|
|
@@ -263,7 +262,7 @@ export const Notification: Story = {
|
|
|
263
262
|
control={CONTROLS.iconButton}
|
|
264
263
|
/>
|
|
265
264
|
))}
|
|
266
|
-
</
|
|
265
|
+
</ol>
|
|
267
266
|
);
|
|
268
267
|
},
|
|
269
268
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import AvatarViewComp, { AvatarViewProps } from '../../avatarView';
|
|
3
|
+
import { useListItemMedia } from '../useListItemMedia';
|
|
3
4
|
|
|
4
5
|
export type ListItemAvatarViewProps = Omit<AvatarViewProps, 'size' | 'interactive'> & {
|
|
5
6
|
size?: 32 | 40 | 48 | 56 | 72;
|
|
@@ -13,6 +14,8 @@ export type ListItemAvatarViewProps = Omit<AvatarViewProps, 'size' | 'interactiv
|
|
|
13
14
|
* Please refer to the [Design documentation](https://wise.design/components/list-item#avatar) for details.
|
|
14
15
|
*/
|
|
15
16
|
export const AvatarView = ({ className, size = 48, ...props }: ListItemAvatarViewProps) => {
|
|
17
|
+
useListItemMedia(size);
|
|
18
|
+
|
|
16
19
|
return (
|
|
17
20
|
<AvatarViewComp
|
|
18
21
|
{...props}
|
|
@@ -1,49 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { screen, mockMatchMedia } from '../../test-utils';
|
|
2
2
|
import { Button as ItemButton } from './ListItemButton';
|
|
3
3
|
import { ButtonPriority } from '../../button/Button.types';
|
|
4
|
-
import {
|
|
4
|
+
import { renderWithListItemContext, clearListItemMocks, mockSetControlType } from '../test-utils';
|
|
5
5
|
|
|
6
6
|
mockMatchMedia();
|
|
7
7
|
|
|
8
8
|
describe('ItemButton', () => {
|
|
9
|
-
const mockSetControlType = jest.fn();
|
|
10
|
-
const mockSetControlProps = jest.fn();
|
|
11
|
-
|
|
12
|
-
const renderWithItemContext = (ui: React.ReactNode) => {
|
|
13
|
-
return render(
|
|
14
|
-
<ListItemContext.Provider
|
|
15
|
-
value={{
|
|
16
|
-
setControlType: mockSetControlType,
|
|
17
|
-
setControlProps: mockSetControlProps,
|
|
18
|
-
ids: {
|
|
19
|
-
title: 'title',
|
|
20
|
-
additionalInfo: 'additional Info',
|
|
21
|
-
valueTitle: 'value title',
|
|
22
|
-
control: 'control',
|
|
23
|
-
prompt: 'prompt',
|
|
24
|
-
},
|
|
25
|
-
props: {},
|
|
26
|
-
describedByIds: 'described-by-ids',
|
|
27
|
-
}}
|
|
28
|
-
>
|
|
29
|
-
{ui}
|
|
30
|
-
</ListItemContext.Provider>,
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
9
|
beforeEach(() => {
|
|
35
|
-
|
|
10
|
+
clearListItemMocks();
|
|
36
11
|
});
|
|
37
12
|
|
|
38
13
|
it('always sets v2 to true', () => {
|
|
39
|
-
|
|
14
|
+
renderWithListItemContext(<ItemButton priority="primary">Test Button</ItemButton>);
|
|
40
15
|
const button = screen.getByRole('button');
|
|
41
16
|
expect(button).toBeInTheDocument();
|
|
42
17
|
expect(mockSetControlType).toHaveBeenCalledWith('button');
|
|
43
18
|
});
|
|
44
19
|
|
|
45
20
|
it('always sets size to "sm"', () => {
|
|
46
|
-
|
|
21
|
+
renderWithListItemContext(<ItemButton priority="primary">Test Button</ItemButton>);
|
|
47
22
|
const button = screen.getByRole('button');
|
|
48
23
|
expect(button).toHaveClass('wds-Button--small');
|
|
49
24
|
});
|
|
@@ -51,21 +26,21 @@ describe('ItemButton', () => {
|
|
|
51
26
|
it('supports all priorities', () => {
|
|
52
27
|
const priorities: ButtonPriority[] = ['primary', 'secondary', 'tertiary'];
|
|
53
28
|
priorities.forEach((priority) => {
|
|
54
|
-
|
|
29
|
+
renderWithListItemContext(<ItemButton priority={priority}>Test {priority}</ItemButton>);
|
|
55
30
|
const button = screen.getByRole('button', { name: `Test ${priority}` });
|
|
56
31
|
expect(button).toBeInTheDocument();
|
|
57
32
|
});
|
|
58
33
|
});
|
|
59
34
|
|
|
60
35
|
it('renders as a button by default', () => {
|
|
61
|
-
|
|
36
|
+
renderWithListItemContext(<ItemButton>Click me</ItemButton>);
|
|
62
37
|
const button = screen.getByRole('button');
|
|
63
38
|
expect(button).toBeInTheDocument();
|
|
64
39
|
expect(button.tagName).toBe('BUTTON');
|
|
65
40
|
});
|
|
66
41
|
|
|
67
42
|
it('renders as an anchor when href is provided', () => {
|
|
68
|
-
|
|
43
|
+
renderWithListItemContext(<ItemButton href="https://example.com">Go to Example</ItemButton>);
|
|
69
44
|
const link = screen.getByRole('link', { name: 'Go to Example' });
|
|
70
45
|
expect(link).toBeInTheDocument();
|
|
71
46
|
expect(link.tagName).toBe('A');
|
|
@@ -73,14 +48,14 @@ describe('ItemButton', () => {
|
|
|
73
48
|
});
|
|
74
49
|
|
|
75
50
|
it('spreads additional props to the button', () => {
|
|
76
|
-
|
|
51
|
+
renderWithListItemContext(<ItemButton aria-label="Custom Button">Custom</ItemButton>);
|
|
77
52
|
const button = screen.getByRole('button', { name: 'Custom Button' });
|
|
78
53
|
expect(button).toBeInTheDocument();
|
|
79
54
|
expect(button).toHaveAttribute('aria-label', 'Custom Button');
|
|
80
55
|
});
|
|
81
56
|
|
|
82
57
|
it('spreads additional props to the anchor', () => {
|
|
83
|
-
|
|
58
|
+
renderWithListItemContext(
|
|
84
59
|
<ItemButton href="https://example.com" target="_blank" aria-label="Custom Link">
|
|
85
60
|
Custom Link
|
|
86
61
|
</ItemButton>,
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
SB_LIST_ITEM_MEDIA as MEDIA,
|
|
8
8
|
} from '../_stories/subcomponents';
|
|
9
9
|
import type { ListItemButtonProps } from './ListItemButton';
|
|
10
|
-
import { List } from '../List';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Convenience controls for previewing rich markup,
|
|
@@ -182,7 +181,7 @@ export const Interactivity: Story = {
|
|
|
182
181
|
},
|
|
183
182
|
render: (args: ListItemButtonProps) => {
|
|
184
183
|
return (
|
|
185
|
-
<
|
|
184
|
+
<ol className="list-unstyled">
|
|
186
185
|
<ListItem
|
|
187
186
|
title="Fully interactive ListItem"
|
|
188
187
|
subtitle="Button in fully interactive context"
|
|
@@ -196,7 +195,7 @@ export const Interactivity: Story = {
|
|
|
196
195
|
media={MEDIA.avatarSingle}
|
|
197
196
|
control={<ListItem.Button {...args} partiallyInteractive />}
|
|
198
197
|
/>
|
|
199
|
-
</
|
|
198
|
+
</ol>
|
|
200
199
|
);
|
|
201
200
|
},
|
|
202
201
|
};
|
|
@@ -231,7 +230,7 @@ export const AsAnchor: Story = {
|
|
|
231
230
|
export const Sentiment: Story = {
|
|
232
231
|
render: (args: ListItemButtonProps) => {
|
|
233
232
|
return (
|
|
234
|
-
<
|
|
233
|
+
<ol className="list-unstyled">
|
|
235
234
|
<ListItem
|
|
236
235
|
title="Default Sentiment - Primary"
|
|
237
236
|
subtitle="Default sentiment with primary priority"
|
|
@@ -272,7 +271,7 @@ export const Sentiment: Story = {
|
|
|
272
271
|
</ListItem.Button>
|
|
273
272
|
}
|
|
274
273
|
/>
|
|
275
|
-
</
|
|
274
|
+
</ol>
|
|
276
275
|
);
|
|
277
276
|
},
|
|
278
277
|
args: {
|
|
@@ -288,7 +287,7 @@ export const Sentiment: Story = {
|
|
|
288
287
|
export const Priority: Story = {
|
|
289
288
|
render: (args: ListItemButtonProps) => {
|
|
290
289
|
return (
|
|
291
|
-
<
|
|
290
|
+
<ol className="list-unstyled">
|
|
292
291
|
<ListItem
|
|
293
292
|
title="Primary Priority"
|
|
294
293
|
subtitle="Primary priority (default)"
|
|
@@ -329,7 +328,7 @@ export const Priority: Story = {
|
|
|
329
328
|
</ListItem.Button>
|
|
330
329
|
}
|
|
331
330
|
/>
|
|
332
|
-
</
|
|
331
|
+
</ol>
|
|
333
332
|
);
|
|
334
333
|
},
|
|
335
334
|
args: {
|
|
@@ -369,7 +368,7 @@ const addonProps = {
|
|
|
369
368
|
export const WithIcons: Story = {
|
|
370
369
|
render: (args: ListItemButtonProps) => {
|
|
371
370
|
return (
|
|
372
|
-
<
|
|
371
|
+
<ol className="list-unstyled">
|
|
373
372
|
<ListItem
|
|
374
373
|
title="With Start Icon"
|
|
375
374
|
subtitle="Button with icon before the label"
|
|
@@ -400,7 +399,7 @@ export const WithIcons: Story = {
|
|
|
400
399
|
</ListItem.Button>
|
|
401
400
|
}
|
|
402
401
|
/>
|
|
403
|
-
</
|
|
402
|
+
</ol>
|
|
404
403
|
);
|
|
405
404
|
},
|
|
406
405
|
args: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import { Edit, Heart } from '@transferwise/icons';
|
|
3
|
+
import { ListItem } from '../ListItem';
|
|
4
4
|
import {
|
|
5
5
|
SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
|
|
6
6
|
SB_LIST_ITEM_MEDIA as MEDIA,
|
|
@@ -114,7 +114,7 @@ export const Interactivity: Story = {
|
|
|
114
114
|
},
|
|
115
115
|
render: (args: ListItemIconButtonProps) => {
|
|
116
116
|
return (
|
|
117
|
-
<
|
|
117
|
+
<ol className="list-unstyled">
|
|
118
118
|
<ListItem
|
|
119
119
|
control={<ListItem.IconButton {...args} />}
|
|
120
120
|
title="Fully interactive ListItem"
|
|
@@ -132,7 +132,7 @@ export const Interactivity: Story = {
|
|
|
132
132
|
additionalInfo={INFO.interactive}
|
|
133
133
|
prompt={PROMPTS.interactive}
|
|
134
134
|
/>
|
|
135
|
-
</
|
|
135
|
+
</ol>
|
|
136
136
|
);
|
|
137
137
|
},
|
|
138
138
|
};
|
|
@@ -145,7 +145,7 @@ export const Interactivity: Story = {
|
|
|
145
145
|
export const Sentiment: Story = {
|
|
146
146
|
render: (args) => {
|
|
147
147
|
return (
|
|
148
|
-
<
|
|
148
|
+
<ol className="list-unstyled">
|
|
149
149
|
<ListItem
|
|
150
150
|
control={<ListItem.IconButton {...args} priority="primary" type="default" />}
|
|
151
151
|
title="Default Sentiment - Primary"
|
|
@@ -170,7 +170,7 @@ export const Sentiment: Story = {
|
|
|
170
170
|
subtitle="Negative sentiment with secondary priority"
|
|
171
171
|
media={MEDIA.avatarSingle}
|
|
172
172
|
/>
|
|
173
|
-
</
|
|
173
|
+
</ol>
|
|
174
174
|
);
|
|
175
175
|
},
|
|
176
176
|
};
|
|
@@ -183,7 +183,7 @@ export const Sentiment: Story = {
|
|
|
183
183
|
export const Priority: Story = {
|
|
184
184
|
render: (args) => {
|
|
185
185
|
return (
|
|
186
|
-
<
|
|
186
|
+
<ol className="list-unstyled">
|
|
187
187
|
<ListItem
|
|
188
188
|
title="Primary Priority"
|
|
189
189
|
subtitle="Primary priority (default)"
|
|
@@ -208,7 +208,7 @@ export const Priority: Story = {
|
|
|
208
208
|
media={MEDIA.avatarSingle}
|
|
209
209
|
control={<ListItem.IconButton {...args} priority="minimal" />}
|
|
210
210
|
/>
|
|
211
|
-
</
|
|
211
|
+
</ol>
|
|
212
212
|
);
|
|
213
213
|
},
|
|
214
214
|
};
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { render, screen } from '../../test-utils';
|
|
2
|
-
import { ListItem } from '../ListItem';
|
|
2
|
+
import { ListItem, type Props as ListItemProps } from '../ListItem';
|
|
3
|
+
|
|
4
|
+
const renderWithMedia = (media: ListItemProps['media']) =>
|
|
5
|
+
render(<ListItem title="Test Title" media={media} />);
|
|
3
6
|
|
|
4
7
|
describe('ListItem.Image', () => {
|
|
5
8
|
it('renders image with presentation role when no alt text', () => {
|
|
6
|
-
|
|
9
|
+
renderWithMedia(<ListItem.Image src="test-image.jpg" />);
|
|
7
10
|
expect(screen.getByRole('presentation')).toHaveAttribute('src', 'test-image.jpg');
|
|
8
11
|
});
|
|
9
12
|
|
|
10
13
|
it('renders image with graphics-symbol role when alt text provided', () => {
|
|
11
|
-
|
|
14
|
+
renderWithMedia(<ListItem.Image src="test-image.jpg" alt="Test image description" />);
|
|
12
15
|
|
|
13
16
|
const image = screen.getByRole('graphics-symbol');
|
|
14
17
|
expect(image).toHaveAttribute('alt', 'Test image description');
|
|
@@ -16,12 +19,12 @@ describe('ListItem.Image', () => {
|
|
|
16
19
|
});
|
|
17
20
|
|
|
18
21
|
it('renders image with loading prop', () => {
|
|
19
|
-
|
|
22
|
+
renderWithMedia(<ListItem.Image src="test-image.jpg" loading="lazy" />);
|
|
20
23
|
expect(screen.getByRole('presentation')).toHaveAttribute('loading', 'lazy');
|
|
21
24
|
});
|
|
22
25
|
|
|
23
26
|
it('renders image with className prop', () => {
|
|
24
|
-
|
|
27
|
+
renderWithMedia(<ListItem.Image src="test-image.jpg" className="custom-image-class" />);
|
|
25
28
|
expect(screen.getByRole('presentation')).toHaveClass('custom-image-class');
|
|
26
29
|
});
|
|
27
30
|
});
|
|
@@ -6,6 +6,12 @@ import {
|
|
|
6
6
|
} from '../_stories/subcomponents';
|
|
7
7
|
import { ListItemImageProps } from './ListItemImage';
|
|
8
8
|
|
|
9
|
+
const IMAGE_URLS = {
|
|
10
|
+
portrait: 'https://cdn-icons-png.flaticon.com/512/656/656404.png',
|
|
11
|
+
landscape:
|
|
12
|
+
'https://wise.com/public-resources/assets/spend/card-asset/medium/v2/personal_green_wise_2023_active.svg',
|
|
13
|
+
};
|
|
14
|
+
|
|
9
15
|
export default {
|
|
10
16
|
component: ListItem.Image,
|
|
11
17
|
title: 'Content/ListItem/ListItem.Image',
|
|
@@ -15,22 +21,33 @@ export default {
|
|
|
15
21
|
},
|
|
16
22
|
},
|
|
17
23
|
args: {
|
|
18
|
-
src:
|
|
19
|
-
size:
|
|
24
|
+
src: IMAGE_URLS.landscape,
|
|
25
|
+
size: 72,
|
|
20
26
|
loading: undefined,
|
|
21
27
|
alt: undefined,
|
|
28
|
+
imageOrientation: 'landscape' as keyof typeof IMAGE_URLS,
|
|
22
29
|
},
|
|
23
|
-
|
|
30
|
+
argTypes: {
|
|
31
|
+
imageOrientation: {
|
|
32
|
+
control: { type: 'radio' },
|
|
33
|
+
options: ['portrait', 'landscape'],
|
|
34
|
+
description: 'Switch between portrait and landscape images',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
} satisfies Meta<ListItemImageProps & { imageOrientation: keyof typeof IMAGE_URLS }>;
|
|
24
38
|
|
|
25
|
-
type Story = StoryObj<ListItemImageProps>;
|
|
39
|
+
type Story = StoryObj<ListItemImageProps & { imageOrientation: keyof typeof IMAGE_URLS }>;
|
|
26
40
|
|
|
27
41
|
export const Playground: Story = {
|
|
28
|
-
render: (args: ListItemImageProps) => {
|
|
42
|
+
render: (args: ListItemImageProps & { imageOrientation: keyof typeof IMAGE_URLS }) => {
|
|
43
|
+
const { imageOrientation, ...imageProps } = args;
|
|
44
|
+
const src = IMAGE_URLS[imageOrientation];
|
|
45
|
+
|
|
29
46
|
return (
|
|
30
47
|
<ListItem
|
|
31
48
|
title="List item title"
|
|
32
49
|
subtitle="Subtitle goes here"
|
|
33
|
-
media={<ListItem.Image {...
|
|
50
|
+
media={<ListItem.Image {...imageProps} src={src} />}
|
|
34
51
|
control={CONTROLS.partialButton}
|
|
35
52
|
additionalInfo={INFO.nonInteractive}
|
|
36
53
|
/>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ImageComp, { type ImageProps } from '../../image';
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
|
+
import { useListItemMedia } from '../useListItemMedia';
|
|
3
4
|
|
|
4
5
|
type SizeProp = {};
|
|
5
6
|
|
|
@@ -23,17 +24,24 @@ export type ListItemImageProps = Omit<ImageProps, 'stretch' | 'shrink' | 'id' |
|
|
|
23
24
|
*
|
|
24
25
|
* > **NB**: This component is [not intended for use with illustrations](https://wise.design/foundations/illustration#scale).
|
|
25
26
|
*/
|
|
26
|
-
export const Image = ({ alt = '', size = 48, ...props }: ListItemImageProps) => {
|
|
27
|
+
export const Image = ({ alt = '', size = 48, className, ...props }: ListItemImageProps) => {
|
|
28
|
+
useListItemMedia(size);
|
|
29
|
+
|
|
27
30
|
return (
|
|
28
31
|
<div
|
|
29
|
-
className={clsx('wds-list-item-media-image')}
|
|
32
|
+
className={clsx('wds-list-item-media-image-wrapper')}
|
|
30
33
|
style={
|
|
31
34
|
{
|
|
32
|
-
'--item-media-
|
|
35
|
+
'--wds-list-item-media-size': `${size}px`,
|
|
33
36
|
} as React.CSSProperties
|
|
34
37
|
}
|
|
35
38
|
>
|
|
36
|
-
<ImageComp
|
|
39
|
+
<ImageComp
|
|
40
|
+
{...props}
|
|
41
|
+
className={clsx(className, 'wds-list-item-media-image')}
|
|
42
|
+
alt={alt}
|
|
43
|
+
role={alt ? 'graphics-symbol' : 'presentation'}
|
|
44
|
+
/>
|
|
37
45
|
</div>
|
|
38
46
|
);
|
|
39
47
|
};
|