@lumx/react 2.1.9-alpha-thumbnail3 → 2.1.9-alpha.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.
Files changed (119) hide show
  1. package/esm/_internal/AlertDialog.js +1 -2
  2. package/esm/_internal/AlertDialog.js.map +1 -1
  3. package/esm/_internal/AutocompleteMultiple.js +1 -2
  4. package/esm/_internal/AutocompleteMultiple.js.map +1 -1
  5. package/esm/_internal/Button2.js +1 -1
  6. package/esm/_internal/Checkbox2.js +1 -2
  7. package/esm/_internal/Checkbox2.js.map +1 -1
  8. package/esm/_internal/DatePickerField.js +1 -1
  9. package/esm/_internal/DragHandle.js +2 -3
  10. package/esm/_internal/DragHandle.js.map +1 -1
  11. package/esm/_internal/ExpansionPanel.js +1 -1
  12. package/esm/_internal/Flag2.js +1 -3
  13. package/esm/_internal/Flag2.js.map +1 -1
  14. package/esm/_internal/Icon2.js +32 -4
  15. package/esm/_internal/Icon2.js.map +1 -1
  16. package/esm/_internal/IconButton.js +1 -1
  17. package/esm/_internal/ImageBlock.js +1 -0
  18. package/esm/_internal/ImageBlock.js.map +1 -1
  19. package/esm/_internal/Lightbox2.js +1 -1
  20. package/esm/_internal/Link2.js +1 -1
  21. package/esm/_internal/LinkPreview.js +1 -1
  22. package/esm/_internal/LinkPreview.js.map +1 -1
  23. package/esm/_internal/Message2.js +5 -5
  24. package/esm/_internal/Message2.js.map +1 -1
  25. package/esm/_internal/Notification2.js +1 -2
  26. package/esm/_internal/Notification2.js.map +1 -1
  27. package/esm/_internal/ProgressTrackerStepPanel.js +1 -2
  28. package/esm/_internal/ProgressTrackerStepPanel.js.map +1 -1
  29. package/esm/_internal/SelectMultiple.js +1 -2
  30. package/esm/_internal/SelectMultiple.js.map +1 -1
  31. package/esm/_internal/SideNavigationItem.js +1 -2
  32. package/esm/_internal/SideNavigationItem.js.map +1 -1
  33. package/esm/_internal/Slider2.js +2 -21
  34. package/esm/_internal/Slider2.js.map +1 -1
  35. package/esm/_internal/SlideshowControls.js +1 -1
  36. package/esm/_internal/TabPanel.js +1 -1
  37. package/esm/_internal/TableRow.js +1 -2
  38. package/esm/_internal/TableRow.js.map +1 -1
  39. package/esm/_internal/TextField.js +1 -2
  40. package/esm/_internal/TextField.js.map +1 -1
  41. package/esm/_internal/Thumbnail2.js +764 -62
  42. package/esm/_internal/Thumbnail2.js.map +1 -1
  43. package/esm/_internal/alert-dialog.js +1 -2
  44. package/esm/_internal/alert-dialog.js.map +1 -1
  45. package/esm/_internal/autocomplete.js +1 -2
  46. package/esm/_internal/autocomplete.js.map +1 -1
  47. package/esm/_internal/avatar.js +4 -2
  48. package/esm/_internal/avatar.js.map +1 -1
  49. package/esm/_internal/button.js +1 -1
  50. package/esm/_internal/checkbox.js +1 -2
  51. package/esm/_internal/checkbox.js.map +1 -1
  52. package/esm/_internal/clamp.js +22 -0
  53. package/esm/_internal/clamp.js.map +1 -0
  54. package/esm/_internal/comment-block.js +4 -2
  55. package/esm/_internal/comment-block.js.map +1 -1
  56. package/esm/_internal/date-picker.js +1 -2
  57. package/esm/_internal/date-picker.js.map +1 -1
  58. package/esm/_internal/drag-handle.js +1 -2
  59. package/esm/_internal/drag-handle.js.map +1 -1
  60. package/esm/_internal/expansion-panel.js +1 -2
  61. package/esm/_internal/expansion-panel.js.map +1 -1
  62. package/esm/_internal/flag.js +1 -1
  63. package/esm/_internal/icon.js +1 -1
  64. package/esm/_internal/image-block.js +4 -2
  65. package/esm/_internal/image-block.js.map +1 -1
  66. package/esm/_internal/lightbox.js +1 -2
  67. package/esm/_internal/lightbox.js.map +1 -1
  68. package/esm/_internal/link-preview.js +4 -2
  69. package/esm/_internal/link-preview.js.map +1 -1
  70. package/esm/_internal/link.js +1 -1
  71. package/esm/_internal/message.js +1 -2
  72. package/esm/_internal/message.js.map +1 -1
  73. package/esm/_internal/mosaic.js +4 -2
  74. package/esm/_internal/mosaic.js.map +1 -1
  75. package/esm/_internal/notification.js +1 -2
  76. package/esm/_internal/notification.js.map +1 -1
  77. package/esm/_internal/post-block.js +4 -2
  78. package/esm/_internal/post-block.js.map +1 -1
  79. package/esm/_internal/progress-tracker.js +1 -2
  80. package/esm/_internal/progress-tracker.js.map +1 -1
  81. package/esm/_internal/select.js +1 -2
  82. package/esm/_internal/select.js.map +1 -1
  83. package/esm/_internal/side-navigation.js +1 -2
  84. package/esm/_internal/side-navigation.js.map +1 -1
  85. package/esm/_internal/slider.js +2 -1
  86. package/esm/_internal/slider.js.map +1 -1
  87. package/esm/_internal/slideshow.js +1 -2
  88. package/esm/_internal/slideshow.js.map +1 -1
  89. package/esm/_internal/table.js +1 -2
  90. package/esm/_internal/table.js.map +1 -1
  91. package/esm/_internal/tabs.js +1 -1
  92. package/esm/_internal/text-field.js +1 -2
  93. package/esm/_internal/text-field.js.map +1 -1
  94. package/esm/_internal/thumbnail.js +4 -2
  95. package/esm/_internal/thumbnail.js.map +1 -1
  96. package/esm/_internal/uploader.js +1 -1
  97. package/esm/_internal/user-block.js +3 -2
  98. package/esm/_internal/user-block.js.map +1 -1
  99. package/esm/index.js +4 -4
  100. package/package.json +4 -4
  101. package/src/components/drag-handle/DragHandle.tsx +5 -1
  102. package/src/components/flag/Flag.test.tsx +1 -2
  103. package/src/components/flag/Flag.tsx +2 -10
  104. package/src/components/flag/__snapshots__/Flag.test.tsx.snap +0 -15
  105. package/src/components/icon/Icon.tsx +15 -1
  106. package/src/components/image-block/ImageBlock.tsx +1 -0
  107. package/src/components/link-preview/LinkPreview.tsx +1 -1
  108. package/src/components/link-preview/__snapshots__/LinkPreview.test.tsx.snap +2 -2
  109. package/src/components/message/Message.tsx +4 -2
  110. package/src/components/thumbnail/Thumbnail.stories.tsx +59 -399
  111. package/src/components/thumbnail/Thumbnail.test.tsx +6 -6
  112. package/src/components/thumbnail/Thumbnail.tsx +34 -35
  113. package/src/components/thumbnail/useFocusPoint.ts +10 -18
  114. package/src/components/thumbnail/useImageLoad.ts +22 -23
  115. package/src/hooks/useOnResize.ts +0 -6
  116. package/src/stories/knobs/image.ts +3 -35
  117. package/types.d.ts +0 -2
  118. package/esm/_internal/mdi.js +0 -22
  119. package/esm/_internal/mdi.js.map +0 -1
