@gradio/multimodaltextbox 0.5.5 → 0.5.6

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,23 @@
1
1
  # @gradio/multimodaltextbox
2
2
 
3
+ ## 0.5.6
4
+
5
+ ### Features
6
+
7
+ - [#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!
8
+ - [#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!
9
+
10
+ ### Dependency updates
11
+
12
+ - @gradio/utils@0.6.0
13
+ - @gradio/upload@0.12.3
14
+ - @gradio/atoms@0.8.0
15
+ - @gradio/client@1.5.1
16
+ - @gradio/statustracker@0.7.5
17
+ - @gradio/icons@0.7.1
18
+ - @gradio/image@0.15.0
19
+ - @gradio/video@0.10.3
20
+
3
21
  ## 0.5.5
4
22
 
5
23
  ### Dependency updates
package/Index.svelte CHANGED
@@ -50,16 +50,19 @@
50
50
  export let interactive: boolean;
51
51
  export let root: string;
52
52
  export let file_count: "single" | "multiple" | "directory";
53
+
54
+ let dragging: boolean;
53
55
  </script>
54
56
 
55
57
  <Block
56
58
  {visible}
57
59
  {elem_id}
58
- {elem_classes}
60
+ elem_classes={[...elem_classes, "multimodal-textbox"]}
59
61
  {scale}
60
62
  {min_width}
61
63
  allow_overflow={false}
62
64
  padding={container}
65
+ border_mode={dragging ? "focus" : "base"}
63
66
  >
64
67
  {#if loading_status}
65
68
  <StatusTracker
@@ -73,6 +76,7 @@
73
76
  <MultimodalTextbox
74
77
  bind:value
75
78
  bind:value_is_output
79
+ bind:dragging
76
80
  {file_types}
77
81
  {root}
78
82
  {label}
@@ -103,3 +107,11 @@
103
107
  stream_handler={gradio.client.stream}
104
108
  />
105
109
  </Block>
110
+
111
+ <style>
112
+ :global(.form .block.multimodal-textbox) {
113
+ box-shadow: var(--block-shadow) !important;
114
+ border-width: var(--block-border-width) !important;
115
+ border-radius: var(--block-radius) !important;
116
+ }
117
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/multimodaltextbox",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -14,16 +14,21 @@
14
14
  "./package.json": "./package.json"
15
15
  },
16
16
  "dependencies": {
17
- "@gradio/icons": "^0.7.0",
18
- "@gradio/statustracker": "^0.7.4",
19
- "@gradio/upload": "^0.12.2",
20
- "@gradio/image": "^0.14.0",
21
- "@gradio/video": "^0.10.2",
22
- "@gradio/client": "^1.5.0",
23
- "@gradio/utils": "^0.5.2",
24
- "@gradio/atoms": "^0.7.9"
17
+ "@gradio/atoms": "^0.8.0",
18
+ "@gradio/icons": "^0.7.1",
19
+ "@gradio/statustracker": "^0.7.5",
20
+ "@gradio/upload": "^0.12.3",
21
+ "@gradio/utils": "^0.6.0",
22
+ "@gradio/image": "^0.15.0",
23
+ "@gradio/video": "^0.10.3",
24
+ "@gradio/client": "^1.5.1"
25
25
  },
26
26
  "devDependencies": {
27
- "@gradio/preview": "^0.10.2"
27
+ "@gradio/preview": "^0.11.0"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/gradio-app/gradio.git",
32
+ "directory": "js/multimodaltextbox"
28
33
  }
29
34
  }
@@ -45,11 +45,13 @@
45
45
  let can_scroll: boolean;
46
46
  let previous_scroll_top = 0;
47
47
  let user_has_scrolled_up = false;
48
- let dragging = false;
48
+ export let dragging = false;
49
49
  let uploading = false;
50
50
  let oldValue = value.text;
51
51
  $: dispatch("drag", dragging);
52
52
 
53
+ let full_container: HTMLDivElement;
54
+
53
55
  $: if (oldValue !== value.text) {
54
56
  dispatch("change", value);
55
57
  oldValue = value.text;
@@ -201,109 +203,168 @@
201
203
  }
202
204
  }
203
205
  }
