@gradio/image 0.14.0 → 0.16.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 CHANGED
@@ -1,5 +1,61 @@
1
1
  # @gradio/image
2
2
 
3
+ ## 0.16.0-beta.1
4
+
5
+ ### Dependency updates
6
+
7
+ - @gradio/atoms@0.8.1-beta.1
8
+ - @gradio/icons@0.8.0-beta.1
9
+ - @gradio/statustracker@0.8.0-beta.1
10
+ - @gradio/utils@0.7.0-beta.1
11
+ - @gradio/client@1.6.0-beta.1
12
+ - @gradio/upload@0.12.4-beta.1
13
+ - @gradio/wasm@0.13.1-beta.1
14
+
15
+ ## 0.16.0-beta.0
16
+
17
+ ### Features
18
+
19
+ - [#9149](https://github.com/gradio-app/gradio/pull/9149) [`3d7a9b8`](https://github.com/gradio-app/gradio/commit/3d7a9b81f6fef06187eca832471dc1692eb493a0) - Open audio/image input stream only when queue is ready. Thanks @freddyaboulton!
20
+ - [#9173](https://github.com/gradio-app/gradio/pull/9173) [`66349fe`](https://github.com/gradio-app/gradio/commit/66349fe26827e3a3c15b738a1177e95fec7f5554) - Streaming Guides. Thanks @freddyaboulton!
21
+ - [#8941](https://github.com/gradio-app/gradio/pull/8941) [`97a7bf6`](https://github.com/gradio-app/gradio/commit/97a7bf66a79179d1b91a3199d68e5c11216ca500) - Streaming inputs for 5.0. Thanks @freddyaboulton!
22
+
23
+ ### Fixes
24
+
25
+ - [#9163](https://github.com/gradio-app/gradio/pull/9163) [`2b6cbf2`](https://github.com/gradio-app/gradio/commit/2b6cbf25908e42cf027324e54ef2cc0baad11a91) - fix exports and generate types. Thanks @pngwn!
26
+
27
+ ### Dependency updates
28
+
29
+ - @gradio/utils@0.7.0-beta.0
30
+ - @gradio/statustracker@0.8.0-beta.0
31
+ - @gradio/atoms@0.8.1-beta.0
32
+ - @gradio/client@1.6.0-beta.0
33
+ - @gradio/icons@0.8.0-beta.0
34
+ - @gradio/upload@0.12.4-beta.0
35
+ - @gradio/wasm@0.13.1-beta.0
36
+
37
+ ## 0.15.0
38
+
39
+ ### Features
40
+
41
+ - [#9031](https://github.com/gradio-app/gradio/pull/9031) [`04b7d32`](https://github.com/gradio-app/gradio/commit/04b7d327ec1227a693fc2dfea51b1e2729851bde) - Allow drag and replace image in `gr.Image` and Multimodal textbox. Thanks @hannahblair!
42
+ - [#8930](https://github.com/gradio-app/gradio/pull/8930) [`41d5ab9`](https://github.com/gradio-app/gradio/commit/41d5ab987ba9728753be4509490c79041655809b) - Add `placeholder` param to Image and ImageEditor to replace upload image text. Thanks @hannahblair!
43
+ - [#9118](https://github.com/gradio-app/gradio/pull/9118) [`e1c404d`](https://github.com/gradio-app/gradio/commit/e1c404da1143fb52b659d03e028bdba1badf443d) - setup npm-previews of all packages. Thanks @pngwn!
44
+
45
+ ### Fixes
46
+
47
+ - [#9116](https://github.com/gradio-app/gradio/pull/9116) [`ba6322e`](https://github.com/gradio-app/gradio/commit/ba6322ec2bb975f15389fe0700816bf671c6819d) - Fix image height content fit. Thanks @hannahblair!
48
+
49
+ ### Dependency updates
50
+
51
+ - @gradio/utils@0.6.0
52
+ - @gradio/upload@0.12.3
53
+ - @gradio/atoms@0.8.0
54
+ - @gradio/client@1.5.1
55
+ - @gradio/statustracker@0.7.5
56
+ - @gradio/wasm@0.13.0
57
+ - @gradio/icons@0.7.1
58
+
3
59
  ## 0.14.0
4
60
 
5
61
  ### Features
@@ -3,6 +3,8 @@
3
3
  import StaticImage from "./Index.svelte";
4
4
  import { userEvent, within } from "@storybook/test";
5
5
  import { allModes } from "../storybook/modes";
6
+ import image_file_100x100 from "../storybook/test_files/image_100x100.webp";
7
+ import image_file_100x1000 from "../storybook/test_files/image_100x100.webp";
6
8
 
7
9
  export const meta = {
8
10
  title: "Components/Image",
@@ -16,6 +18,8 @@
16
18
  }
17
19
  }
18
20
  };
21
+
22
+ let md = `# a heading! /n a new line! `;
19
23
  </script>
20
24
 
21
25
  <Template let:args>
@@ -28,20 +32,7 @@
28
32
  </Template>
29
33
 
30
34
  <Story
31
- name="static with label and download button"
32
- args={{
33
- value: {
34
- path: "https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
35
- url: "https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
36
- orig_name: "cheetah.jpg"
37
- },
38
- show_label: true,
39
- show_download_button: true
40
- }}
41
- />
42
-
43
- <Story
44
- name="static with label and download button"
35
+ name="static with label, info and download button"
45
36
  args={{
46
37
  value: {
47
38
  path: "https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
@@ -49,6 +40,7 @@
49
40
  orig_name: "cheetah.jpg"
50
41
  },
51
42
  show_label: true,
43
+ placeholder: "This is a cheetah",
52
44
  show_download_button: true
53
45
  }}
54
46
  play={async ({ canvasElement }) => {
@@ -74,6 +66,41 @@
74
66
  }}
75
67
  />
76
68
 
69
+ <Story
70
+ name="static with a vertically long image"
71
+ args={{
72
+ value: {
73
+ path: image_file_100x1000,
74
+ url: image_file_100x1000,
75
+ orig_name: "image.webp"
76
+ }
77
+ }}
78
+ />
79
+
80
+ <Story
81
+ name="static with a vertically long image and a fixed height"
82
+ args={{
83
+ value: {
84
+ path: image_file_100x1000,
85
+ url: image_file_100x1000,
86
+ orig_name: "image.webp"
87
+ },
88
+ height: "500px"
89
+ }}
90
+ />
91
+
92
+ <Story
93
+ name="static with a small image and a fixed height"
94
+ args={{
95
+ value: {
96
+ path: image_file_100x100,
97
+ url: image_file_100x100,
98
+ orig_name: "image.webp"
99
+ },
100
+ height: "500px"
101
+ }}
102
+ />
103
+
77
104
  <Story
78
105
  name="interactive with upload, clipboard, and webcam"
79
106
  args={{
@@ -85,7 +112,8 @@
85
112
  },
86
113
  show_label: false,
87
114
  show_download_button: false,
88
- interactive: true
115
+ interactive: true,
116
+ placeholder: md
89
117
  }}
90
118
  play={async ({ canvasElement }) => {
91
119
  const canvas = within(canvasElement);
package/Image.test.ts CHANGED
@@ -7,9 +7,8 @@ import {
7
7
  beforeAll,
8
8
  beforeEach
9
9
  } from "vitest";
10
- import { spy } from "tinyspy";
11
- import { cleanup, render } from "@gradio/tootils";
12
- import { setupi18n } from "../app/src/i18n";
10
+ import { cleanup, render } from "@self/tootils";
11
+ import { setupi18n } from "../core/src/i18n";
13
12
 
14
13
  import Image from "./Index.svelte";
15
14
  import type { LoadingStatus } from "@gradio/statustracker";
package/Index.svelte CHANGED
@@ -9,7 +9,7 @@
9
9
  </script>
10
10
 
11
11
  <script lang="ts">
12
- import type { Gradio, SelectData } from "@gradio/utils";
12
+ import type { Gradio, SelectData, ValueData } from "@gradio/utils";
13
13
  import StaticImage from "./shared/ImagePreview.svelte";
14
14
  import ImageUploader from "./shared/ImageUploader.svelte";
15
15
  import { afterUpdate } from "svelte";
@@ -22,6 +22,16 @@
22
22
 
23
23
  type sources = "upload" | "webcam" | "clipboard" | null;
24
24
 
25
+ let stream_state = "closed";
26
+ let _modify_stream: (state: "open" | "closed" | "waiting") => void;
27
+ export function modify_stream_state(
28
+ state: "open" | "closed" | "waiting"
29
+ ): void {
30
+ stream_state = state;
31
+ _modify_stream(state);
32
+ }
33
+ export const get_stream_state: () => void = () => stream_state;
34
+ export let set_time_limit: (arg0: number) => void;
25
35
  export let value_is_output = false;
26
36
  export let elem_id = "";
27
37
  export let elem_classes: string[] = [];
@@ -35,6 +45,7 @@
35
45
 
36
46
  export let height: number | undefined;
37
47
  export let width: number | undefined;
48
+ export let stream_every: number;
38
49
 
39
50
  export let _selectable = false;
40
51
  export let container = true;
@@ -51,6 +62,7 @@
51
62
  export let streaming: boolean;
52
63
  export let pending: boolean;
53
64
  export let mirror_webcam: boolean;
65
+ export let placeholder: string | undefined = undefined;
54
66
  export let show_fullscreen_button: boolean;
55
67
 
56
68
  export let gradio: Gradio<{
@@ -58,13 +70,14 @@
58
70
  change: never;
59
71
  error: string;
60
72
  edit: never;
61
- stream: never;
73
+ stream: ValueData;
62
74
  drag: never;
63
75
  upload: never;
64
76
  clear: never;
65
77
  select: SelectData;
66
78
  share: ShareData;
67
79
  clear_status: LoadingStatus;
80
+ close_stream: string;
68
81
  }>;
69
82
 
70
83
  $: {
@@ -76,12 +89,37 @@
76
89
  }
77
90
  }
78
91
  }
92
+
79
93
  afterUpdate(() => {
80
94
  value_is_output = false;
81
95
  });
82
96
 
83
97
  let dragging: boolean;
84
98
  let active_source: sources = null;
99
+ let upload_component: ImageUploader;
100
+ const handle_drag_event = (event: Event): void => {
101
+ const drag_event = event as DragEvent;
102
+ drag_event.preventDefault();
103
+ drag_event.stopPropagation();
104
+ if (drag_event.type === "dragenter" || drag_event.type === "dragover") {
105
+ dragging = true;
106
+ } else if (drag_event.type === "dragleave") {
107
+ dragging = false;
108
+ }
109
+ };
110
+
111
+ const handle_drop = (event: Event): void => {
112
+ if (interactive) {
113
+ const drop_event = event as DragEvent;
114
+ drop_event.preventDefault();
115
+ drop_event.stopPropagation();
116
+ dragging = false;
117
+
118
+ if (upload_component) {
119
+ upload_component.loadFilesFromDrop(drop_event);
120
+ }
121
+ }
122
+ };
85
123
  </script>
86
124
 
87
125
  {#if !interactive}
@@ -132,6 +170,10 @@
132
170
  {container}
133
171
  {scale}
134
172
  {min_width}
173
+ on:dragenter={handle_drag_event}
174
+ on:dragleave={handle_drag_event}
175
+ on:dragover={handle_drag_event}
176
+ on:drop={handle_drop}
135
177
  >
136
178
  <StatusTracker
137
179
  autoscroll={gradio.autoscroll}
@@ -141,8 +183,10 @@
141
183
  />
142
184
 
143
185
  <ImageUploader
186
+ bind:this={upload_component}
144
187
  bind:active_source
145
188
  bind:value
189
+ bind:dragging
146
190
  selectable={_selectable}
147
191
  {root}
148
192
  {sources}
@@ -150,7 +194,7 @@
150
194
  on:clear={() => {
151
195
  gradio.dispatch("clear");
152
196
  }}
153
- on:stream={() => gradio.dispatch("stream")}
197
+ on:stream={({ detail }) => gradio.dispatch("stream", detail)}
154
198
  on:drag={({ detail }) => (dragging = detail)}
155
199
  on:upload={() => gradio.dispatch("upload")}
156
200
  on:select={({ detail }) => gradio.dispatch("select", detail)}
@@ -160,18 +204,24 @@
160
204
  loading_status.status = "error";
161
205
  gradio.dispatch("error", detail);
162
206
  }}
207
+ on:close_stream={() => {
208
+ gradio.dispatch("close_stream", "stream");
209
+ }}
163
210
  {label}
164
211
  {show_label}
165
212
  {pending}
166
213
  {streaming}
167
214
  {mirror_webcam}
215
+ {stream_every}
216
+ bind:modify_stream={_modify_stream}
217
+ bind:set_time_limit
168
218
  max_file_size={gradio.max_file_size}
169
219
  i18n={gradio.i18n}
170
220
  upload={gradio.client.upload}
171
221
  stream_handler={gradio.client.stream}
172
222
  >
173
223
  {#if active_source === "upload" || !active_source}
174
- <UploadText i18n={gradio.i18n} type="image" />
224
+ <UploadText i18n={gradio.i18n} type="image" {placeholder} />
175
225
  {:else if active_source === "clipboard"}
176
226
  <UploadText i18n={gradio.i18n} type="clipboard" mode="short" />
177
227
  {:else}
@@ -0,0 +1,46 @@
1
+ <script>import Image from "./shared/Image.svelte";
2
+ export let value;
3
+ export let type;
4
+ export let selected = false;
5
+ </script>
6
+
7
+ <div
8
+ class="container"
9
+ class:table={type === "table"}
10
+ class:gallery={type === "gallery"}
11
+ class:selected
12
+ class:border={value}
13
+ >
14
+ {#if value}
15
+ <Image src={value.url} alt="" />
16
+ {/if}
17
+ </div>
18
+
19
+ <style>
20
+ .container :global(img) {
21
+ width: 100%;
22
+ height: 100%;
23
+ }
24
+
25
+ .container.selected {
26
+ border-color: var(--border-color-accent);
27
+ }
28
+ .border.table {
29
+ border: 2px solid var(--border-color-primary);
30
+ }
31
+
32
+ .container.table {
33
+ margin: 0 auto;
34
+ border-radius: var(--radius-lg);
35
+ overflow: hidden;
36
+ width: var(--size-20);
37
+ height: var(--size-20);
38
+ object-fit: cover;
39
+ }
40
+
41
+ .container.gallery {
42
+ width: var(--size-20);
43
+ max-width: var(--size-20);
44
+ object-fit: cover;
45
+ }
46
+ </style>
@@ -0,0 +1,19 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { FileData } from "@gradio/client";
3
+ declare const __propDef: {
4
+ props: {
5
+ value: null | FileData;
6
+ type: "gallery" | "table";
7
+ selected?: boolean | undefined;
8
+ };
9
+ events: {
10
+ [evt: string]: CustomEvent<any>;
11
+ };
12
+ slots: {};
13
+ };
14
+ export type ExampleProps = typeof __propDef.props;
15
+ export type ExampleEvents = typeof __propDef.events;
16
+ export type ExampleSlots = typeof __propDef.slots;
17
+ export default class Example extends SvelteComponent<ExampleProps, ExampleEvents, ExampleSlots> {
18
+ }
19
+ export {};
@@ -0,0 +1,200 @@
1
+ <svelte:options accessors={true} />
2
+
3
+ <script context="module">export { default as Webcam } from "./shared/Webcam.svelte";
4
+ export { default as BaseImageUploader } from "./shared/ImageUploader.svelte";
5
+ export { default as BaseStaticImage } from "./shared/ImagePreview.svelte";
6
+ export { default as BaseExample } from "./Example.svelte";
7
+ export { default as BaseImage } from "./shared/Image.svelte";
8
+ </script>
9
+
10
+ <script>import StaticImage from "./shared/ImagePreview.svelte";
11
+ import ImageUploader from "./shared/ImageUploader.svelte";
12
+ import { afterUpdate } from "svelte";
13
+ import { Block, Empty, UploadText } from "@gradio/atoms";
14
+ import { Image } from "@gradio/icons";
15
+ import { StatusTracker } from "@gradio/statustracker";
16
+ let stream_state = "closed";
17
+ let _modify_stream;
18
+ export function modify_stream_state(state) {
19
+ stream_state = state;
20
+ _modify_stream(state);
21
+ }
22
+ export const get_stream_state = () => stream_state;
23
+ export let set_time_limit;
24
+ export let value_is_output = false;
25
+ export let elem_id = "";
26
+ export let elem_classes = [];
27
+ export let visible = true;
28
+ export let value = null;
29
+ let old_value = null;
30
+ export let label;
31
+ export let show_label;
32
+ export let show_download_button;
33
+ export let root;
34
+ export let height;
35
+ export let width;
36
+ export let stream_every;
37
+ export let _selectable = false;
38
+ export let container = true;
39
+ export let scale = null;
40
+ export let min_width = void 0;
41
+ export let loading_status;
42
+ export let show_share_button = false;
43
+ export let sources = [
44
+ "upload",
45
+ "clipboard",
46
+ "webcam"
47
+ ];
48
+ export let interactive;
49
+ export let streaming;
50
+ export let pending;
51
+ export let mirror_webcam;
52
+ export let placeholder = void 0;
53
+ export let show_fullscreen_button;
54
+ export let gradio;
55
+ $: {
56
+ if (JSON.stringify(value) !== JSON.stringify(old_value)) {
57
+ old_value = value;
58
+ gradio.dispatch("change");
59
+ if (!value_is_output) {
60
+ gradio.dispatch("input");
61
+ }
62
+ }
63
+ }
64
+ afterUpdate(() => {
65
+ value_is_output = false;
66
+ });
67
+ let dragging;
68
+ let active_source = null;
69
+ let upload_component;
70
+ const handle_drag_event = (event) => {
71
+ const drag_event = event;
72
+ drag_event.preventDefault();
73
+ drag_event.stopPropagation();
74
+ if (drag_event.type === "dragenter" || drag_event.type === "dragover") {
75
+ dragging = true;
76
+ } else if (drag_event.type === "dragleave") {
77
+ dragging = false;
78
+ }
79
+ };
80
+ const handle_drop = (event) => {
81
+ if (interactive) {
82
+ const drop_event = event;
83
+ drop_event.preventDefault();
84
+ drop_event.stopPropagation();
85
+ dragging = false;
86
+ if (upload_component) {
87
+ upload_component.loadFilesFromDrop(drop_event);
88
+ }
89
+ }
90
+ };
91
+ </script>
92
+
93
+ {#if !interactive}
94
+ <Block
95
+ {visible}
96
+ variant={"solid"}
97
+ border_mode={dragging ? "focus" : "base"}
98
+ padding={false}
99
+ {elem_id}
100
+ {elem_classes}
101
+ height={height || undefined}
102
+ {width}
103
+ allow_overflow={false}
104
+ {container}
105
+ {scale}
106
+ {min_width}
107
+ >
108
+ <StatusTracker
109
+ autoscroll={gradio.autoscroll}
110
+ i18n={gradio.i18n}
111
+ {...loading_status}
112
+ />
113
+ <StaticImage
114
+ on:select={({ detail }) => gradio.dispatch("select", detail)}
115
+ on:share={({ detail }) => gradio.dispatch("share", detail)}
116
+ on:error={({ detail }) => gradio.dispatch("error", detail)}
117
+ {value}
118
+ {label}
119
+ {show_label}
120
+ {show_download_button}
121
+ selectable={_selectable}
122
+ {show_share_button}
123
+ i18n={gradio.i18n}
124
+ {show_fullscreen_button}
125
+ />
126
+ </Block>
127
+ {:else}
128
+ <Block
129
+ {visible}
130
+ variant={value === null ? "dashed" : "solid"}
131
+ border_mode={dragging ? "focus" : "base"}
132
+ padding={false}
133
+ {elem_id}
134
+ {elem_classes}
135
+ height={height || undefined}
136
+ {width}
137
+ allow_overflow={false}
138
+ {container}
139
+ {scale}
140
+ {min_width}
141
+ on:dragenter={handle_drag_event}
142
+ on:dragleave={handle_drag_event}
143
+ on:dragover={handle_drag_event}
144
+ on:drop={handle_drop}
145
+ >
146
+ <StatusTracker
147
+ autoscroll={gradio.autoscroll}
148
+ i18n={gradio.i18n}
149
+ {...loading_status}
150
+ on:clear_status={() => gradio.dispatch("clear_status", loading_status)}
151
+ />
152
+
153
+ <ImageUploader
154
+ bind:this={upload_component}
155
+ bind:active_source
156
+ bind:value
157
+ bind:dragging
158
+ selectable={_selectable}
159
+ {root}
160
+ {sources}
161
+ on:edit={() => gradio.dispatch("edit")}
162
+ on:clear={() => {
163
+ gradio.dispatch("clear");
164
+ }}
165
+ on:stream={({ detail }) => gradio.dispatch("stream", detail)}
166
+ on:drag={({ detail }) => (dragging = detail)}
167
+ on:upload={() => gradio.dispatch("upload")}
168
+ on:select={({ detail }) => gradio.dispatch("select", detail)}
169
+ on:share={({ detail }) => gradio.dispatch("share", detail)}
170
+ on:error={({ detail }) => {
171
+ loading_status = loading_status || {};
172
+ loading_status.status = "error";
173
+ gradio.dispatch("error", detail);
174
+ }}
175
+ on:close_stream={() => {
176
+ gradio.dispatch("close_stream", "stream");
177
+ }}
178
+ {label}
179
+ {show_label}
180
+ {pending}
181
+ {streaming}
182
+ {mirror_webcam}
183
+ {stream_every}
184
+ bind:modify_stream={_modify_stream}
185
+ bind:set_time_limit
186
+ max_file_size={gradio.max_file_size}
187
+ i18n={gradio.i18n}
188
+ upload={gradio.client.upload}
189
+ stream_handler={gradio.client.stream}
190
+ >
191
+ {#if active_source === "upload" || !active_source}
192
+ <UploadText i18n={gradio.i18n} type="image" {placeholder} />
193
+ {:else if active_source === "clipboard"}
194
+ <UploadText i18n={gradio.i18n} type="clipboard" mode="short" />
195
+ {:else}
196
+ <Empty unpadded_box={true} size="large"><Image /></Empty>
197
+ {/if}
198
+ </ImageUploader>
199
+ </Block>
200
+ {/if}