@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.
Files changed (87) hide show
  1. package/build/listItem/AvatarLayout/ListItemAvatarLayout.js +2 -0
  2. package/build/listItem/AvatarLayout/ListItemAvatarLayout.js.map +1 -1
  3. package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs +2 -0
  4. package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs.map +1 -1
  5. package/build/listItem/AvatarView/ListItemAvatarView.js +2 -0
  6. package/build/listItem/AvatarView/ListItemAvatarView.js.map +1 -1
  7. package/build/listItem/AvatarView/ListItemAvatarView.mjs +2 -0
  8. package/build/listItem/AvatarView/ListItemAvatarView.mjs.map +1 -1
  9. package/build/listItem/Image/ListItemImage.js +6 -2
  10. package/build/listItem/Image/ListItemImage.js.map +1 -1
  11. package/build/listItem/Image/ListItemImage.mjs +6 -2
  12. package/build/listItem/Image/ListItemImage.mjs.map +1 -1
  13. package/build/listItem/ListItem.js +16 -14
  14. package/build/listItem/ListItem.js.map +1 -1
  15. package/build/listItem/ListItem.mjs +16 -14
  16. package/build/listItem/ListItem.mjs.map +1 -1
  17. package/build/listItem/ListItemContext.js.map +1 -1
  18. package/build/listItem/ListItemContext.mjs.map +1 -1
  19. package/build/listItem/Navigation/ListItemNavigation.js +1 -1
  20. package/build/listItem/Navigation/ListItemNavigation.js.map +1 -1
  21. package/build/listItem/Navigation/ListItemNavigation.mjs +1 -1
  22. package/build/listItem/Navigation/ListItemNavigation.mjs.map +1 -1
  23. package/build/listItem/_stories/images/landscape.svg +1 -0
  24. package/build/listItem/_stories/images/portrait.svg +1 -0
  25. package/build/listItem/useListItemMedia.js +21 -0
  26. package/build/listItem/useListItemMedia.js.map +1 -0
  27. package/build/listItem/useListItemMedia.mjs +19 -0
  28. package/build/listItem/useListItemMedia.mjs.map +1 -0
  29. package/build/main.css +64 -101
  30. package/build/styles/avatarView/AvatarView.css +1 -3
  31. package/build/styles/listItem/ListItem.css +63 -98
  32. package/build/styles/listItem/ListItem.grid.css +17 -11
  33. package/build/styles/main.css +64 -101
  34. package/build/switch/Switch.js.map +1 -1
  35. package/build/switch/Switch.mjs.map +1 -1
  36. package/build/types/listItem/AvatarLayout/ListItemAvatarLayout.d.ts.map +1 -1
  37. package/build/types/listItem/AvatarView/ListItemAvatarView.d.ts.map +1 -1
  38. package/build/types/listItem/Image/ListItemImage.d.ts +1 -1
  39. package/build/types/listItem/Image/ListItemImage.d.ts.map +1 -1
  40. package/build/types/listItem/ListItem.d.ts +1 -1
  41. package/build/types/listItem/ListItem.d.ts.map +1 -1
  42. package/build/types/listItem/ListItemContext.d.ts +4 -0
  43. package/build/types/listItem/ListItemContext.d.ts.map +1 -1
  44. package/build/types/listItem/test-utils.d.ts +7 -0
  45. package/build/types/listItem/test-utils.d.ts.map +1 -0
  46. package/build/types/listItem/useListItemMedia.d.ts +6 -0
  47. package/build/types/listItem/useListItemMedia.d.ts.map +1 -0
  48. package/build/types/switch/Switch.d.ts +1 -1
  49. package/build/types/switch/Switch.d.ts.map +1 -1
  50. package/package.json +3 -3
  51. package/src/avatarView/AvatarView.css +1 -3
  52. package/src/avatarView/AvatarView.less +1 -2
  53. package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.story.tsx +8 -58
  54. package/src/listItem/AvatarLayout/ListItemAvatarLayout.story.tsx +0 -3
  55. package/src/listItem/AvatarLayout/ListItemAvatarLayout.tsx +3 -0
  56. package/src/listItem/AvatarView/ListItemAvatarView.story.tsx +3 -21
  57. package/src/listItem/AvatarView/ListItemAvatarView.tsx +3 -0
  58. package/src/listItem/Button/ListItemButton.spec.tsx +10 -35
  59. package/src/listItem/Button/ListItemButton.story.tsx +37 -95
  60. package/src/listItem/Checkbox/ListItemCheckbox.story.tsx +0 -18
  61. package/src/listItem/IconButton/ListItemIconButton.story.tsx +2 -15
  62. package/src/listItem/Image/ListItemImage.spec.tsx +8 -5
  63. package/src/listItem/Image/ListItemImage.story.tsx +23 -6
  64. package/src/listItem/Image/ListItemImage.tsx +12 -4
  65. package/src/listItem/ListItem.css +63 -98
  66. package/src/listItem/ListItem.grid.css +17 -11
  67. package/src/listItem/ListItem.grid.less +24 -16
  68. package/src/listItem/ListItem.less +60 -113
  69. package/src/listItem/ListItem.tsx +24 -18
  70. package/src/listItem/ListItemContext.tsx +5 -0
  71. package/src/listItem/Navigation/ListItemNavigation.story.tsx +2 -5
  72. package/src/listItem/Navigation/ListItemNavigation.tsx +1 -1
  73. package/src/listItem/Radio/ListItemRadio.story.tsx +0 -10
  74. package/src/listItem/Switch/ListItemSwitch.story.tsx +0 -8
  75. package/src/listItem/_stories/ListItem.layout.test.story.tsx +142 -2
  76. package/src/listItem/_stories/ListItem.story.tsx +141 -243
  77. package/src/listItem/_stories/ListItem.variants.test.story.tsx +7 -2
  78. package/src/listItem/_stories/images/landscape.svg +1 -0
  79. package/src/listItem/_stories/images/portrait.svg +1 -0
  80. package/src/listItem/test-utils.tsx +33 -0
  81. package/src/listItem/useListItemMedia.tsx +13 -0
  82. package/src/main.css +64 -101
  83. package/src/switch/Switch.tsx +1 -1
  84. package/build/types/listItem/_stories/helpers.d.ts +0 -27
  85. package/build/types/listItem/_stories/helpers.d.ts.map +0 -1
  86. package/src/listItem/_stories/ListItem.scenarios.story.tsx +0 -209
  87. package/src/listItem/_stories/helpers.tsx +0 -53