@@ -12,83 +12,22 @@ import {
12
12
  Thumbnail,
13
13
  ThumbnailVariant,
14
14
  } from '@lumx/react';
15
- import { IMAGE_SIZES, imageKnob, IMAGES } from '@lumx/react/stories/knobs/image';
15
+ import { imageKnob, IMAGES } from '@lumx/react/stories/knobs/image';
16
+ import { htmlDecode } from '@lumx/react/utils/htmlDecode';
16
17
  import { boolean, select, text } from '@storybook/addon-knobs';
17
18
  import { enumKnob } from '@lumx/react/stories/knobs/enumKnob';
18
19
  import { focusKnob } from '@lumx/react/stories/knobs/focusKnob';
19
20
  import { sizeKnob } from '@lumx/react/stories/knobs/sizeKnob';
20
- import { action } from '@storybook/addon-actions';
21
21
  import classNames from 'classnames';
22
22
 
23
23
  export default { title: 'LumX components/thumbnail/Thumbnail' };
24
24
 
25
- /** Default thumbnail props (editable via knobs) */
26
- export const Default = ({ theme }: any) => {
27
- const alt = text('Alternative text', 'Image alt text');
28
- const align = enumKnob(
29
- 'Alignment',
30
- [undefined, Alignment.center, Alignment.left, Alignment.right] as const,
31
- undefined,
32
- );
33
- const aspectRatio = enumKnob('Aspect ratio', [undefined, ...Object.values(AspectRatio)], undefined);
34
- const crossOrigin = enumKnob('CORS', [undefined, 'anonymous', 'use-credentials'] as const, undefined);
35
- const fillHeight = boolean('Fill Height', false);
36
- const focusPoint = { x: focusKnob('Focus X'), y: focusKnob('Focus Y') };
37
- const image = imageKnob('Image', IMAGES.landscape1);
38
- const variant = select('Variant', ThumbnailVariant, ThumbnailVariant.squared);
39
- const size = sizeKnob('Size', undefined);
40
- const onClick = boolean('clickable?', false) ? action('onClick') : undefined;
41
-
42
- return (
43
- <Thumbnail
44
- alt={alt}
45
- align={align}
46
- aspectRatio={aspectRatio}
47
- crossOrigin={crossOrigin}
48
- fillHeight={fillHeight}
49
- focusPoint={focusPoint}
50
- image={image}
51
- size={size}
52
- theme={theme}
53
- variant={variant}
54
- onClick={onClick}
55
- />
56
- );
57
- };
58
-
59
- export const WithBadge = () => {
60
- const thumbnailSize = sizeKnob('Size', Size.l);
61
- const variant = select('Variant', ThumbnailVariant, ThumbnailVariant.rounded);
62
- const badgeColor = select('Badge color', ColorPalette, ColorPalette.primary);
63
- const activateFallback = boolean('Activate fallback', false);
64
- const image = imageKnob();
65
- return (
66
- <Thumbnail
67
- alt="Image alt text"
68
- image={activateFallback ? '' : image}
69
- variant={variant}
70
- aspectRatio={AspectRatio.square}
71
- size={thumbnailSize}
72
- badge={
73
- <Badge color={badgeColor}>
74
- <Icon icon={mdiAbTesting} />
75
- </Badge>
76
- }
77
- />
78
- );
79
- };
25
+ export const Default = () => <Thumbnail alt="Image alt text" image={imageKnob()} size={Size.xxl} />;
80
26
 
