@gradio/gallery 0.12.1 → 0.13.0-beta.1
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/CHANGELOG.md +36 -0
- package/Gallery.stories.svelte +9 -1
- package/Gallery.test.ts +31 -8
- package/Index.svelte +12 -5
- package/dist/Index.svelte +110 -0
- package/dist/Index.svelte.d.ts +52 -0
- package/dist/shared/Gallery.svelte +624 -0
- package/dist/shared/Gallery.svelte.d.ts +40 -0
- package/dist/shared/utils.d.ts +2 -0
- package/dist/shared/utils.js +13 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.js +1 -0
- package/package.json +24 -12
- package/shared/Gallery.svelte +125 -46
- package/types.ts +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/gallery",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0-beta.1",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -8,24 +8,36 @@
|
|
|
8
8
|
"private": false,
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"dequal": "^2.0.2",
|
|
11
|
-
"@gradio/atoms": "^0.8.
|
|
12
|
-
"@gradio/client": "^1.
|
|
13
|
-
"@gradio/
|
|
14
|
-
"@gradio/
|
|
15
|
-
"@gradio/
|
|
16
|
-
"@gradio/
|
|
17
|
-
"@gradio/
|
|
18
|
-
"@gradio/
|
|
11
|
+
"@gradio/atoms": "^0.8.1-beta.1",
|
|
12
|
+
"@gradio/client": "^1.6.0-beta.1",
|
|
13
|
+
"@gradio/image": "^0.16.0-beta.1",
|
|
14
|
+
"@gradio/statustracker": "^0.8.0-beta.1",
|
|
15
|
+
"@gradio/icons": "^0.8.0-beta.1",
|
|
16
|
+
"@gradio/upload": "^0.12.4-beta.1",
|
|
17
|
+
"@gradio/utils": "^0.7.0-beta.1",
|
|
18
|
+
"@gradio/video": "^0.11.0-beta.1",
|
|
19
|
+
"@gradio/file": "^0.9.4-beta.1"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
|
-
"@gradio/preview": "^0.11.0"
|
|
22
|
+
"@gradio/preview": "^0.11.1-beta.0"
|
|
22
23
|
},
|
|
23
24
|
"main": "./Index.svelte",
|
|
24
25
|
"main_changeset": true,
|
|
25
26
|
"exports": {
|
|
26
|
-
".":
|
|
27
|
+
".": {
|
|
28
|
+
"gradio": "./Index.svelte",
|
|
29
|
+
"svelte": "./dist/Index.svelte",
|
|
30
|
+
"types": "./dist/Index.svelte.d.ts"
|
|
31
|
+
},
|
|
27
32
|
"./package.json": "./package.json",
|
|
28
|
-
"./base":
|
|
33
|
+
"./base": {
|
|
34
|
+
"gradio": "./shared/Gallery.svelte",
|
|
35
|
+
"svelte": "./dist/shared/Gallery.svelte",
|
|
36
|
+
"types": "./dist/shared/Gallery.svelte.d.ts"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"svelte": "^4.0.0"
|
|
29
41
|
},
|
|
30
42
|
"repository": {
|
|
31
43
|
"type": "git",
|
package/shared/Gallery.svelte
CHANGED
|
@@ -3,28 +3,30 @@
|
|
|
3
3
|
import { ModifyUpload } from "@gradio/upload";
|
|
4
4
|
import type { SelectData } from "@gradio/utils";
|
|
5
5
|
import { Image } from "@gradio/image/shared";
|
|
6
|
+
import { Video } from "@gradio/video/shared";
|
|
6
7
|
import { dequal } from "dequal";
|
|
7
8
|
import { createEventDispatcher, onMount } from "svelte";
|
|
8
9
|
import { tick } from "svelte";
|
|
10
|
+
import type { GalleryImage, GalleryVideo } from "../types";
|
|
9
11
|
|
|
10
12
|
import {
|
|
11
13
|
Download,
|
|
12
14
|
Image as ImageIcon,
|
|
13
15
|
Maximize,
|
|
14
16
|
Minimize,
|
|
15
|
-
Clear
|
|
17
|
+
Clear,
|
|
18
|
+
Play
|
|
16
19
|
} from "@gradio/icons";
|
|
17
20
|
import { FileData } from "@gradio/client";
|
|
18
21
|
import { format_gallery_for_sharing } from "./utils";
|
|
19
22
|
import { IconButton } from "@gradio/atoms";
|
|
20
23
|
import type { I18nFormatter } from "@gradio/utils";
|
|
21
24
|
|
|
22
|
-
type
|
|
23
|
-
type GalleryData = GalleryImage[];
|
|
25
|
+
type GalleryData = GalleryImage | GalleryVideo;
|
|
24
26
|
|
|
25
27
|
export let show_label = true;
|
|
26
28
|
export let label: string;
|
|
27
|
-
export let value: GalleryData | null = null;
|
|
29
|
+
export let value: GalleryData[] | null = null;
|
|
28
30
|
export let columns: number | number[] | undefined = [2];
|
|
29
31
|
export let rows: number | number[] | undefined = undefined;
|
|
30
32
|
export let height: number | "auto" = "auto";
|
|
@@ -54,16 +56,24 @@
|
|
|
54
56
|
|
|
55
57
|
$: was_reset = value == null || value.length === 0 ? true : was_reset;
|
|
56
58
|
|
|
57
|
-
let resolved_value: GalleryData | null = null;
|
|
59
|
+
let resolved_value: GalleryData[] | null = null;
|
|
60
|
+
|
|
58
61
|
$: resolved_value =
|
|
59
62
|
value == null
|
|
60
63
|
? null
|
|
61
|
-
: value.map((data) =>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
: (value.map((data) => {
|
|
65
|
+
if ("video" in data) {
|
|
66
|
+
return {
|
|
67
|
+
video: data.video as FileData,
|
|
68
|
+
caption: data.caption
|
|
69
|
+
};
|
|
70
|
+
} else if ("image" in data) {
|
|
71
|
+
return { image: data.image as FileData, caption: data.caption };
|
|
72
|
+
}
|
|
73
|
+
return {};
|
|
74
|
+
}) as GalleryData[]);
|
|
75
|
+
|
|
76
|
+
let prev_value: GalleryData[] | null = value;
|
|
67
77
|
if (selected_index == null && preview && value?.length) {
|
|
68
78
|
selected_index = 0;
|
|
69
79
|
}
|
|
@@ -201,7 +211,7 @@
|
|
|
201
211
|
URL.revokeObjectURL(url);
|
|
202
212
|
}
|
|
203
213
|
|
|
204
|
-
$:
|
|
214
|
+
$: selected_media =
|
|
205
215
|
selected_index != null && resolved_value != null
|
|
206
216
|
? resolved_value[selected_index]
|
|
207
217
|
: null;
|
|
@@ -230,7 +240,7 @@
|
|
|
230
240
|
<Empty unpadded_box={true} size="large"><ImageIcon /></Empty>
|
|
231
241
|
{:else}
|
|
232
242
|
<div class="gallery-container" bind:this={gallery_container}>
|
|
233
|
-
{#if
|
|
243
|
+
{#if selected_media && allow_preview}
|
|
234
244
|
<button
|
|
235
245
|
on:keydown={on_keydown}
|
|
236
246
|
class="preview"
|
|
@@ -242,7 +252,10 @@
|
|
|
242
252
|
Icon={Download}
|
|
243
253
|
label={i18n("common.download")}
|
|
244
254
|
on:click={() => {
|
|
245
|
-
const image =
|
|
255
|
+
const image =
|
|
256
|
+
"image" in selected_media
|
|
257
|
+
? selected_media?.image
|
|
258
|
+
: selected_media?.video;
|
|
246
259
|
if (image == null) {
|
|
247
260
|
return;
|
|
248
261
|
}
|
|
@@ -281,25 +294,40 @@
|
|
|
281
294
|
{/if}
|
|
282
295
|
</div>
|
|
283
296
|
<button
|
|
284
|
-
class="
|
|
285
|
-
on:click={
|
|
286
|
-
|
|
297
|
+
class="media-button"
|
|
298
|
+
on:click={"image" in selected_media
|
|
299
|
+
? (event) => handle_preview_click(event)
|
|
300
|
+
: null}
|
|
301
|
+
style="height: calc(100% - {selected_media.caption
|
|
287
302
|
? '80px'
|
|
288
303
|
: '60px'})"
|
|
289
304
|
aria-label="detailed view of selected image"
|
|
290
305
|
>
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
306
|
+
{#if "image" in selected_media}
|
|
307
|
+
<Image
|
|
308
|
+
data-testid="detailed-image"
|
|
309
|
+
src={selected_media.image.url}
|
|
310
|
+
alt={selected_media.caption || ""}
|
|
311
|
+
title={selected_media.caption || null}
|
|
312
|
+
class={selected_media.caption && "with-caption"}
|
|
313
|
+
loading="lazy"
|
|
314
|
+
/>
|
|
315
|
+
{:else}
|
|
316
|
+
<Video
|
|
317
|
+
src={selected_media.video.url}
|
|
318
|
+
data-testid={"detailed-video"}
|
|
319
|
+
alt={selected_media.caption || ""}
|
|
320
|
+
loading="lazy"
|
|
321
|
+
loop={false}
|
|
322
|
+
is_stream={false}
|
|
323
|
+
muted={false}
|
|
324
|
+
controls={true}
|
|
325
|
+
/>
|
|
326
|
+
{/if}
|
|
299
327
|
</button>
|
|
300
|
-
{#if
|
|
328
|
+
{#if selected_media?.caption}
|
|
301
329
|
<caption class="caption">
|
|
302
|
-
{
|
|
330
|
+
{selected_media.caption}
|
|
303
331
|
</caption>
|
|
304
332
|
{/if}
|
|
305
333
|
<div
|
|
@@ -307,7 +335,7 @@
|
|
|
307
335
|
class="thumbnails scroll-hide"
|
|
308
336
|
data-testid="container_el"
|
|
309
337
|
>
|
|
310
|
-
{#each resolved_value as
|
|
338
|
+
{#each resolved_value as media, i}
|
|
311
339
|
<button
|
|
312
340
|
bind:this={el[i]}
|
|
313
341
|
on:click={() => (selected_index = i)}
|
|
@@ -318,13 +346,26 @@
|
|
|
318
346
|
" of " +
|
|
319
347
|
resolved_value.length}
|
|
320
348
|
>
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
349
|
+
{#if "image" in media}
|
|
350
|
+
<Image
|
|
351
|
+
src={media.image.url}
|
|
352
|
+
title={media.caption || null}
|
|
353
|
+
data-testid={"thumbnail " + (i + 1)}
|
|
354
|
+
alt=""
|
|
355
|
+
loading="lazy"
|
|
356
|
+
/>
|
|
357
|
+
{:else}
|
|
358
|
+
<Play />
|
|
359
|
+
<Video
|
|
360
|
+
src={media.video.url}
|
|
361
|
+
title={media.caption || null}
|
|
362
|
+
is_stream={false}
|
|
363
|
+
data-testid={"thumbnail " + (i + 1)}
|
|
364
|
+
alt=""
|
|
365
|
+
loading="lazy"
|
|
366
|
+
loop={false}
|
|
367
|
+
/>
|
|
368
|
+
{/if}
|
|
328
369
|
</button>
|
|
329
370
|
{/each}
|
|
330
371
|
</div>
|
|
@@ -347,7 +388,7 @@
|
|
|
347
388
|
<ModifyUpload
|
|
348
389
|
{i18n}
|
|
349
390
|
absolute={false}
|
|
350
|
-
on:clear={() => (value =
|
|
391
|
+
on:clear={() => (value = [])}
|
|
351
392
|
/>
|
|
352
393
|
</div>
|
|
353
394
|
{/if}
|
|
@@ -369,13 +410,26 @@
|
|
|
369
410
|
on:click={() => (selected_index = i)}
|
|
370
411
|
aria-label={"Thumbnail " + (i + 1) + " of " + resolved_value.length}
|
|
371
412
|
>
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
413
|
+
{#if "image" in entry}
|
|
414
|
+
<Image
|
|
415
|
+
alt={entry.caption || ""}
|
|
416
|
+
src={typeof entry.image === "string"
|
|
417
|
+
? entry.image
|
|
418
|
+
: entry.image.url}
|
|
419
|
+
loading="lazy"
|
|
420
|
+
/>
|
|
421
|
+
{:else}
|
|
422
|
+
<Play />
|
|
423
|
+
<Video
|
|
424
|
+
src={entry.video.url}
|
|
425
|
+
title={entry.caption || null}
|
|
426
|
+
is_stream={false}
|
|
427
|
+
data-testid={"thumbnail " + (i + 1)}
|
|
428
|
+
alt=""
|
|
429
|
+
loading="lazy"
|
|
430
|
+
loop={false}
|
|
431
|
+
/>
|
|
432
|
+
{/if}
|
|
379
433
|
{#if entry.caption}
|
|
380
434
|
<div class="caption-label">
|
|
381
435
|
{entry.caption}
|
|
@@ -440,12 +494,13 @@
|
|
|
440
494
|
}
|
|
441
495
|
}
|
|
442
496
|
|
|
443
|
-
.
|
|
497
|
+
.media-button {
|
|
444
498
|
height: calc(100% - 60px);
|
|
445
499
|
width: 100%;
|
|
446
500
|
display: flex;
|
|
447
501
|
}
|
|
448
|
-
.
|
|
502
|
+
.media-button :global(img),
|
|
503
|
+
.media-button :global(video) {
|
|
449
504
|
width: var(--size-full);
|
|
450
505
|
height: var(--size-full);
|
|
451
506
|
object-fit: contain;
|
|
@@ -455,6 +510,14 @@
|
|
|
455
510
|
width: var(--size-full);
|
|
456
511
|
height: var(--size-full);
|
|
457
512
|
}
|
|
513
|
+
.thumbnails :global(svg) {
|
|
514
|
+
position: absolute;
|
|
515
|
+
top: var(--size-2);
|
|
516
|
+
left: var(--size-2);
|
|
517
|
+
width: 50%;
|
|
518
|
+
height: 50%;
|
|
519
|
+
opacity: 50%;
|
|
520
|
+
}
|
|
458
521
|
.preview :global(img.with-caption) {
|
|
459
522
|
height: var(--size-full);
|
|
460
523
|
}
|
|
@@ -516,6 +579,23 @@
|
|
|
516
579
|
border-color: var(--color-accent);
|
|
517
580
|
}
|
|
518
581
|
|
|
582
|
+
.thumbnail-item :global(svg) {
|
|
583
|
+
position: absolute;
|
|
584
|
+
top: 50%;
|
|
585
|
+
left: 50%;
|
|
586
|
+
width: 50%;
|
|
587
|
+
height: 50%;
|
|
588
|
+
opacity: 50%;
|
|
589
|
+
transform: translate(-50%, -50%);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.thumbnail-item :global(video) {
|
|
593
|
+
width: var(--size-full);
|
|
594
|
+
height: var(--size-full);
|
|
595
|
+
overflow: hidden;
|
|
596
|
+
object-fit: cover;
|
|
597
|
+
}
|
|
598
|
+
|
|
519
599
|
.thumbnail-small {
|
|
520
600
|
flex: none;
|
|
521
601
|
transform: scale(0.9);
|
|
@@ -523,7 +603,6 @@
|
|
|
523
603
|
width: var(--size-9);
|
|
524
604
|
height: var(--size-9);
|
|
525
605
|
}
|
|
526
|
-
|
|
527
606
|
.thumbnail-small.selected {
|
|
528
607
|
--ring-color: var(--color-accent);
|
|
529
608
|
transform: scale(1);
|