Skip to content

Commit

Permalink
Allows setting a height to gr.File and improves the UI of the compo…
Browse files Browse the repository at this point in the history
…nent (#5221)

* file

* file downlaod

* add changeset

* added story

* lint

* fix test

* add changeset

* margin

* fixes

* lint

* modify

* lint

* add changeset

* revert

* revert

* add changeset

* Delete Chatbot.stories.svelte

* revert

* revert

* add changeset

* redesign

* lint

* fixes

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
  • Loading branch information
abidlabs and gradio-pr-bot committed Aug 18, 2023
1 parent ddac7e4 commit f344592
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 15 deletions.
6 changes: 6 additions & 0 deletions .changeset/lovely-bikes-thank.md
@@ -0,0 +1,6 @@
---
"@gradio/file": minor
"gradio": minor
---

feat:Allows setting a height to `gr.File` and improves the UI of the component
6 changes: 6 additions & 0 deletions gradio/components/file.py
Expand Up @@ -55,6 +55,7 @@ def __init__(
container: bool = True,
scale: int | None = None,
min_width: int = 160,
height: int | float | None = None,
interactive: bool | None = None,
visible: bool = True,
elem_id: str | None = None,
Expand All @@ -73,6 +74,7 @@ def __init__(
container: If True, will place the component in a container - providing some extra padding around the border.
scale: relative width compared to adjacent Components in a Row. For example, if Component A has scale=2, and Component B has scale=1, A will be twice as wide as B. Should be an integer.
min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.
height: The maximum height of the file component, in pixels. If more files are uploaded than can fit in the height, a scrollbar will appear.
interactive: if True, will allow users to upload a file; if False, can only be used to display files. If not provided, this is inferred based on whether the component is used as an input or output.
visible: If False, component will be hidden.
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
Expand Down Expand Up @@ -102,6 +104,7 @@ def __init__(
"The `file_types` parameter is ignored when `file_count` is 'directory'."
)
self.type = type
self.height = height
self.select: EventListenerMethod
"""
Event listener for when the user selects file from list.
Expand Down Expand Up @@ -130,6 +133,7 @@ def get_config(self):
"file_types": self.file_types,
"value": self.value,
"selectable": self.selectable,
"height": self.height,
**IOComponent.get_config(self),
}

Expand All @@ -141,6 +145,7 @@ def update(
container: bool | None = None,
scale: int | None = None,
min_width: int | None = None,
height: int | float | None = None,
interactive: bool | None = None,
visible: bool | None = None,
):
Expand All @@ -150,6 +155,7 @@ def update(
"container": container,
"scale": scale,
"min_width": min_width,
"height": height,
"interactive": interactive,
"visible": visible,
"value": value,
Expand Down
6 changes: 3 additions & 3 deletions gradio/components/gallery.py
Expand Up @@ -48,7 +48,7 @@ def __init__(
elem_classes: list[str] | str | None = None,
columns: int | tuple | None = 2,
rows: int | tuple | None = None,
height: str | None = None,
height: int | float | None = None,
preview: bool | None = None,
object_fit: Literal["contain", "cover", "fill", "none", "scale-down"]
| None = None,
Expand All @@ -71,7 +71,7 @@ def __init__(
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
columns: Represents the number of images that should be shown in one row, for each of the six standard screen sizes (<576px, <768px, <992px, <1200px, <1400px, >1400px). if fewer that 6 are given then the last will be used for all subsequent breakpoints
rows: Represents the number of rows in the image grid, for each of the six standard screen sizes (<576px, <768px, <992px, <1200px, <1400px, >1400px). if fewer that 6 are given then the last will be used for all subsequent breakpoints
height: Height of the gallery.
height: The height of the gallery component, in pixels. If more images are displayed than can fit in the height, a scrollbar will appear.
preview: If True, will display the Gallery in preview mode, which shows all of the images as thumbnails and allows the user to click on them to view them in full size.
object_fit: CSS object-fit property for the thumbnail images in the gallery. Can be "contain", "cover", "fill", "none", or "scale-down".
allow_preview: If True, images in the gallery will be enlarged when they are clicked. Default is True.
Expand Down Expand Up @@ -127,7 +127,7 @@ def update(
visible: bool | None = None,
columns: int | tuple | None = None,
rows: int | tuple | None = None,
height: str | None = None,
height: int | float | None = None,
preview: bool | None = None,
object_fit: Literal["contain", "cover", "fill", "none", "scale-down"]
| None = None,
Expand Down
45 changes: 45 additions & 0 deletions js/file/File.stories.svelte
@@ -0,0 +1,45 @@
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import FilePreview from "./shared/FilePreview.svelte";
</script>

<Meta
title="Components/File"
component={FilePreview}
argTypes={{
value: {
control: "text",
description: "The URL or filepath (or list of URLs or filepaths)",
name: "value",
value: []
}
}}
/>

<Template let:args>
<FilePreview {...args} />
</Template>

<Story
name="Default"
args={{
value: [
{
name: "groot.jpg",
data: "https://i.ibb.co/6BgKdSj/groot.jpg",
size: 10000
}
]
}}
/>
<Story
name="With height set to 80px"
args={{
value: Array(10).fill({
name: "groot.jpg",
data: "https://i.ibb.co/6BgKdSj/groot.jpg",
size: 10000
}),
height: 80
}}
/>
3 changes: 3 additions & 0 deletions js/file/index.svelte
Expand Up @@ -31,6 +31,7 @@
export let container = true;
export let scale: number | null = null;
export let min_width: number | undefined = undefined;
export let height: number | undefined = undefined;
</script>

{#if mode === "static"}
Expand All @@ -49,6 +50,7 @@
{container}
{scale}
{min_width}
{height}
on:clear
on:select
on:change
Expand All @@ -73,6 +75,7 @@
{container}
{scale}
{min_width}
{height}
on:clear
on:select
on:change
Expand Down
3 changes: 2 additions & 1 deletion js/file/interactive/FileUpload.svelte
Expand Up @@ -14,6 +14,7 @@
export let file_count = "single";
export let file_types: string[] | null = null;
export let selectable = false;
export let height: number | undefined = undefined;
async function handle_upload({
detail
Expand Down Expand Up @@ -64,7 +65,7 @@

{#if value}
<ModifyUpload on:clear={handle_clear} absolute />
<FilePreview on:select {selectable} {value} />
<FilePreview on:select {selectable} {value} {height} />
{:else}
<Upload
on:load={handle_upload}
Expand Down
4 changes: 4 additions & 0 deletions js/file/interactive/InteractiveFile.svelte
Expand Up @@ -33,6 +33,7 @@
export let container = true;
export let scale: number | null = null;
export let min_width: number | undefined = undefined;
export let height: number | undefined = undefined;
const upload_files =
getContext<typeof default_upload_files>("upload_files") ??
Expand Down Expand Up @@ -113,6 +114,8 @@
{container}
{scale}
{min_width}
{height}
allow_overflow={false}
>
<StatusTracker
{...loading_status}
Expand All @@ -128,6 +131,7 @@
{file_count}
{file_types}
{selectable}
{height}
on:change={({ detail }) => (value = detail)}
on:drag={({ detail }) => (dragging = detail)}
on:clear
Expand Down
22 changes: 16 additions & 6 deletions js/file/shared/FilePreview.svelte
Expand Up @@ -9,9 +9,13 @@
}>();
export let value: FileData | FileData[];
export let selectable = false;
export let height: number | undefined = undefined;
</script>

<div class="file-preview-holder">
<div
class="file-preview-holder"
style="max-height: {typeof height === undefined ? 'auto' : height + 'px'};"
>
<table class="file-preview">
<tbody>
{#each Array.isArray(value) ? value : [value] as file, i}
Expand All @@ -28,10 +32,6 @@
{display_file_name(file)}
</td>

<td>
{display_file_size(file)}
</td>

<td class="download">
{#if file.data}
<a
Expand All @@ -41,7 +41,7 @@
? null
: file.orig_name || file.name}
>
Download
{@html display_file_size(file)}&nbsp;&#8675;
</a>
{:else}
Uploading...
Expand All @@ -64,11 +64,13 @@
}
.file-preview-holder {
overflow-x: auto;
overflow-y: scroll;
}
.file-preview {
width: var(--size-full);
max-height: var(--size-60);
overflow-y: auto;
margin-top: var(--size-1);
color: var(--body-text-color);
}
.file {
Expand Down Expand Up @@ -98,4 +100,12 @@
.selectable {
cursor: pointer;
}
tbody > tr:nth-child(even) {
background: var(--block-background-fill);
}
tbody > tr:nth-child(odd) {
background: var(--table-odd-background-fill);
}
</style>
14 changes: 11 additions & 3 deletions js/file/shared/utils.ts
Expand Up @@ -8,14 +8,22 @@ export const prettyBytes = (bytes: number): string => {
i++;
}
let unit = units[i];
return bytes.toFixed(1) + " " + unit;
return bytes.toFixed(1) + "&nbsp;" + unit;
};

export const display_file_name = (value: FileData): string => {
var str: string;
str = value.orig_name || value.name;
if (str.length > 30) {
return `${str.substr(0, 30)}...`;
const max_length = 30;

if (str.length > max_length) {
const truncated_name = str.substring(0, max_length);
const file_extension_index = str.lastIndexOf(".");
if (file_extension_index !== -1) {
const file_extension = str.slice(file_extension_index);
return `${truncated_name}..${file_extension}`;
}
return truncated_name;
}
return str;
};
Expand Down
3 changes: 2 additions & 1 deletion js/file/static/File.svelte
Expand Up @@ -8,6 +8,7 @@
export let label: string;
export let show_label = true;
export let selectable = false;
export let height: number | undefined = undefined;
</script>

<BlockLabel
Expand All @@ -18,7 +19,7 @@
/>

{#if value}
<FilePreview {selectable} on:select {value} />
<FilePreview {selectable} on:select {value} {height} />
{:else}
<Empty unpadded_box={true} size="large"><File /></Empty>
{/if}
3 changes: 2 additions & 1 deletion js/file/static/StaticFile.svelte
Expand Up @@ -25,6 +25,7 @@
export let root: string;
export let label: string;
export let show_label: boolean;
export let height: number | undefined = undefined;
export let root_url: null | string;
export let selectable = false;
Expand Down Expand Up @@ -120,5 +121,5 @@
: loading_status?.status || "complete"}
/>

<File on:select {selectable} value={_value} {label} {show_label} />
<File on:select {selectable} value={_value} {label} {show_label} {height} />
</Block>
1 change: 1 addition & 0 deletions test/test_components.py
Expand Up @@ -1014,6 +1014,7 @@ def test_component_functions(self):
"interactive": None,
"root_url": None,
"selectable": False,
"height": None,
}
assert file_input.preprocess(None) is None
x_file["is_example"] = True
Expand Down

0 comments on commit f344592

Please sign in to comment.