81
- export const Clickable = () => (
82
- <Thumbnail alt="Click me" image={imageKnob()} size={sizeKnob('Size', Size.xxl)} onClick={action('onClick')} />
83
- );
27
+ export const Clickable = () => <Thumbnail alt="Click me" image={imageKnob()} size={Size.xxl} onClick={console.log} />;
84
28
 
85
29
  export const ClickableLink = () => (
86
- <Thumbnail
87
- alt="Click me"
88
- image={imageKnob()}
89
- size={sizeKnob('Size', Size.xxl)}
90
- linkProps={{ href: 'https://google.fr' }}
91
- />
30
+ <Thumbnail alt="Click me" image={imageKnob()} size={Size.xxl} linkProps={{ href: 'https://google.fr' }} />
92
31
  );
93
32
 
94
33
  const CustomLinkComponent = (props: any) => (
@@ -101,266 +40,41 @@ export const ClickableCustomLink = () => (
101
40
  <Thumbnail
102
41
  alt="Click me"
103
42
  image={imageKnob()}
104
- size={sizeKnob('Size', Size.xxl)}
43
+ size={Size.xxl}
105
44
  linkAs={CustomLinkComponent}
106
45
  linkProps={{ href: 'https://google.fr', className: 'custom-class-name' }}
107
46
  />
108
47
  );
109
48
 
110
- export const FillHeight = () => {
111
- const parentStyle = {
112
- width: 600,
113
- height: 240,
114
- border: '1px solid red',
115
- overflow: 'hidden',
116
- resize: 'both',
117
- } as const;
118
- return (
119
- <>
120
- <h2>Default</h2>
121
- <div style={parentStyle}>
122
- <Thumbnail alt="" image={IMAGES.landscape1s200} fillHeight />
123
- </div>
124
- <h2>Ratio wide</h2>
125
- <div style={parentStyle}>
126
- <Thumbnail alt="" image={IMAGES.landscape1s200} fillHeight aspectRatio="wide" />
127
- </div>
128
- <h2>Ratio vertical</h2>
129
- <div style={parentStyle}>
130
- <Thumbnail alt="" image={IMAGES.landscape1s200} fillHeight aspectRatio="vertical" />
131
- </div>
132
- <h2>Ratio free</h2>
133
- <div style={parentStyle}>
134
- <Thumbnail alt="" image={IMAGES.landscape1s200} fillHeight aspectRatio="free" />
135
- </div>
136
- </>
137
- );
138
- };
49
+ export const DefaultFallback = () => <Thumbnail alt="foo" image="foo" />;
139
50
 
140
- export const Original = () => (
141
- <>
142
- <h1>Ratio: Original</h1>
143
- <h2>Default</h2>
144
- <table>
145
- <tr>
146
- <th>Landscape</th>
147
- <th>
148
- Landscape <small>(with original size)</small>
149
- </th>
150
- <th>Portrait</th>
151
- <th>
152
- Portrait <small>(with original size)</small>
153
- </th>
154
- </tr>
155
- <tr>
156
- <td>
157
- <Thumbnail alt="" image={IMAGES.landscape1} />
158
- </td>
159
- <td>
160
- <Thumbnail alt="" image={IMAGES.landscape1} imgProps={IMAGE_SIZES.landscape1} />
161
- </td>
162
- <td>
163
- <Thumbnail alt="" image={IMAGES.portrait1} />
164
- </td>
165
- <td>
166
- <Thumbnail alt="" image={IMAGES.portrait1} imgProps={IMAGE_SIZES.portrait1} />
167
- </td>
168
- </tr>
169
- </table>
170
- <h2>Constrained parent size</h2>
171
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
172
- <div className="parent" style={{ width: 220 }}>
173
- <Thumbnail alt="" image={IMAGES.landscape1} />
174
- </div>
175
- <div className="parent" style={{ width: 220 }}>
176
- <Thumbnail alt="" image={IMAGES.portrait1} />
177
- </div>
178
- </FlexBox>
179
- <h2>With size</h2>
180
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
181
- <Thumbnail alt="" image={IMAGES.landscape1} size="xxl" />
182
- <Thumbnail alt="" image={IMAGES.portrait1} size="xxl" />
183
- </FlexBox>
184
- <h2>With size & smaller image</h2>
185
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
186
- <Thumbnail alt="" image={IMAGES.landscape1s200} size="xxl" />
187
- <Thumbnail alt="" image={IMAGES.portrait1s200} size="xxl" />
188
- </FlexBox>
189
- <h2>With size & smaller image & fill height</h2>
190
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
191
- <Thumbnail alt="" image={IMAGES.landscape1s200} size="xxl" fillHeight />
192
- <Thumbnail alt="" image={IMAGES.portrait1s200} size="xxl" fillHeight />
193
- </FlexBox>
194
- <h2>Constrained parent size & smaller image & fill height</h2>
195
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
196
- <div className="parent" style={{ width: 220 }}>
197
- <Thumbnail alt="" image={IMAGES.landscape1s200} fillHeight />
198
- </div>
199
- <div className="parent" style={{ width: 220 }}>
200
- <Thumbnail alt="" image={IMAGES.portrait1s200} fillHeight />
201
- </div>
202
- </FlexBox>
203
- </>
204
- );
205
-
206
- export const Vertical = () => (
207
- <>
208
- <h1>Ratio: vertical</h1>
209
- <h2>Default</h2>
210
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
211
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.landscape1} />
212
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.portrait1} />
213
- </FlexBox>
214
- <h2>Constraint parent size</h2>
215
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
216
- <div className="parent" style={{ width: 220 }}>
217
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.landscape1} />
218
- </div>
219
- <div className="parent" style={{ width: 220 }}>
220
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.portrait1} />
221
- </div>
222
- </FlexBox>
223
- <h2>Constraint parent size & smaller image</h2>
224
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
225
- <div className="parent" style={{ width: 220 }}>
226
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.landscape1s200} />
227
- </div>
228
- <div className="parent" style={{ width: 220 }}>
229
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.portrait1s200} />
230
- </div>
231
- </FlexBox>
232
- <h2>With size</h2>
233
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
234
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.landscape1} size="xxl" />
235
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.portrait1} size="xxl" />
236
- </FlexBox>
237
- <h2>With size & smaller image</h2>
238
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
239
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.landscape1s200} size="xxl" />
240
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.portrait1s200} size="xxl" />
241
- </FlexBox>
242
- <h2>With size & smaller image & fill height</h2>
243
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
244
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.landscape1s200} size="xxl" fillHeight />
245
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.portrait1s200} size="xxl" fillHeight />
246
- </FlexBox>
247
- <h2>Constrained parent size & smaller image & fill height</h2>
248
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
249
- <div className="parent" style={{ width: 220 }}>
250
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.landscape1s200} fillHeight />
251
- </div>
252
- <div className="parent" style={{ width: 220 }}>
253
- <Thumbnail alt="" aspectRatio="vertical" image={IMAGES.portrait1s200} fillHeight />
254
- </div>
255
- </FlexBox>
256
- </>
257
- );
51
+ export const IconFallback = () => <Thumbnail alt="foo" image="foo" fallback={mdiAbTesting} />;
258
52
 