@@ -6,7 +6,6 @@ import {
6
6
  SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
7
7
  SB_LIST_ITEM_CONTROLS as CONTROLS,
8
8
  } from '../_stories/subcomponents';
9
- import { disableControls } from '../_stories/helpers';
10
9
  import { ListItemAvatarLayoutProps } from './ListItemAvatarLayout';
11
10
 
12
11
  export default {
@@ -64,7 +63,6 @@ export const Playground: Story = {
64
63
  * Please refer to the [design documentation](https://wise.design/components/avatar#double) for more details.
65
64
  */
66
65
  export const Orientations: Story = {
67
- argTypes: disableControls()(['orientation']),
68
66
  render: (args) => {
69
67
  return (
70
68
  <ol className="list-unstyled">
@@ -97,7 +95,6 @@ export const Sizes: Story = {
97
95
  },
98
96
  },
99
97
  },
100
- argTypes: disableControls()(['size', 'orientation']),
101
98
  render: (args) => {
102
99
  const sizes = [32, 40, 48, 56, 72] as const;
103
100
  const orientations = ['horizontal', 'diagonal'] as const;
@@ -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}
@@ -1,16 +1,13 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import { Leaf, Taxi } from '@transferwise/icons';
3
- import { lorem10 } from '../../test-utils';
4
- import { ProfileType } from '../../common';
5
3
  import { ListItem } from '../ListItem';
6
4
  import {
7
5
  SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
8
6
  SB_LIST_ITEM_CONTROLS as CONTROLS,
9
7
  } from '../_stories/subcomponents';
10
- import { disableControls } from '../_stories/helpers';
11
8
  import { ListItemAvatarViewProps } from './ListItemAvatarView';
12
-
13
- const hideControls = disableControls(['badge', 'children']);
9
+ import { lorem10 } from '../../test-utils';
10
+ import { ProfileType } from '../../common';
14
11
 
15
12
  const SIZES = [32, 40, 48, 56, 72] as const;
16
13
  const BADGES = {
@@ -81,11 +78,8 @@ export default {
81
78
  },
82
79
  profileType: {
83
80
  control: 'select',
84
- options: [ProfileType.PERSONAL, ProfileType.BUSINESS],
81
+ options: ['personal', 'business'],
85
82
  description: 'Type of profile for default icons',
86
- table: {
87
- type: { summary: 'ProfileType' },
88
- },
89
83
  },
90
84
  notification: {
91
85
  control: 'boolean',
@@ -139,7 +133,6 @@ export const ContentTypes: Story = {
139
133
  args: {
140
134
  badge: undefined,
141
135
  },
142
- argTypes: hideControls(['profileName', 'imgSrc', 'profileType']),
143
136
  parameters: {
144
137
  docs: {
145
138
  canvas: {
@@ -217,7 +210,6 @@ export const Sizes: Story = {
217
210
  },
218
211
  },
219
212
  },
220
- argTypes: hideControls(['profileName', 'imgSrc', 'profileType', 'size']),
221
213
  render: (args) => {
222
214
  return (
223
215
  <ol className="list-unstyled">
@@ -254,14 +246,6 @@ export const Notification: Story = {
254
246
  args: {
255
247
  badge: undefined,
256
248
  },
257
- argTypes: hideControls([
258
- 'profileName',
259
- 'imgSrc',
260
- 'profileType',
261
- 'size',
262
- 'notification',
263
- 'selected',
264
- ]),
265
249
  render: (args) => {
266
250
  return (
267
251
  <ol className="list-unstyled">
@@ -291,7 +275,6 @@ export const Badges: Story = {
291
275
  args: {
292
276
  imgSrc: '../avatar-square-dude.webp',
293
277
  },
294
- argTypes: hideControls(['profileName', 'imgSrc', 'profileType', 'notification', 'selected']),
295
278
  parameters: {
296
279
  docs: {
297
280
  canvas: {
@@ -320,7 +303,6 @@ export const Badges: Story = {
320
303
  * AvatarView supports selected state for interactive contexts.
321
304
  */
322
305
  export const Selected: Story = {
323
- argTypes: hideControls(['profileName', 'imgSrc', 'profileType', 'notification', 'selected']),
324
306
  render: (args) => {
325
307
  return (
326
308
  <ol className="list-unstyled">
@@ -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 { render, screen, mockMatchMedia } from '../../test-utils';
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 { ListItemContext } from '../ListItemContext';
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
- jest.clearAllMocks();
10
+ clearListItemMocks();
36
11
  });
37
12
 
38
13
  it('always sets v2 to true', () => {
39
- renderWithItemContext(<ItemButton priority="primary">Test Button</ItemButton>);
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
- renderWithItemContext(<ItemButton priority="primary">Test Button</ItemButton>);
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
- renderWithItemContext(<ItemButton priority={priority}>Test {priority}</ItemButton>);
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
- renderWithItemContext(<ItemButton>Click me</ItemButton>);
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
- renderWithItemContext(<ItemButton href="https://example.com">Go to Example</ItemButton>);
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
- renderWithItemContext(<ItemButton aria-label="Custom Button">Custom</ItemButton>);
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
- renderWithItemContext(
58
+ renderWithListItemContext(
84
59
  <ItemButton href="https://example.com" target="_blank" aria-label="Custom Link">
85
60
  Custom Link
86
61
  </ItemButton>,
@@ -7,15 +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 { disableControls } from '../_stories/helpers';
11
-
12
- const hideControls = disableControls([
13
- 'onClick',
14
- 'children',
15
- 'className',
16
- 'addonStart',
17
- 'addonEnd',
18
- ]);
19
10
 
20
11
  /**
21
12
  * Convenience controls for previewing rich markup,
@@ -137,11 +128,6 @@ const meta: Meta<typeof ListItem.Button> = {
137
128
  addonEnd: {
138
129
  description: 'Icon accessory to be displayed after the label',
139
130
  },
140
- onClick: {
141
- table: {
142
- type: { summary: '(event: MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => void' },
143
- },
144
- },
145
131
  },
146
132
  } satisfies Meta<ListItemButtonProps>;
147
133
 
@@ -189,33 +175,25 @@ export const Playground: StoryObj<PreviewStoryArgs> = {
189
175
  *
190
176
  * Refer to the [design documentation](https://wise.design/components/list-item#interaction) for details.
191
177
  */
192
- export const Interactivity: StoryObj<PreviewStoryArgs> = {
178
+ export const Interactivity: Story = {
193
179
  args: {
194
180
  children: 'Action',
195
- previewAddonStart: false,
196
- previewAddonEnd: false,
197
181
  },
198
- argTypes: {
199
- ...hideControls(['partiallyInteractive']),
200
- ...previewArgTypes,
201
- },
202
- render: (args: PreviewStoryArgs) => {
203
- const [props, previewProps] = getPropsForPreview(args);
204
-
182
+ render: (args: ListItemButtonProps) => {
205
183
  return (
206
184
  <ol className="list-unstyled">
207
185
  <ListItem
208
186
  title="Fully interactive ListItem"
209
187
  subtitle="Button in fully interactive context"
210
188
  media={MEDIA.avatarSingle}
211
- control={<ListItem.Button {...props} {...previewProps} />}
189
+ control={<ListItem.Button {...args} />}
212
190
  />
213
191
 
214
192
  <ListItem
215
193
  title="Partially interactive ListItem"
216
194
  subtitle="Button in partially interactive context"
217
195
  media={MEDIA.avatarSingle}
218
- control={<ListItem.Button {...props} {...previewProps} partiallyInteractive />}
196
+ control={<ListItem.Button {...args} partiallyInteractive />}
219
197
  />
220
198
  </ol>
221
199
  );
@@ -225,27 +203,20 @@ export const Interactivity: StoryObj<PreviewStoryArgs> = {
225
203
  /**
226
204
  * If `href` prop is set, the component will be automatically rendered as an HTML anchor element.
227
205
  */
228
- export const AsAnchor: StoryObj<PreviewStoryArgs> = {
206
+ export const AsAnchor: Story = {
229
207
  args: {
230
208
  children: 'Visit link',
231
209
  href: 'https://wise.com',
232
210
  target: '_blank',
233
- previewAddonStart: false,
234
- previewAddonEnd: false,
235
211
  },
236
- argTypes: {
237
- ...hideControls(['partiallyInteractive']),
238
- ...previewArgTypes,
239
- },
240
- render: (args: PreviewStoryArgs) => {
241
- const [props, previewProps] = getPropsForPreview(args);
242
-
212
+ render: (args: ListItemButtonProps) => {
243
213
  return (
244
214
  <ListItem
245
- title="List item with a Button control"
246
- subtitle="But it renders as HTML anchor element"
215
+ title="List item with button link"
216
+ subtitle="Button rendered as anchor element"
247
217
  media={MEDIA.avatarSingle}
248
- control={<ListItem.Button {...props} {...previewProps} />}
218
+ control={<ListItem.Button {...args} />}
219
+ additionalInfo={INFO.nonInteractive}
249
220
  />
250
221
  );
251
222
  },
@@ -256,19 +227,8 @@ export const AsAnchor: StoryObj<PreviewStoryArgs> = {
256
227
  * **NB:** Sentiment only applies to `primary` and `secondary` priorities. <br />
257
228
  * [Design documentation](https://wise.design/components/button#types)
258
229
  */
259
- export const Sentiment: StoryObj<PreviewStoryArgs> = {
260
- args: {
261
- children: 'Button text',
262
- previewAddonStart: false,
263
- previewAddonEnd: false,
264
- },
265
- argTypes: {
266
- ...hideControls(['sentiment', 'priority']),
267
- ...previewArgTypes,
268
- },
269
- render: (args: PreviewStoryArgs) => {
270
- const [props, previewProps] = getPropsForPreview(args);
271
-
230
+ export const Sentiment: Story = {
231
+ render: (args: ListItemButtonProps) => {
272
232
  return (
273
233
  <ol className="list-unstyled">
274
234
  <ListItem
@@ -276,7 +236,7 @@ export const Sentiment: StoryObj<PreviewStoryArgs> = {
276
236
  subtitle="Default sentiment with primary priority"
277
237
  media={MEDIA.avatarSingle}
278
238
  control={
279
- <ListItem.Button {...props} {...previewProps} priority="primary">
239
+ <ListItem.Button {...args} priority="primary">
280
240
  Default Sentiment
281
241
  </ListItem.Button>
282
242
  }
@@ -286,7 +246,7 @@ export const Sentiment: StoryObj<PreviewStoryArgs> = {
286
246
  subtitle="Negative sentiment with primary priority"
287
247
  media={MEDIA.avatarSingle}
288
248
  control={
289
- <ListItem.Button {...props} {...previewProps} priority="primary" sentiment="negative">
249
+ <ListItem.Button {...args} priority="primary" sentiment="negative">
290
250
  Negative Sentiment
291
251
  </ListItem.Button>
292
252
  }
@@ -296,7 +256,7 @@ export const Sentiment: StoryObj<PreviewStoryArgs> = {
296
256
  subtitle="Default sentiment with secondary priority"
297
257
  media={MEDIA.avatarSingle}
298
258
  control={
299
- <ListItem.Button {...props} {...previewProps} priority="secondary">
259
+ <ListItem.Button {...args} priority="secondary">
300
260
  Default Sentiment
301
261
  </ListItem.Button>
302
262
  }
@@ -306,7 +266,7 @@ export const Sentiment: StoryObj<PreviewStoryArgs> = {
306
266
  subtitle="Negative sentiment with secondary priority"
307
267
  media={MEDIA.avatarSingle}
308
268
  control={
309
- <ListItem.Button {...props} {...previewProps} priority="secondary" sentiment="negative">
269
+ <ListItem.Button {...args} priority="secondary" sentiment="negative">
310
270
  Negative Sentiment
311
271
  </ListItem.Button>
312
272
  }
@@ -314,6 +274,9 @@ export const Sentiment: StoryObj<PreviewStoryArgs> = {
314
274
  </ol>
315
275
  );
316
276
  },
277
+ args: {
278
+ children: 'Button text',
279
+ },
317
280
  };
318
281
 
319
282
  /**
@@ -321,19 +284,8 @@ export const Sentiment: StoryObj<PreviewStoryArgs> = {
321
284
  * screen to help more important buttons to take precedence over others. <br />
322
285
  * [Design documentation](https://wise.design/components/button#priorities)
323
286
  */
324
- export const Priority: StoryObj<PreviewStoryArgs> = {
325
- args: {
326
- children: 'Button text',
327
- previewAddonStart: false,
328
- previewAddonEnd: false,
329
- },
330
- argTypes: {
331
- ...hideControls(['priority']),
332
- ...previewArgTypes,
333
- },
334
- render: (args: PreviewStoryArgs) => {
335
- const [props, previewProps] = getPropsForPreview(args);
336
-
287
+ export const Priority: Story = {
288
+ render: (args: ListItemButtonProps) => {
337
289
  return (
338
290
  <ol className="list-unstyled">
339
291
  <ListItem
@@ -341,7 +293,7 @@ export const Priority: StoryObj<PreviewStoryArgs> = {
341
293
  subtitle="Primary priority (default)"
342
294
  media={MEDIA.avatarSingle}
343
295
  control={
344
- <ListItem.Button {...props} {...previewProps} priority="primary">
296
+ <ListItem.Button {...args} priority="primary">
345
297
  Primary Priority
346
298
  </ListItem.Button>
347
299
  }
@@ -351,7 +303,7 @@ export const Priority: StoryObj<PreviewStoryArgs> = {
351
303
  subtitle="Secondary priority"
352
304
  media={MEDIA.avatarSingle}
353
305
  control={
354
- <ListItem.Button {...props} {...previewProps} priority="secondary">
306
+ <ListItem.Button {...args} priority="secondary">
355
307
  Secondary Priority
356
308
  </ListItem.Button>
357
309
  }
@@ -361,7 +313,7 @@ export const Priority: StoryObj<PreviewStoryArgs> = {
361
313
  subtitle="Secondary neutral priority"
362
314
  media={MEDIA.avatarSingle}
363
315
  control={
364
- <ListItem.Button {...props} {...previewProps} priority="secondary-neutral">
316
+ <ListItem.Button {...args} priority="secondary-neutral">
365
317
  Secondary Neutral Priority
366
318
  </ListItem.Button>
367
319
  }
@@ -371,7 +323,7 @@ export const Priority: StoryObj<PreviewStoryArgs> = {
371
323
  subtitle="Tertiary priority"
372
324
  media={MEDIA.avatarSingle}
373
325
  control={
374
- <ListItem.Button {...props} {...previewProps} priority="tertiary">
326
+ <ListItem.Button {...args} priority="tertiary">
375
327
  Tertiary Priority
376
328
  </ListItem.Button>
377
329
  }
@@ -379,38 +331,29 @@ export const Priority: StoryObj<PreviewStoryArgs> = {
379
331
  </ol>
380
332
  );
381
333
  },
334
+ args: {
335
+ children: 'Button text',
336
+ },
382
337
  };
383
338
 
384
339
  /**
385
340
  * Button in loading state.
386
341
  */
387
- export const Loading: StoryObj<PreviewStoryArgs> = {
388
- args: {
389
- loading: true,
390
- previewAddonStart: false,
391
- previewAddonEnd: false,
392
- },
393
- argTypes: {
394
- ...hideControls(['loading']),
395
- ...previewArgTypes,
396
- },
397
- render: (args: PreviewStoryArgs) => {
398
- const [props, previewProps] = getPropsForPreview(args);
399
-
342
+ export const Loading: Story = {
343
+ render: (args: ListItemButtonProps) => {
400
344
  return (
401
345
  <ListItem
402
346
  title="Loading Button"
403
347
  subtitle="Button in loading state"
404
348
  media={MEDIA.avatarSingle}
405
- control={
406
- <ListItem.Button {...props} {...previewProps}>
407
- Loading Button
408
- </ListItem.Button>
409
- }
349
+ control={<ListItem.Button {...args}>Loading Button</ListItem.Button>}
410
350
  additionalInfo={INFO.nonInteractive}
411
351
  />
412
352
  );
413
353
  },
354
+ args: {
355
+ loading: true,
356
+ },
414
357
  };
415
358
 
416
359
  const addonProps = {
@@ -423,10 +366,6 @@ const addonProps = {
423
366
  * **NB:** ListItem.Button only supports icon addons.
424
367
  */
425
368
  export const WithIcons: Story = {
426
- args: {
427
- children: 'Button text',
428
- },
429
- argTypes: hideControls(),
430
369
  render: (args: ListItemButtonProps) => {
431
370
  return (
432
371
  <ol className="list-unstyled">
@@ -463,4 +402,7 @@ export const WithIcons: Story = {
463
402
  </ol>
464
403
  );
465
404
  },
405
+ args: {
406
+ children: 'Button text',
407
+ },
466
408
  };
@@ -32,21 +32,6 @@ const meta: Meta<ListItemCheckboxProps> = {
32
32
  indeterminate: {
33
33
  control: 'boolean',
34
34
  },
35
- onChange: {
36
- table: {
37
- type: { summary: '(event: ChangeEvent<HTMLInputElement>) => void' },
38
- },
39
- },
40
- onFocus: {
41
- table: {
42
- type: { summary: '(event: FocusEvent<HTMLInputElement>) => void' },
43
- },
44
- },
45
- onBlur: {
46
- table: {
47
- type: { summary: '(event: FocusEvent<HTMLInputElement>) => void' },
48
- },
49
- },
50
35
  },
51
36
  } satisfies Meta<ListItemCheckboxProps>;
52
37
 
@@ -73,9 +58,6 @@ export const Playground: Story = {
73
58
  * Checkbox controls demonstrate different states including checked, unchecked, and indeterminate.
74
59
  */
75
60
  export const States: Story = {
76
- parameters: {
77
- controls: { disable: true },
78
- },
79
61
  render: function Render() {
80
62
  const [isChecked0, setisChecked0] = useState(false);
81
63
  const [isChecked1, setisChecked1] = useState(true);
@@ -1,22 +1,13 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
- import { Edit } from '@transferwise/icons';
3
- import { fn } from 'storybook/test';
2
+ import { Edit, Heart } from '@transferwise/icons';
4
3
  import { ListItem } from '../ListItem';
5
4
  import {
6
5
  SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
7
6
  SB_LIST_ITEM_MEDIA as MEDIA,
8
7
  SB_LIST_ITEM_PROMPTS as PROMPTS,
9
8
  } from '../_stories/subcomponents';
10
- import { disableControls } from '../_stories/helpers';
11
9
  import type { ListItemIconButtonProps } from './ListItemIconButton';
12
-
13
- const hideControls = disableControls([
14
- 'onClick',
15
- 'children',
16
- 'className',
17
- 'addonStart',
18
- 'addonEnd',
19
- ]);
10
+ import { fn } from 'storybook/test';
20
11
 
21
12
  /**
22
13
  * Use IconButton to provide compact action controls within a ListItem context using iconography.
@@ -121,7 +112,6 @@ export const Interactivity: Story = {
121
112
  args: {
122
113
  children: <Edit />,
123
114
  },
124
- argTypes: hideControls(['partiallyInteractive']),
125
115
  render: (args: ListItemIconButtonProps) => {
126
116
  return (
127
117
  <ol className="list-unstyled">
@@ -153,7 +143,6 @@ export const Interactivity: Story = {
153
143
  * [Design documentation](https://wise.design/components/icon-button#types)
154
144
  */
155
145
  export const Sentiment: Story = {
156
- argTypes: hideControls(['sentiment', 'priority']),
157
146
  render: (args) => {
158
147
  return (
159
148
  <ol className="list-unstyled">
@@ -192,7 +181,6 @@ export const Sentiment: Story = {
192
181
  * [Design documentation](https://wise.design/components/icon-button#priorities)
193
182
  */
194
183
  export const Priority: Story = {
195
- argTypes: hideControls(['sentiment', 'priority']),
196
184
  render: (args) => {
197
185
  return (
198
186
  <ol className="list-unstyled">
@@ -235,7 +223,6 @@ export const AsAnchor: Story = {
235
223
  target: '_blank',
236
224
  onClick: undefined,
237
225
  },
238
- argTypes: hideControls(),
239
226
  render: (args: ListItemIconButtonProps) => {
240
227
  return (
241
228
  <ListItem
@@ -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
- render(<ListItem.Image src="test-image.jpg" />);
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
- render(<ListItem.Image src="test-image.jpg" alt="Test image description" />);
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
- render(<ListItem.Image src="test-image.jpg" loading="lazy" />);
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
- render(<ListItem.Image src="test-image.jpg" className="custom-image-class" />);
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
  });