206
+
207
+ function handle_dragenter(event: DragEvent): void {
208
+ event.preventDefault();
209
+ dragging = true;
210
+ }
211
+
212
+ function handle_dragleave(event: DragEvent): void {
213
+ event.preventDefault();
214
+ const rect = full_container.getBoundingClientRect();
215
+ const { clientX, clientY } = event;
216
+ if (
217
+ clientX <= rect.left ||
218
+ clientX >= rect.right ||
219
+ clientY <= rect.top ||
220
+ clientY >= rect.bottom
221
+ ) {
222
+ dragging = false;
223
+ }
224
+ }
225
+
226
+ function handle_drop(event: DragEvent): void {
227
+ event.preventDefault();
228
+ dragging = false;
229
+ if (event.dataTransfer && event.dataTransfer.files) {
230
+ upload_component.load_files(Array.from(event.dataTransfer.files));
231
+ }
232
+ }
204
233
  </script>
205
234
 
206
- <!-- svelte-ignore a11y-autofocus -->
207
- <label class:container>
208
- <BlockTitle {show_label} {info}>{label}</BlockTitle>
209
- {#if value.files.length > 0 || uploading}
210
- <div
211
- class="thumbnails scroll-hide"
212
- data-testid="container_el"
213
- style="display: {value.files.length > 0 || uploading ? 'flex' : 'none'};"
214
- >
215
- {#each value.files as file, index}
216
- <button class="thumbnail-item thumbnail-small">
217
- <button
218
- class:disabled
219
- class="delete-button"
220
- on:click={(event) => remove_thumbnail(event, index)}
221
- ><Clear /></button
222
- >
223
- {#if file.mime_type && file.mime_type.includes("image")}
224
- <Image
225
- src={file.url}
226
- title={null}
227
- alt=""
228
- loading="lazy"
229
- class={"thumbnail-image"}
230
- />
231
- {:else if file.mime_type && file.mime_type.includes("audio")}
232
- <Music />
233
- {:else if file.mime_type && file.mime_type.includes("video")}
234
- <Video />
235
+ <div
236
+ class="full-container"
237
+ class:dragging
238
+ bind:this={full_container}
239
+ on:dragenter={handle_dragenter}
240
+ on:dragleave={handle_dragleave}
241
+ on:dragover|preventDefault
242
+ on:drop={handle_drop}
243
+ role="group"
244
+ aria-label="Multimedia input field"
245
+ >
246
+ <!-- svelte-ignore a11y-autofocus -->
247
+ <label class:container>
248
+ <BlockTitle {show_label} {info}>{label}</BlockTitle>
249
+ {#if value.files.length > 0 || uploading}
250
+ <div
251
+ class="thumbnails scroll-hide"
252
+ aria-label="Uploaded files"
253
+ data-testid="container_el"
254
+ style="display: {value.files.length > 0 || uploading
255
+ ? 'flex'
256
+ : 'none'};"
257
+ >
258
+ {#each value.files as file, index}
259
+ <span role="listitem" aria-label="File thumbnail">
260
+ <button class="thumbnail-item thumbnail-small">
261
+ <button
262
+ class:disabled
263
+ class="delete-button"
264
+ on:click={(event) => remove_thumbnail(event, index)}
265
+ ><Clear /></button
266
+ >
267
+ {#if file.mime_type && file.mime_type.includes("image")}
268
+ <Image
269
+ src={file.url}
270
+ title={null}
271
+ alt=""
272
+ loading="lazy"
273
+ class={"thumbnail-image"}
274
+ />
275
+ {:else if file.mime_type && file.mime_type.includes("audio")}
276
+ <Music />
277
+ {:else if file.mime_type && file.mime_type.includes("video")}
278
+ <Video />
279
+ {:else}
280
+ <File />
281
+ {/if}
282
+ </button>
283
+ </span>
284
+ {/each}
285
+ {#if uploading}
286
+ <div class="loader" role="status" aria-label="Uploading"></div>
287
+ {/if}
288
+ </div>
289
+ {/if}
290
+ <div class="input-container">
291
+ <Upload
292
+ bind:this={upload_component}
293
+ on:load={handle_upload}
294
+ {file_count}
295
+ {root}
296
+ {max_file_size}
297
+ bind:dragging
298
+ bind:uploading
299
+ show_progress={false}
300
+ disable_click={true}
301
+ bind:hidden_upload
302
+ on:error
303
+ hidden={true}
304
+ {upload}
305
+ {stream_handler}
306
+ ></Upload>
307
+ <button
308
+ data-testid="upload-button"
309
+ class="upload-button"
310
+ on:click={handle_upload_click}><Paperclip /></button
311
+ >
312
+ <textarea
313
+ data-testid="textbox"
314
+ use:text_area_resize={{
315
+ text: value.text,
316
+ lines: lines,
317
+ max_lines: max_lines
318
+ }}
319
+ class="scroll-hide"
320
+ dir={rtl ? "rtl" : "ltr"}
321
+ bind:value={value.text}
322
+ bind:this={el}
323
+ {placeholder}
324
+ rows={lines}
325
+ {disabled}
326
+ {autofocus}
327
+ on:keypress={handle_keypress}
328
+ on:blur
329
+ on:select={handle_select}
330
+ on:focus
331
+ on:scroll={handle_scroll}
332
+ on:paste={handle_paste}
333
+ style={text_align ? "text-align: " + text_align : ""}
334
+ />
335
+ {#if submit_btn}
336
+ <button
337
+ class="submit-button"
338
+ class:padded-button={submit_btn !== true}
339
+ on:click={handle_submit}
340
+ >
341
+ {#if submit_btn === true}
342
+ <Send />
235
343
  {:else}
236
- <File />
344
+ Hello World
237
345
  {/if}
238
346
  </button>
239
- {/each}
240
- {#if uploading}
241
- <div class="loader"></div>
242
347
  {/if}
243
348
  </div>
244
- {/if}
245
- <div class="input-container">
246
- <Upload
247
- bind:this={upload_component}
248
- on:load={handle_upload}
249
- {file_count}
250
- {root}
251
- {max_file_size}
252
- bind:dragging
253
- bind:uploading
254
- show_progress={false}
255
- disable_click={true}
256
- bind:hidden_upload
257
- on:error
258
- hidden={true}
259
- {upload}
260
- {stream_handler}
261
- ></Upload>
262
- <button
263
- data-testid="upload-button"
264
- class="upload-button"
265
- on:click={handle_upload_click}><Paperclip /></button
266
- >
267
- <textarea
268
- data-testid="textbox"
269
- use:text_area_resize={{
270
- text: value.text,
271
- lines: lines,
272
- max_lines: max_lines
273
- }}
274
- class="scroll-hide"
275
- dir={rtl ? "rtl" : "ltr"}
276
- bind:value={value.text}
277
- bind:this={el}
278
- {placeholder}
279
- rows={lines}
280
- {disabled}
281
- {autofocus}
282
- on:keypress={handle_keypress}
283
- on:blur
284
- on:select={handle_select}
285
- on:focus
286
- on:scroll={handle_scroll}
287
- on:paste={handle_paste}
288
- style={text_align ? "text-align: " + text_align : ""}
289
- />
290
- {#if submit_btn}
291
- <button
292
- class="submit-button"
293
- class:padded-button={submit_btn !== true}
294
- on:click={handle_submit}
295
- >
296
- {#if submit_btn === true}
297
- <Send />
298
- {:else}
299
- Hello World
300
- {/if}
301
- </button>
302
- {/if}
303
- </div>
304
- </label>
349
+ </label>
350
+ </div>
305
351
 
306
352
  <style>
353
+ .full-container {
354
+ width: 100%;
355
+ position: relative;
356
+ }
357
+
358
+ .full-container.dragging::after {
359
+ content: "";
360
+ position: absolute;
361
+ top: 0;
362
+ left: 0;
363
+ right: 0;
364
+ bottom: 0;
365
+ pointer-events: none;
366
+ }
367
+
307
368
  .input-container {
308
369
  display: flex;
309
370
  position: relative;
@@ -323,6 +384,8 @@
323
384
  margin-top: 0px;
324
385
  margin-bottom: 0px;
325
386
  resize: none;
387
+ position: relative;
388
+ z-index: 1;
326
389
  }
327
390
 
328
391
  textarea:disabled {
@@ -351,6 +414,7 @@
351
414
  justify-content: center;
352
415
  align-items: center;
353
416
  margin-bottom: 5px;
417
+ z-index: var(--layer-1);
354
418
  }
355
419
  .padded-button {
356
420
  padding: 0 10px;
@@ -406,11 +470,11 @@
406
470
  }
407
471
 
408
472
  .thumbnails {
409
- align-self: flex-start;
410
473
  display: flex;
411
- justify-content: left;
412
474
  align-items: center;
413
475
  gap: var(--spacing-lg);
476
+ overflow-x: scroll;
477
+ padding-top: var(--spacing-sm);
414
478
  }
415
479
 
416
480
  .thumbnail-item {