259
- export const Wide = () => (
260
- <>
261
- <h1>Ratio: wide</h1>
262
- <h2>Default</h2>
263
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
264
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.landscape1} />
265
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.portrait1} />
266
- </FlexBox>
267
- <h2>Constrained parent size</h2>
268
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
269
- <div className="parent" style={{ width: 220 }}>
270
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.landscape1} />
271
- </div>
272
- <div className="parent" style={{ width: 220 }}>
273
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.portrait1} />
274
- </div>
275
- </FlexBox>
276
- <h2>Constrained parent size & smaller image</h2>
277
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
278
- <div className="parent" style={{ width: 220 }}>
279
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.landscape1s200} />
280
- </div>
281
- <div className="parent" style={{ width: 220 }}>
282
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.portrait1s200} />
283
- </div>
284
- </FlexBox>
285
- <h2>With size</h2>
286
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
287
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.landscape1} size="xxl" />
288
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.portrait1} size="xxl" />
289
- </FlexBox>
290
- <h2>With size & smaller image</h2>
291
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
292
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.landscape1s200} size="xxl" />
293
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.portrait1s200} size="xxl" />
294
- </FlexBox>
295
- <h2>With size & smaller image & fill height</h2>
296
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
297
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.landscape1s200} size="xxl" fillHeight />
298
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.portrait1s200} size="xxl" fillHeight />
299
- </FlexBox>
300
- <h2>Constrained parent size & smaller image & fill height</h2>
301
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
302
- <div className="parent" style={{ width: 220 }}>
303
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.landscape1s200} fillHeight />
304
- </div>
305
- <div className="parent" style={{ width: 220 }}>
306
- <Thumbnail alt="" aspectRatio="wide" image={IMAGES.portrait1s200} fillHeight />
307
- </div>
308
- </FlexBox>
309
- </>
53
+ export const CustomFallback = () => (
54
+ <Thumbnail alt="foo" image="foo" fallback={<Thumbnail alt="missing image" image="/logo.svg" />} />
310
55
  );
311
56
 
312
- export const Square = () => (
313
- <>
314
- <h1>Ratio: square</h1>
315
- <h2>Default</h2>
316
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
317
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.landscape1} />
318
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.portrait1} />
319
- </FlexBox>
320
- <h2>Constrained parent size</h2>
321
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
322
- <div className="parent" style={{ width: 220 }}>
323
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.landscape1} />
324
- </div>
325
- <div className="parent" style={{ width: 220 }}>
326
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.portrait1} />
327
- </div>
328
- </FlexBox>
329
- <h2>Constrained parent size & smaller image</h2>
330
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
331
- <div className="parent" style={{ width: 220 }}>
332
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.landscape1s200} />
333
- </div>
334
- <div className="parent" style={{ width: 220 }}>
335
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.portrait1s200} />
336
- </div>
337
- </FlexBox>
338
- <h2>With size</h2>
339
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
340
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.landscape1} size="xxl" />
341
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.portrait1} size="xxl" />
342
- </FlexBox>
343
- <h2>With size & smaller image</h2>
344
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
345
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.landscape1s200} size="xxl" />
346
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.portrait1s200} size="xxl" />
347
- </FlexBox>
348
- <h2>With size & smaller image & fill height</h2>
349
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
350
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.landscape1s200} size="xxl" fillHeight />
351
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.portrait1s200} size="xxl" fillHeight />
352
- </FlexBox>
353
- <h2>Constrained parent size & smaller image & fill height</h2>
354
- <FlexBox orientation="horizontal" vAlign="center" gap="huge">
355
- <div className="parent" style={{ width: 220 }}>
356
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.landscape1s200} fillHeight />
357
- </div>
358
- <div className="parent" style={{ width: 220 }}>
359
- <Thumbnail alt="" aspectRatio="square" image={IMAGES.portrait1s200} fillHeight />
360
- </div>
361
- </FlexBox>
362
- </>
363
- );
57
+ export const WithBadge = () => {
58
+ const thumbnailSize = sizeKnob('Thumbnail size', Size.l);
59
+ const variant = select('Thumbnail variant', ThumbnailVariant, ThumbnailVariant.rounded);
60
+ const badgeColor = select('Badge color', ColorPalette, ColorPalette.primary);
61
+ const activateFallback = boolean('Activate fallback', false);
62
+ const image = imageKnob();
63
+ return (
64
+ <Thumbnail
65
+ alt="Image alt text"
66
+ image={activateFallback ? '' : image}
67
+ variant={variant}
68
+ aspectRatio={AspectRatio.square}
69
+ size={thumbnailSize}
70
+ badge={
71
+ <Badge color={badgeColor}>
72
+ <Icon icon={mdiAbTesting} />
73
+ </Badge>
74
+ }
75
+ />
76
+ );
77
+ };
364
78
 
365
79
  export const ParentSizeConstraint = () => {
366
80
  const fillHeight = boolean('Fill Height', true);
@@ -368,7 +82,7 @@ export const ParentSizeConstraint = () => {
368
82
  <FlexBox key={aspectRatio} orientation="horizontal" gap="huge">
369
83
  <h1>ratio: {aspectRatio}</h1>
370
84
 
371
- <div style={{ border: '1px solid red', width: 220, height: 400, resize: 'both', overflow: 'auto' }}>
85
+ <div style={{ border: '1px solid red', width: 200, height: 400, resize: 'both', overflow: 'auto' }}>
372
86
  <Thumbnail alt="Grid" image="/demo-assets/grid.jpg" aspectRatio={aspectRatio} fillHeight={fillHeight} />
373
87
  </div>
374
88
 
@@ -383,89 +97,35 @@ export const ParentSizeConstraint = () => {
383
97
  ));
384
98
  };
385
99
 
386
- export const IsLoading = ({ theme }: any) => (
387
- <FlexBox
388
- orientation="horizontal"
389
- vAlign="center"
390
- marginAuto={['left', 'right']}
391
- style={{ border: '1px solid red', width: 900, height: 700, resize: 'both', overflow: 'auto' }}
392
- >
100
+ export const Knobs = ({ theme }: any) => {
101
+ const alt = text('Alternative text', 'Image alt text');
102
+ const align = enumKnob(
103
+ 'Alignment',
104
+ [undefined, Alignment.center, Alignment.left, Alignment.right] as const,
105
+ undefined,
106
+ );
107
+ const aspectRatio = enumKnob('Aspect ratio', [undefined, ...Object.values(AspectRatio)], undefined);
108
+ const crossOrigin = enumKnob('CORS', [undefined, 'anonymous', 'use-credentials'] as const, undefined);
109
+ const fillHeight = boolean('Fill Height', false);
110
+ const focusPoint = { x: focusKnob('Focus X'), y: focusKnob('Focus Y') };
111
+ const image = imageKnob('Image', IMAGES.landscape1);
112
+ const variant = select('Variant', ThumbnailVariant, ThumbnailVariant.squared);
113
+ const size = sizeKnob('Size', Size.xxl);
114
+ const onClick = boolean('clickable?', false) ? () => console.log('ok') : undefined;
115
+
116
+ return (
393
117
  <Thumbnail
118
+ alt={alt}
119
+ align={align}
120
+ aspectRatio={aspectRatio}
121
+ crossOrigin={crossOrigin}
122
+ fillHeight={fillHeight}
123
+ focusPoint={focusPoint}
124
+ image={htmlDecode(image)}
125
+ size={size}
394
126
  theme={theme}
395
- alt="Image alt text"
396
- image={IMAGES.landscape2}
397
- isLoading={boolean('Is loading', true)}
398
- fillHeight={boolean('Fill Height', false)}
399
- size={sizeKnob('Size', undefined)}
127
+ variant={variant}
128
+ onClick={onClick}
400
129
  />
401
- </FlexBox>
402
- );
403
-
404
- export const ErrorFallback = () => <Thumbnail alt="foo" image="foo" />;
405
-
406
- export const ErrorCustomIconFallback = () => <Thumbnail alt="foo" image="foo" fallback={mdiAbTesting} />;
407
-
408
- export const ErrorCustomFallback = () => (
409
- <Thumbnail alt="foo" image="foo" fallback={<Thumbnail alt="missing image" image="/logo.svg" />} />
410
- );
411
-
412
- export const ErrorFallbackVariants = () => {
413
- const isLoading = boolean('is loading', false);
414
- const variant = select('Variant', ThumbnailVariant, undefined);
415
- const base = { alt: 'foo', image: 'foo', isLoading, variant } as const;
416
- const imageFallback = <img src="/logo.svg" alt="logo" />;
417
- const imgProps = { width: 50, height: 50 };
418
- return (
419
- <>
420
- <h2>Default</h2>
421
- Default fallback | Custom icon fallback | Custom react node fallback
422
- <FlexBox orientation="horizontal" gap="big">
423
- <Thumbnail {...base} />
424
- <Thumbnail {...base} fallback={mdiAbTesting} />
425
- <Thumbnail {...base} fallback={imageFallback} />
426
- </FlexBox>
427
- <h2>
428
- With original image size <small>(50x50)</small>
429
- </h2>
430
- <FlexBox orientation="horizontal" gap="big">
431
- <Thumbnail {...base} imgProps={imgProps} />
432
- <Thumbnail {...base} fallback={mdiAbTesting} imgProps={imgProps} />
433
- <Thumbnail {...base} fallback={imageFallback} imgProps={imgProps} />
434
- </FlexBox>
435
- <h2>With size</h2>
436
- <FlexBox orientation="horizontal" gap="big">
437
- <Thumbnail {...base} size="xl" />
438
- <Thumbnail {...base} size="xl" fallback={mdiAbTesting} />
439
- <Thumbnail {...base} size="xl" fallback={imageFallback} imgProps={imgProps} />
440
- </FlexBox>
441
- <h2>With size & ratio</h2>
442
- <FlexBox orientation="horizontal" gap="big">
443
- <Thumbnail {...base} size="xl" aspectRatio="wide" />
444
- <Thumbnail {...base} size="xl" aspectRatio="wide" fallback={mdiAbTesting} />
445
- <Thumbnail {...base} size="xl" aspectRatio="wide" fallback={imageFallback} />
446
- </FlexBox>
447
- <h2>
448
- With original size <small>(50x50)</small> & ratio
449
- </h2>
450
- <FlexBox orientation="horizontal" gap="big">
451
- <Thumbnail {...base} imgProps={imgProps} aspectRatio="wide" />
452
- <Thumbnail {...base} imgProps={imgProps} aspectRatio="wide" fallback={mdiAbTesting} />
453
- <Thumbnail {...base} imgProps={imgProps} aspectRatio="wide" fallback={imageFallback} />
454
- </FlexBox>
455
- <h2>
456
- With original size <small>(50x50)</small> & ratio & constrained parent size
457
- </h2>
458
- <FlexBox orientation="horizontal" gap="big">
459
- <div className="parent" style={{ width: 220 }}>
460
- <Thumbnail {...base} imgProps={imgProps} aspectRatio="wide" />
461
- </div>
462
- <div className="parent" style={{ width: 220 }}>
463
- <Thumbnail {...base} imgProps={imgProps} aspectRatio="wide" fallback={mdiAbTesting} />
464
- </div>
465
- <div className="parent" style={{ width: 220 }}>
466
- <Thumbnail {...base} imgProps={imgProps} aspectRatio="wide" fallback={imageFallback} />
467
- </div>
468
- </FlexBox>
469
- </>
470
130
  );
471
131
  };
@@ -9,10 +9,10 @@ import {
9
9
  Clickable,
10
10
  ClickableCustomLink,
11
11
  ClickableLink,
12
- ErrorCustomFallback,
12
+ CustomFallback,
13
13
  Default,
14
- ErrorFallback,
15
- ErrorCustomIconFallback,
14
+ DefaultFallback,
15
+ IconFallback,
16
16
  WithBadge,
17
17
  } from './Thumbnail.stories';
18
18
 
@@ -36,9 +36,9 @@ describe(`<${Thumbnail.displayName}>`, () => {
36
36
  Clickable,
37
37
  ClickableLink,
38
38
  ClickableCustomLink,
39
- ErrorFallback,
40
- ErrorCustomFallback,
41
- ErrorCustomIconFallback,
39
+ DefaultFallback,
40
+ CustomFallback,
41
+ IconFallback,
42
42
  WithBadge,
43
43
  },
44
44
  Thumbnail,