Remove style parameter (#4374)

* changes

* changes

* changes

* changes

* changes

* changes

* fixes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes
This commit is contained in:
aliabid94 2023-06-07 18:35:31 -07:00 committed by GitHub
parent 8617291049
commit ff6e676a92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 1566 additions and 1214 deletions

View File

@ -35,6 +35,8 @@ No changes to highlight.
## Other Changes:
- When running on Spaces, handler functions will be transformed by the [PySpaces](https://pypi.org/project/spaces/) library in order to make them work with specific hardware. It will have no effect on standalone Gradio apps or regular Gradio Spaces and can be globally deactivated as follows : `import spaces; spaces.disable_gradio_auto_wrap()` by [@cbensimon](https://github.com/cbensimon) in [PR 4389](https://github.com/gradio-app/gradio/pull/4389).
- Deprecated `.style` parameter and moved arguments to constructor. Added support for `.update()` to all arguments initially in style. Added `scale` and `min_width` support to every Component. By [@aliabid94](https://github.com/aliabid94) in [PR 4374](https://github.com/gradio-app/gradio/pull/4374)
## Breaking Changes:

View File

@ -1 +1 @@
{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: blocks_layout"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "\n", "demo = gr.Blocks()\n", "\n", "with demo:\n", " with gr.Row():\n", " gr.Image(interactive=True)\n", " gr.Image()\n", " with gr.Row():\n", " gr.Textbox(label=\"Text\")\n", " gr.Number(label=\"Count\")\n", " gr.Radio(choices=[\"One\", \"Two\"])\n", " with gr.Row():\n", " with gr.Row():\n", " with gr.Column():\n", " gr.Textbox(label=\"Text\")\n", " gr.Number(label=\"Count\")\n", " gr.Radio(choices=[\"One\", \"Two\"])\n", " gr.Image()\n", " with gr.Column():\n", " gr.Image(interactive=True)\n", " gr.Image()\n", " gr.Image()\n", " gr.Textbox(label=\"Text\")\n", " gr.Number(label=\"Count\")\n", " gr.Radio(choices=[\"One\", \"Two\"])\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: blocks_layout"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "\n", "demo = gr.Blocks()\n", "\n", "with demo:\n", " with gr.Row():\n", " gr.Image(interactive=True, scale=2)\n", " gr.Image()\n", " with gr.Row():\n", " gr.Textbox(label=\"Text\")\n", " gr.Number(label=\"Count\", scale=2)\n", " gr.Radio(choices=[\"One\", \"Two\"])\n", " with gr.Row():\n", " gr.Button(\"500\", scale=0, min_width=500)\n", " gr.Button(\"A\").style(full_width=False)\n", " gr.Button(\"grow\")\n", " with gr.Row():\n", " gr.Textbox()\n", " gr.Textbox()\n", " gr.Button() \n", " with gr.Row():\n", " with gr.Row():\n", " with gr.Column():\n", " gr.Textbox(label=\"Text\")\n", " gr.Number(label=\"Count\")\n", " gr.Radio(choices=[\"One\", \"Two\"])\n", " gr.Image()\n", " with gr.Column():\n", " gr.Image(interactive=True)\n", " gr.Image()\n", " gr.Image()\n", " gr.Textbox(label=\"Text\")\n", " gr.Number(label=\"Count\")\n", " gr.Radio(choices=[\"One\", \"Two\"])\n", "\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}

View File

@ -5,12 +5,20 @@ demo = gr.Blocks()
with demo:
with gr.Row():
gr.Image(interactive=True)
gr.Image(interactive=True, scale=2)
gr.Image()
with gr.Row():
gr.Textbox(label="Text")
gr.Number(label="Count")
gr.Number(label="Count", scale=2)
gr.Radio(choices=["One", "Two"])
with gr.Row():
gr.Button("500", scale=0, min_width=500)
gr.Button("A").style(full_width=False)
gr.Button("grow")
with gr.Row():
gr.Textbox()
gr.Textbox()
gr.Button()
with gr.Row():
with gr.Row():
with gr.Column():

View File

@ -97,7 +97,6 @@ class Block:
self.root_url = root_url
self.share_token = secrets.token_urlsafe(32)
self._skip_init_processing = _skip_init_processing
self._style = {}
self.parent: BlockContext | None = None
if render:
@ -297,7 +296,6 @@ class Block:
"visible": self.visible,
"elem_id": self.elem_id,
"elem_classes": self.elem_classes,
"style": self._style,
"root_url": self.root_url,
}
@ -329,6 +327,9 @@ class BlockContext(Block):
self.children: list[Block] = []
Block.__init__(self, visible=visible, render=render, **kwargs)
def add_child(self, child: Block):
self.children.append(child)
def __enter__(self):
self.parent = Context.block
Context.block = self
@ -350,11 +351,12 @@ class BlockContext(Block):
if pseudo_parent is not None and isinstance(
pseudo_parent, expected_parent
):
pseudo_parent.children.append(child)
pseudo_parent.add_child(child)
else:
pseudo_parent = expected_parent(render=False)
pseudo_parent.parent = self
children.append(pseudo_parent)
pseudo_parent.children = [child]
pseudo_parent.add_child(child)
if Context.root_block:
Context.root_block.blocks[pseudo_parent._id] = pseudo_parent
child.parent = pseudo_parent
@ -772,6 +774,11 @@ class Blocks(BlockContext):
"""
config = copy.deepcopy(config)
components_config = config["components"]
for component_config in components_config:
# for backwards compatibility, extract style into props
if "style" in component_config["props"]:
component_config["props"].update(component_config["props"]["style"])
del component_config["props"]["style"]
theme = config.get("theme", "default")
original_mapping: dict[int, Block] = {}
root_urls = {root_url}
@ -785,7 +792,6 @@ class Blocks(BlockContext):
cls = component_or_layout_class(block_config["type"])
block_config["props"].pop("type", None)
block_config["props"].pop("name", None)
style = block_config["props"].pop("style", None)
# If a Gradio app B is loaded into a Gradio app A, and B itself loads a
# Gradio app C, then the root_urls of the components in A need to be the
# URL of C, not B. The else clause below handles this case.
@ -795,8 +801,6 @@ class Blocks(BlockContext):
root_urls.add(block_config["props"]["root_url"])
# Any component has already processed its initial value, so we skip that step here
block = cls(**block_config["props"], _skip_init_processing=True)
if style and isinstance(block, components.IOComponent):
block.style(**style)
return block
def iterate_over_children(children_list):

File diff suppressed because it is too large Load Diff

View File

@ -403,7 +403,7 @@ class Interface(Blocks):
interpretation_btn, interpretation_set = None, None
input_component_column, interpret_component_column = None, None
with Row().style(equal_height=False):
with Row(equal_height=False):
if self.interface_type in [
InterfaceTypes.STANDARD,
InterfaceTypes.INPUT_ONLY,

View File

@ -1,12 +1,16 @@
from __future__ import annotations
import warnings
from typing import TYPE_CHECKING
from gradio_client.documentation import document, set_documentation_group
from gradio.blocks import BlockContext
from gradio.events import Changeable, Selectable
if TYPE_CHECKING:
from gradio.blocks import Block
set_documentation_group("layout")
@ -17,8 +21,8 @@ class Row(BlockContext):
Example:
with gr.Blocks() as demo:
with gr.Row():
gr.Image("lion.jpg")
gr.Image("tiger.jpg")
gr.Image("lion.jpg", scale=2)
gr.Image("tiger.jpg", scale=1)
demo.launch()
Guides: controlling-layout
"""
@ -29,6 +33,7 @@ class Row(BlockContext):
variant: str = "default",
visible: bool = True,
elem_id: str | None = None,
equal_height: bool = True,
**kwargs,
):
"""
@ -36,14 +41,21 @@ class Row(BlockContext):
variant: row type, 'default' (no background), 'panel' (gray background color and rounded corners), or 'compact' (rounded corners and no internal gap).
visible: If False, row 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.
equal_height: If True, makes every child element have equal height
"""
self.variant = variant
self.equal_height = equal_height
if variant == "compact":
self.allow_expected_parents = False
super().__init__(visible=visible, elem_id=elem_id, **kwargs)
def get_config(self):
return {"type": "row", "variant": self.variant, **super().get_config()}
return {
"type": "row",
"variant": self.variant,
"equal_height": self.equal_height,
**super().get_config(),
}
@staticmethod
def update(
@ -58,19 +70,18 @@ class Row(BlockContext):
self,
*,
equal_height: bool | None = None,
mobile_collapse: bool | None = None,
**kwargs,
):
"""
Styles the Row.
Parameters:
equal_height: If True, makes every child element have equal height
mobile_collapse: DEPRECATED.
"""
warnings.warn(
"The `style` method is deprecated. Please set these arguments in the constructor instead."
)
if equal_height is not None:
self._style["equal_height"] = equal_height
if mobile_collapse is not None:
warnings.warn("mobile_collapse is no longer supported.")
self.equal_height = equal_height
return self
@ -301,12 +312,35 @@ class Box(BlockContext):
}
def style(self, **kwargs):
warnings.warn("The `style` method is deprecated.")
return self
class Form(BlockContext):
def __init__(self, *, scale: int = 0, min_width: int = 0, **kwargs):
"""
Parameters:
scale: relative width compared to adjacent Columns. For example, if Column A has scale=2, and Column B has scale=1, A will be twice as wide as B.
min_width: minimum pixel width of Column, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in a column narrower than min_width, the min_width parameter will be respected first.
"""
self.scale = scale
self.min_width = min_width
super().__init__(**kwargs)
def add_child(self, child: Block):
if isinstance(self.parent, Row):
scale = getattr(child, "scale", None)
self.scale += 1 if scale is None else scale
self.min_width += getattr(child, "min_width", 0)
super().add_child(child)
def get_config(self):
return {"type": "form", **super().get_config()}
return {
"type": "form",
"scale": self.scale,
"min_width": self.min_width,
**super().get_config(),
}
@document()

View File

@ -1,33 +1,33 @@
XRAY_CONFIG = {
"version": "3.26.0\n",
"version": "3.32.0\n",
"mode": "blocks",
"dev_mode": True,
"analytics_enabled": False,
"components": [
{
"id": 6,
"id": 1,
"type": "markdown",
"props": {
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 7,
"id": 2,
"type": "checkboxgroup",
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"value": [],
"label": "Disease to Scan For",
"show_label": True,
"container": True,
"min_width": 160,
"name": "checkboxgroup",
"visible": True,
"style": {},
},
"serializer": "ListStringSerializable",
"api_info": {
@ -36,20 +36,87 @@ XRAY_CONFIG = {
},
"example_inputs": {"raw": "Covid", "serialized": "Covid"},
},
{"id": 8, "type": "tabs", "props": {"visible": True, "style": {}}},
{"id": 3, "type": "tabs", "props": {"visible": True}},
{"id": 4, "type": "tabitem", "props": {"label": "X-ray", "visible": True}},
{
"id": 9,
"type": "tabitem",
"props": {"label": "X-ray", "visible": True, "style": {}},
"id": 5,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
},
},
{
"id": 6,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"visible": True,
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 7,
"type": "json",
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 8,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{"id": 9, "type": "tabitem", "props": {"label": "CT Scan", "visible": True}},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
"style": {},
},
},
{
@ -63,9 +130,10 @@ XRAY_CONFIG = {
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"visible": True,
"style": {},
},
"serializer": "ImgSerializable",
"api_info": {
@ -83,7 +151,13 @@ XRAY_CONFIG = {
{
"id": 12,
"type": "json",
"props": {"show_label": True, "name": "json", "visible": True, "style": {}},
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
@ -100,7 +174,6 @@ XRAY_CONFIG = {
"interactive": True,
"name": "button",
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
@ -108,17 +181,259 @@ XRAY_CONFIG = {
},
{
"id": 14,
"type": "tabitem",
"props": {"label": "CT Scan", "visible": True, "style": {}},
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"show_label": True,
"container": True,
"min_width": 160,
"name": "textbox",
"show_copy_button": False,
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 15,
"type": "form",
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
{
"id": 16,
"type": "form",
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
],
"css": None,
"title": "Gradio",
"is_space": False,
"enable_queue": None,
"show_error": True,
"show_api": True,
"is_colab": False,
"stylesheets": [
"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap",
"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap",
],
"theme": "default",
"layout": {
"id": 0,
"children": [
{"id": 1},
{"id": 15, "children": [{"id": 2}]},
{
"id": 3,
"children": [
{
"id": 4,
"children": [
{"id": 5, "children": [{"id": 6}, {"id": 7}]},
{"id": 8},
],
},
{
"id": 9,
"children": [
{"id": 10, "children": [{"id": 11}, {"id": 12}]},
{"id": 13},
],
},
],
},
{"id": 16, "children": [{"id": 14}]},
],
},
"dependencies": [
{
"targets": [8],
"trigger": "click",
"inputs": [2, 6],
"outputs": [7],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"show_progress": True,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [13],
"trigger": "click",
"inputs": [2, 11],
"outputs": [12],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"show_progress": True,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [],
"trigger": "load",
"inputs": [],
"outputs": [14],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"show_progress": True,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
],
}
XRAY_CONFIG_DIFF_IDS = {
"version": "3.32.0\n",
"mode": "blocks",
"dev_mode": True,
"analytics_enabled": False,
"components": [
{
"id": 6,
"type": "markdown",
"props": {
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 7,
"type": "checkboxgroup",
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"value": [],
"label": "Disease to Scan For",
"show_label": True,
"container": True,
"min_width": 160,
"name": "checkboxgroup",
"visible": True,
},
"serializer": "ListStringSerializable",
"api_info": {
"info": {"type": "array", "items": {"type": "string"}},
"serialized_info": False,
},
"example_inputs": {"raw": "Covid", "serialized": "Covid"},
},
{"id": 8, "type": "tabs", "props": {"visible": True}},
{"id": 9, "type": "tabitem", "props": {"label": "X-ray", "visible": True}},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
},
},
{
"id": 11,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"visible": True,
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 12,
"type": "json",
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 13,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{"id": 14, "type": "tabitem", "props": {"label": "CT Scan", "visible": True}},
{
"id": 15,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"visible": True,
"style": {},
},
},
{
@ -132,9 +447,10 @@ XRAY_CONFIG = {
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"container": True,
"min_width": 160,
"name": "image",
"visible": True,
"style": {},
},
"serializer": "ImgSerializable",
"api_info": {
@ -152,7 +468,13 @@ XRAY_CONFIG = {
{
"id": 17,
"type": "json",
"props": {"show_label": True, "name": "json", "visible": True, "style": {}},
"props": {
"show_label": True,
"container": True,
"min_width": 160,
"name": "json",
"visible": True,
},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
@ -169,7 +491,6 @@ XRAY_CONFIG = {
"interactive": True,
"name": "button",
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
@ -184,9 +505,11 @@ XRAY_CONFIG = {
"value": "",
"type": "text",
"show_label": True,
"container": True,
"min_width": 160,
"name": "textbox",
"show_copy_button": False,
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
@ -195,12 +518,12 @@ XRAY_CONFIG = {
{
"id": 20,
"type": "form",
"props": {"type": "form", "visible": True, "style": {}},
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
{
"id": 21,
"type": "form",
"props": {"type": "form", "visible": True, "style": {}},
"props": {"type": "form", "scale": 0, "min_width": 0, "visible": True},
},
],
"css": None,
@ -216,7 +539,7 @@ XRAY_CONFIG = {
],
"theme": "default",
"layout": {
"id": 5,
"id": 0,
"children": [
{"id": 6},
{"id": 20, "children": [{"id": 7}]},
@ -310,318 +633,6 @@ XRAY_CONFIG = {
}
XRAY_CONFIG_DIFF_IDS = {
"version": "3.26.0\n",
"mode": "blocks",
"dev_mode": True,
"analytics_enabled": False,
"components": [
{
"id": 6,
"type": "markdown",
"props": {
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 7,
"type": "checkboxgroup",
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"value": [],
"label": "Disease to Scan For",
"show_label": True,
"name": "checkboxgroup",
"visible": True,
"style": {},
},
"serializer": "ListStringSerializable",
"api_info": {
"info": {"type": "array", "items": {"type": "string"}},
"serialized_info": False,
},
"example_inputs": {"raw": "Covid", "serialized": "Covid"},
},
{"id": 8, "type": "tabs", "props": {"visible": True, "style": {}}},
{
"id": 9,
"type": "tabitem",
"props": {"label": "X-ray", "visible": True, "style": {}},
},
{
"id": 10,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"visible": True,
"style": {},
},
},
{
"id": 11,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"name": "image",
"visible": True,
"style": {},
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 2111,
"type": "json",
"props": {"show_label": True, "name": "json", "visible": True, "style": {}},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 13,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 14,
"type": "tabitem",
"props": {"label": "CT Scan", "visible": True, "style": {}},
},
{
"id": 15,
"type": "row",
"props": {
"type": "row",
"variant": "default",
"visible": True,
"style": {},
},
},
{
"id": 16,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"streaming": False,
"mirror_webcam": True,
"selectable": False,
"show_label": True,
"name": "image",
"visible": True,
"style": {},
},
"serializer": "ImgSerializable",
"api_info": {
"info": {
"type": "string",
"description": "base64 representation of an image",
},
"serialized_info": True,
},
"example_inputs": {
"raw": "data:image/png;base64,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",
"serialized": "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
},
},
{
"id": 17,
"type": "json",
"props": {"show_label": True, "name": "json", "visible": True, "style": {}},
"serializer": "JSONSerializable",
"api_info": {
"info": {"type": {}, "description": "any valid json"},
"serialized_info": True,
},
"example_inputs": {"raw": {"a": 1, "b": 2}, "serialized": None},
},
{
"id": 18,
"type": "button",
"props": {
"value": "Run",
"variant": "secondary",
"interactive": True,
"name": "button",
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 19,
"type": "textbox",
"props": {
"lines": 1,
"max_lines": 20,
"value": "",
"type": "text",
"show_label": True,
"name": "textbox",
"visible": True,
"style": {},
},
"serializer": "StringSerializable",
"api_info": {"info": {"type": "string"}, "serialized_info": False},
"example_inputs": {"raw": "Howdy!", "serialized": "Howdy!"},
},
{
"id": 20,
"type": "form",
"props": {"type": "form", "visible": True, "style": {}},
},
{
"id": 21,
"type": "form",
"props": {"type": "form", "visible": True, "style": {}},
},
],
"css": None,
"title": "Gradio",
"is_space": False,
"enable_queue": None,
"show_error": True,
"show_api": True,
"is_colab": False,
"stylesheets": [
"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap",
"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap",
],
"theme": "default",
"layout": {
"id": 5,
"children": [
{"id": 6},
{"id": 20, "children": [{"id": 7}]},
{
"id": 8,
"children": [
{
"id": 9,
"children": [
{"id": 10, "children": [{"id": 11}, {"id": 2111}]},
{"id": 13},
],
},
{
"id": 14,
"children": [
{"id": 15, "children": [{"id": 16}, {"id": 17}]},
{"id": 18},
],
},
],
},
{"id": 21, "children": [{"id": 19}]},
],
},
"dependencies": [
{
"targets": [13],
"trigger": "click",
"inputs": [7, 11],
"outputs": [2111],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"show_progress": True,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [18],
"trigger": "click",
"inputs": [7, 16],
"outputs": [17],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"show_progress": True,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
{
"targets": [],
"trigger": "load",
"inputs": [],
"outputs": [19],
"backend_fn": True,
"js": None,
"queue": None,
"api_name": None,
"scroll_to_output": False,
"show_progress": True,
"every": None,
"batch": False,
"max_batch_size": 4,
"cancels": [],
"types": {"continuous": False, "generator": False},
"collects_event_data": False,
"trigger_after": None,
"trigger_only_on_success": False,
"show_progress": "full",
},
],
}
XRAY_CONFIG_WITH_MISTAKE = {
"mode": "blocks",
"dev_mode": True,
@ -634,7 +645,6 @@ XRAY_CONFIG_WITH_MISTAKE = {
"props": {
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"style": {},
},
},
{
@ -646,14 +656,14 @@ XRAY_CONFIG_WITH_MISTAKE = {
"name": "checkboxgroup",
"show_label": True,
"label": "Disease to Scan For",
"style": {},
"container": True,
"min_width": 160,
},
},
{
"id": 3,
"type": "tabs",
"props": {
"style": {},
"value": True,
},
},
@ -662,14 +672,18 @@ XRAY_CONFIG_WITH_MISTAKE = {
"type": "tabitem",
"props": {
"label": "X-ray",
"style": {},
"value": True,
},
},
{
"id": 5,
"type": "row",
"props": {"type": "row", "variant": "default", "style": {}, "value": True},
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"value": True,
},
},
{
"id": 6,
@ -681,7 +695,6 @@ XRAY_CONFIG_WITH_MISTAKE = {
"mirror_webcam": True,
"tool": "editor",
"name": "image",
"style": {},
"selectable": False,
},
},
@ -690,7 +703,6 @@ XRAY_CONFIG_WITH_MISTAKE = {
"type": "json",
"props": {
"name": "json",
"style": {},
},
},
{
@ -710,14 +722,18 @@ XRAY_CONFIG_WITH_MISTAKE = {
"props": {
"show_label": True,
"label": "CT Scan",
"style": {},
"value": True,
},
},
{
"id": 10,
"type": "row",
"props": {"type": "row", "variant": "default", "style": {}, "value": True},
"props": {
"type": "row",
"variant": "default",
"equal_height": True,
"value": True,
},
},
{
"id": 11,
@ -729,7 +745,6 @@ XRAY_CONFIG_WITH_MISTAKE = {
"streaming": False,
"mirror_webcam": True,
"name": "image",
"style": {},
"selectable": False,
},
},
@ -738,7 +753,6 @@ XRAY_CONFIG_WITH_MISTAKE = {
"type": "json",
"props": {
"name": "json",
"style": {},
},
},
{
@ -748,7 +762,6 @@ XRAY_CONFIG_WITH_MISTAKE = {
"value": "Run",
"interactive": True,
"name": "button",
"style": {},
"variant": "secondary",
},
},
@ -759,8 +772,8 @@ XRAY_CONFIG_WITH_MISTAKE = {
"lines": 1,
"value": "",
"name": "textbox",
"show_copy_button": False,
"type": "text",
"style": {},
},
},
],

View File

@ -22,6 +22,20 @@ with gr.Blocks() as demo:
btn2 = gr.Button("Button 2")
```
The widths of elements in a Row can be controlled via a combination of `scale` and `min_width` arguments that are present in every Component.
- `scale` is an integer that defines how an element will take up space in a Row. If scale is set to `0`, and element will not expand to take up space. If scale is set to `1` or greater, the element well expand. Multiple elements in a row will expand proportional to their scale. Below, `btn1` will expand twice as much as `btn2`, while `btn0` will not expand at all:
```python
with gr.Blocks() as demo:
with gr.Row():
btn0 = gr.Button("Button 0", scale=0)
btn1 = gr.Button("Button 1", scale=1)
btn2 = gr.Button("Button 2", scale=2)
```
- `min_width` will set the minimum width the element will take. The Row will wrap if there isn't sufficient space to satisfy all `min_width` values.
Learn more about Rows in the [docs](https://gradio.app/docs/#row).
## Columns and Nesting
@ -33,8 +47,6 @@ $demo_rows_and_columns
See how the first column has two Textboxes arranged vertically. The second column has an Image and Button arranged vertically. Notice how the relative widths of the two columns is set by the `scale` parameter. The column with twice the `scale` value takes up twice the width.
Columns have a `min_width` parameter as well (320 pixels by default). This prevents adjacent columns from becoming too narrow on mobile screens.
Learn more about Columns in the [docs](https://gradio.app/docs/#column).
## Tabs and Accordions

View File

@ -68,14 +68,7 @@
/>
</Form>
<Button
size="lg"
variant="primary"
style={{ full_width: true }}
on:click={submit}
>
Login
</Button>
<Button size="lg" variant="primary" on:click={submit}>Login</Button>
</Column>
</div>

View File

@ -60,11 +60,7 @@
</Block>
<span class="space" />
<Button
variant="primary"
on:click={run.bind(null, dependency_index)}
style={{ full_width: true }}
>
<Button variant="primary" on:click={run.bind(null, dependency_index)}>
Try It Out
</Button>

View File

@ -7,11 +7,7 @@
</script>
<span class="space" />
<Button
variant="primary"
on:click={run.bind(null, dependency_index)}
style={{ full_width: true }}
>
<Button variant="primary" on:click={run.bind(null, dependency_index)}>
Try It Out
</Button>

View File

@ -6,7 +6,6 @@
import type { LoadingStatus } from "../StatusTracker/types";
import { FileData, normalise_file } from "@gradio/upload";
import type { SelectData } from "@gradio/utils";
import type { Styles } from "@gradio/utils";
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
@ -17,11 +16,15 @@
export let label: string = "Annotated Image";
export let show_label: boolean = true;
export let show_legend: boolean = true;
export let style: Styles = {};
export let height: number | undefined;
export let width: number | undefined;
export let color_map: Record<string, string>;
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let root: string;
export let root_url: string;
let active: string | null = null;
export let loading_status: LoadingStatus;
const dispatch = createEventDispatcher<{
@ -59,24 +62,25 @@
{elem_id}
{elem_classes}
padding={false}
style={{
height: style.height,
width: style.width
}}
{height}
{width}
allow_overflow={false}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />
<BlockLabel {show_label} Icon={Image} label={label || "Image"} />
<div class="container">
{#if _value == null}
<Empty size="large" unpadded_box={true}><Image /></Empty>
<Empty unpadded_box={true}><Image /></Empty>
{:else}
<div class="image-container">
<!-- svelte-ignore a11y-missing-attribute -->
<img
class="base-image"
class:fit-height={style.height}
class:fit-height={height}
src={_value ? _value[0].data : null}
/>
{#each _value ? _value[1] : [] as [file, label], i}
@ -86,7 +90,7 @@
class:active={active == label}
class:inactive={active != label && active != null}
src={file.data}
style={style.color_map && label in style.color_map
style={color_map && label in color_map
? null
: `filter: hue-rotate(${Math.round(
(i * 360) / _value[1].length
@ -100,9 +104,8 @@
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="legend-item"
style="background-color: {style.color_map &&
label in style.color_map
? style.color_map[label] + '88'
style="background-color: {color_map && label in color_map
? color_map[label] + '88'
: `hsla(${Math.round(
(i * 360) / _value[1].length
)}, 100%, 50%, 0.3)`}"

View File

@ -31,7 +31,9 @@
export let pending: boolean;
export let streaming: boolean;
export let root_url: null | string;
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
let _value: null | FileData;
@ -49,6 +51,9 @@
{elem_id}
{elem_classes}
{visible}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />

View File

@ -1,22 +1,25 @@
<script lang="ts">
import type { Styles } from "@gradio/utils";
import { Button } from "@gradio/button";
import { _ } from "svelte-i18n";
export let style: Styles = {};
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let value: string;
export let variant: "primary" | "secondary" | "stop" = "secondary";
export let mode: "static" | "dynamic" = "dynamic";
export let size: "sm" | "lg" = "lg";
export let scale: number = 1;
export let min_width: number | undefined = undefined;
</script>
<Button
{variant}
{elem_id}
{elem_classes}
{style}
{size}
{scale}
{min_width}
{visible}
disabled={mode === "static"}
on:click

View File

@ -2,7 +2,6 @@
import { ChatBot } from "@gradio/chatbot";
import { Block, BlockLabel } from "@gradio/atoms";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
import type { ThemeMode } from "js/app/src/components/types";
import { Chat } from "@gradio/icons";
import type { FileData } from "@gradio/upload";
@ -16,7 +15,9 @@
[string | FileData | null, string | FileData | null]
> = [];
let _value: Array<[string | FileData | null, string | FileData | null]>;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let label: string;
export let show_label: boolean = true;
export let root: string;
@ -38,9 +39,20 @@
])
: [];
export let loading_status: LoadingStatus | undefined = undefined;
export let height: number = 480;
</script>
<Block {elem_id} {elem_classes} {visible} padding={false}>
<Block
{elem_id}
{elem_classes}
{visible}
padding={false}
{container}
{scale}
{min_width}
{height}
allow_overflow={false}
>
{#if loading_status}
<StatusTracker
{...loading_status}
@ -55,11 +67,10 @@
Icon={Chat}
float={false}
label={label || "Chatbot"}
disable={typeof style.container === "boolean" && !style.container}
disable={container === false}
/>
{/if}
<ChatBot
{style}
{selectable}
{theme_mode}
value={_value}

View File

@ -3,7 +3,6 @@
import { Block, Info } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
@ -13,16 +12,13 @@
export let label: string = "Checkbox";
export let info: string | undefined = undefined;
export let mode: "static" | "dynamic";
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
</script>
<Block
{visible}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
>
<Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}>
<StatusTracker {...loading_status} />
{#if info}

View File

@ -3,7 +3,6 @@
import { Block } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
@ -11,7 +10,9 @@
export let value: Array<string> = [];
export let value_is_output: boolean = false;
export let choices: Array<string>;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let mode: "static" | "dynamic";
export let label: string = "Checkbox Group";
export let info: string | undefined = undefined;
@ -25,7 +26,9 @@
{elem_id}
{elem_classes}
type="fieldset"
disable={typeof style.container === "boolean" && !style.container}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />
@ -35,7 +38,6 @@
{choices}
{label}
{info}
{style}
{show_label}
on:select
on:change

View File

@ -5,7 +5,6 @@
import { Block } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let label: string = "ColorPicker";
export let info: string | undefined = undefined;
@ -15,20 +14,14 @@
export let value: string;
export let value_is_output: boolean = false;
export let show_label: boolean;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
export let mode: "static" | "dynamic";
</script>
<Block
{visible}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
>
<Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}>
<StatusTracker {...loading_status} />
<ColorPicker

View File

@ -1,24 +1,22 @@
<script lang="ts">
import { create_classes } from "@gradio/utils";
import type { Styles } from "@gradio/utils";
export let scale: number = 1;
export let gap: boolean = true;
export let min_width: number = 0;
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let variant: "default" | "panel" | "compact" = "default";
export let style: Styles = {};
</script>
<div
id={elem_id}
class={elem_classes.join(" ")}
class:gap={style.gap !== false}
class:gap
class:compact={variant === "compact"}
class:panel={variant === "panel"}
class:hide={!visible}
style={`min-width: min(${min_width}px, 100%); flex-grow: ${scale}`}
style:flex-grow={scale}
style:min-width="calc(min({min_width}px, 100%))"
>
<slot />
</div>

View File

@ -1,4 +1,5 @@
<script lang="ts">
import { Block } from "@gradio/atoms";
import { Table } from "@gradio/table";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
@ -24,6 +25,8 @@
export let label: string | null = null;
export let wrap: boolean;
export let datatype: Datatype | Array<Datatype>;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
const dispatch = createEventDispatcher();
@ -46,7 +49,16 @@
}
</script>
<div id={elem_id} class={elem_classes.join(" ")} class:hide={!visible}>
<Block
{visible}
padding={false}
{elem_id}
{elem_classes}
container={false}
{scale}
{min_width}
allow_overflow={false}
>
<StatusTracker {...loading_status} />
<Table
{label}
@ -62,15 +74,4 @@
{wrap}
{datatype}
/>
</div>
<style>
div {
position: relative;
overflow: hidden;
}
.hide {
display: none;
}
</style>
</Block>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { hover } from "@testing-library/user-event/dist/hover";
import { Block } from "@gradio/atoms";
import { createEventDispatcher } from "svelte";
import type { SvelteComponentDev, ComponentType } from "svelte/internal";
import { component_map } from "./directory";
@ -16,6 +16,8 @@
export let root: string;
export let root_url: null | string;
export let samples_per_page: number = 10;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
const dispatch = createEventDispatcher<{
click: number;
@ -78,7 +80,15 @@
);
</script>
<div id={elem_id} class="wrap {elem_classes.join(' ')}" class:hide={!visible}>
<Block
{visible}
padding={false}
{elem_id}
{elem_classes}
{scale}
{min_width}
allow_overflow={false}
>
<div class="label">
<svg
xmlns="http://www.w3.org/2000/svg"
@ -183,7 +193,7 @@
{/each}
</div>
{/if}
</div>
</Block>
<style>
.wrap {

View File

@ -3,7 +3,6 @@
import { Block } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let label: string = "Dropdown";
export let info: string | undefined = undefined;
@ -16,7 +15,9 @@
export let max_choices: number;
export let choices: Array<string>;
export let show_label: boolean;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
export let allow_custom_value: boolean = false;
@ -29,12 +30,7 @@
}
</script>
<Block
{visible}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
>
<Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}>
<StatusTracker {...loading_status} />
<Dropdown

View File

@ -26,8 +26,10 @@
export let file_types: Array<string> = ["file"];
export let root_url: null | string;
export let selectable: boolean = false;
export let loading_status: LoadingStatus;
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
$: _value = normalise_file(value, root, root_url);
@ -98,6 +100,9 @@
padding={false}
{elem_id}
{elem_classes}
{container}
{scale}
{min_width}
>
<StatusTracker
{...loading_status}

View File

@ -1,8 +1,15 @@
<script lang="ts">
export let visible = true;
export let scale: number = 1;
export let min_width: number = 0;
</script>
<div class="form" class:hidden={!visible}>
<div
class="form"
class:hidden={!visible}
style:flex-grow={scale}
style:min-width={`calc(min(${min_width}px, 100%))`}
>
<slot />
</div>

View File

@ -3,7 +3,6 @@
import { Gallery } from "@gradio/gallery";
import type { LoadingStatus } from "../StatusTracker/types";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { Styles } from "@gradio/utils";
import type { FileData } from "@gradio/upload";
export let loading_status: LoadingStatus;
@ -15,7 +14,15 @@
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let value: Array<string> | Array<FileData> | null = null;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let grid_cols: number | Array<number> | undefined = [2];
export let grid_rows: number | Array<number> | undefined = undefined;
export let height: number | "auto" = "auto";
export let preview: boolean;
export let object_fit: "contain" | "cover" | "fill" | "none" | "scale-down" =
"cover";
</script>
<Block
@ -24,8 +31,23 @@
padding={false}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
{container}
{scale}
{min_width}
height={typeof height === "number" ? height : undefined}
>
<StatusTracker {...loading_status} />
<Gallery on:select {label} {value} {style} {show_label} {root} {root_url} />
<Gallery
on:select
{label}
{value}
{show_label}
{root}
{root_url}
{grid_cols}
{grid_rows}
{height}
{preview}
{object_fit}
/>
</Block>

View File

@ -17,7 +17,7 @@
$: label, dispatch("change");
</script>
<Block {visible} {elem_id} {elem_classes} disable={true}>
<Block {visible} {elem_id} {elem_classes} container={false}>
<StatusTracker {...loading_status} variant="center" />
<div class:pending={loading_status?.status === "pending"}>
<HTML

View File

@ -5,7 +5,6 @@
import { TextHighlight } from "@gradio/icons";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
@ -15,11 +14,13 @@
export let show_legend: boolean;
export let color_map: Record<string, string> = {};
export let label: string = "Highlighted Text";
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let selectable: boolean = false;
$: if (!style.color_map && Object.keys(color_map).length) {
style.color_map = color_map;
$: if (!color_map && Object.keys(color_map).length) {
color_map = color_map;
}
export let loading_status: LoadingStatus;
@ -40,7 +41,9 @@
{elem_id}
{elem_classes}
padding={false}
disable={typeof style.container === "boolean" && !style.container}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />
{#if label}
@ -48,18 +51,12 @@
Icon={TextHighlight}
{label}
float={false}
disable={typeof style.container === "boolean" && !style.container}
disable={container === false}
/>
{/if}
{#if value}
<HighlightedText
on:select
{selectable}
{value}
{show_legend}
color_map={style.color_map}
/>
<HighlightedText on:select {selectable} {value} {show_legend} {color_map} />
{:else}
<Empty>
<TextHighlight />

View File

@ -5,7 +5,6 @@
import { _ } from "svelte-i18n";
import { Component as StatusTracker } from "../StatusTracker/";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
import UploadText from "../UploadText.svelte";
export let elem_id: string = "";
@ -18,14 +17,16 @@
export let show_label: boolean;
export let streaming: boolean;
export let pending: boolean;
export let style: Styles = {};
export let height: number | undefined;
export let width: number | undefined;
export let mirror_webcam: boolean;
export let shape: [number, number];
export let brush_radius: number;
export let selectable: boolean = false;
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
export let mode: "static" | "dynamic";
const dispatch = createEventDispatcher<{
@ -48,13 +49,13 @@
padding={false}
{elem_id}
{elem_classes}
style={{
height:
style.height ||
(source === "webcam" || mode === "static" ? undefined : FIXED_HEIGHT),
width: style.width
}}
height={height ||
(source === "webcam" || mode === "static" ? undefined : FIXED_HEIGHT)}
{width}
allow_overflow={false}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />
{#if mode === "static"}

View File

@ -6,7 +6,6 @@
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
import { _ } from "svelte-i18n";
export let elem_id: string = "";
@ -17,7 +16,9 @@
export let loading_status: LoadingStatus;
export let label: string;
export let show_label: boolean;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
const dispatch = createEventDispatcher<{ change: undefined }>();
@ -34,7 +35,9 @@
test_id="json"
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
{container}
{scale}
{min_width}
padding={false}
>
{#if label}
@ -43,7 +46,7 @@
{show_label}
{label}
float={false}
disable={typeof style.container === "boolean" && !style.container}
disable={container === false}
/>
{/if}

View File

@ -5,7 +5,6 @@
import { Block, BlockLabel, Empty } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
@ -16,8 +15,9 @@
confidences?: Array<{ label: string; confidence: number }>;
} = {};
export let label: string = "Label";
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
export let show_label: boolean;
export let selectable: boolean = false;
@ -33,15 +33,13 @@
{visible}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />
{#if show_label}
<BlockLabel
Icon={LabelIcon}
{label}
disable={typeof style.container === "boolean" && !style.container}
/>
<BlockLabel Icon={LabelIcon} {label} disable={container === false} />
{/if}
{#if _label !== undefined && _label !== null}
<Label on:select {selectable} {value} {show_label} {color} />

View File

@ -17,7 +17,7 @@
$: label, dispatch("change");
</script>
<Block {visible} {elem_id} {elem_classes} disable={true}>
<Block {visible} {elem_id} {elem_classes} container={false}>
<StatusTracker {...loading_status} variant="center" />
<div class:pending={loading_status?.status === "pending"}>
<Markdown

View File

@ -18,10 +18,12 @@
export let root: string;
export let root_url: null | string;
export let clearColor: Array<number>;
export let loading_status: LoadingStatus;
export let label: string;
export let show_label: boolean;
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
let _value: null | FileData;
$: _value = normalise_file(value, root, root_url);
@ -36,6 +38,9 @@
padding={false}
{elem_id}
{elem_classes}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />
@ -60,6 +65,6 @@
<BlockLabel {show_label} Icon={File} label={label || "3D Model"} />
<Empty size="large" unpadded_box={true}><File /></Empty>
<Empty unpadded_box={true}><File /></Empty>
{/if}
</Block>

View File

@ -3,14 +3,15 @@
import { Block } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let label: string = "Number";
export let info: string | undefined = undefined;
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let value: number = 0;
export let show_label: boolean;
@ -19,12 +20,7 @@
export let value_is_output: boolean = false;
</script>
<Block
{visible}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
>
<Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}>
<StatusTracker {...loading_status} />
<Number

View File

@ -7,19 +7,19 @@
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import { _ } from "svelte-i18n";
import type { Styles } from "@gradio/utils";
import type { ThemeMode } from "js/app/src/components/types";
export let value: null | string = null;
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let loading_status: LoadingStatus;
export let label: string;
export let show_label: boolean;
export let target: HTMLElement;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let theme_mode: ThemeMode;
export let caption: string;
export let bokeh_version: string | null;
@ -30,11 +30,11 @@
{elem_id}
{elem_classes}
{visible}
disable={typeof style.container === "boolean" && !style.container}
{container}
{scale}
{min_width}
>
<BlockLabel {show_label} label={label || "Plot"} Icon={PlotIcon} />
<StatusTracker {...loading_status} />
<Plot {value} {target} {theme_mode} {caption} {bokeh_version} on:change />
</Block>

View File

@ -3,7 +3,6 @@
import { Block } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let label: string = "Radio";
export let info: string | undefined = undefined;
@ -15,7 +14,9 @@
export let choices: Array<string> = [];
export let mode: "static" | "dynamic";
export let show_label: boolean;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
</script>
@ -24,7 +25,9 @@
type="fieldset"
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
{container}
{scale}
{min_width}
>
<StatusTracker {...loading_status} />
@ -36,7 +39,6 @@
{elem_id}
{show_label}
{choices}
{style}
disabled={mode === "static"}
on:change
on:input

View File

@ -1,7 +1,5 @@
<script lang="ts">
import type { Styles } from "@gradio/utils";
export let style: Styles = {};
export let equal_height: boolean = true;
export let elem_id: string;
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
@ -11,8 +9,8 @@
<div
class:compact={variant === "compact"}
class:panel={variant === "panel"}
class:unequal-height={style.equal_height === false}
class:stretch={style.equal_height}
class:unequal-height={equal_height === false}
class:stretch={equal_height}
class:hide={!visible}
id={elem_id}
class={elem_classes.join(" ")}

View File

@ -3,7 +3,6 @@
import { Block } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
@ -11,7 +10,9 @@
export let value: number = 0;
export let label: string = "Slider";
export let info: string | undefined = undefined;
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let minimum: number;
export let maximum: number;
export let step: number;
@ -22,12 +23,7 @@
export let value_is_output: boolean = false;
</script>
<Block
{visible}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
>
<Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}>
<StatusTracker {...loading_status} />
<Range

View File

@ -5,7 +5,6 @@
import { Block } from "@gradio/atoms";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
export let label: string = "Textbox";
export let info: string | undefined = undefined;
@ -18,18 +17,16 @@
export let show_label: boolean;
export let max_lines: number | false;
export let type: "text" | "password" | "email" = "text";
export let style: Styles = {};
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let show_copy_button: boolean = false;
export let loading_status: LoadingStatus | undefined = undefined;
export let mode: "static" | "dynamic";
export let value_is_output: boolean = false;
</script>
<Block
{visible}
{elem_id}
{elem_classes}
disable={typeof style.container === "boolean" && !style.container}
>
<Block {visible} {elem_id} {elem_classes} {scale} {min_width} {container}>
{#if loading_status}
<StatusTracker {...loading_status} />
{/if}
@ -44,7 +41,7 @@
{type}
max_lines={!max_lines && mode === "static" ? lines + 1 : max_lines}
{placeholder}
{style}
{show_copy_button}
on:change
on:input
on:submit

View File

@ -42,7 +42,9 @@
export let label: string;
export let show_label: boolean;
export let colors: Array<string>;
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let loading_status: LoadingStatus;
let _value: string | null;
@ -142,6 +144,9 @@
padding={false}
{elem_id}
{elem_classes}
{container}
{scale}
{min_width}
>
<BlockLabel {show_label} Icon={ChartIcon} label={label || "TimeSeries"} />
<StatusTracker {...loading_status} />
@ -150,7 +155,7 @@
{#if static_data}
<Chart value={static_data} {colors} />
{:else}
<Empty size="large" unpadded_box={true}>
<Empty unpadded_box={true}>
<ChartIcon />
</Empty>
{/if}

View File

@ -1,13 +1,11 @@
<script lang="ts">
import { createEventDispatcher, tick } from "svelte";
import type { Styles } from "@gradio/utils";
import type { FileData } from "@gradio/upload";
import { UploadButton } from "@gradio/upload-button";
import { upload_files } from "@gradio/client";
import { blobToBase64 } from "@gradio/upload";
import { _ } from "svelte-i18n";
export let style: Styles = {};
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
@ -16,6 +14,9 @@
export let file_count: string;
export let file_types: Array<string> = ["file"];
export let root: string;
export let size: "sm" | "lg" = "lg";
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let mode: "static" | "dynamic" = "dynamic";
export let variant: "primary" | "secondary" | "stop" = "secondary";
@ -57,10 +58,12 @@
<UploadButton
{elem_id}
{elem_classes}
{style}
{visible}
{file_count}
{file_types}
{size}
{scale}
{min_width}
{mode}
{variant}
on:click

View File

@ -8,7 +8,6 @@
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import type { Styles } from "@gradio/utils";
import { _ } from "svelte-i18n";
export let elem_id: string = "";
@ -23,12 +22,14 @@
export let root_url: null | string;
export let show_label: boolean;
export let loading_status: LoadingStatus;
export let style: Styles = {};
export let height: number | undefined;
export let width: number | undefined;
export let mirror_webcam: boolean;
export let include_audio: boolean;
export let container: boolean = false;
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let mode: "static" | "dynamic";
let _video: FileData | null = null;
let _subtitle: FileData | null = null;
@ -75,7 +76,11 @@
padding={false}
{elem_id}
{elem_classes}
style={{ height: style.height, width: style.width }}
{height}
{width}
{container}
{scale}
{min_width}
allow_overflow={false}
>
<StatusTracker {...loading_status} />

View File

@ -1,10 +1,7 @@
<script lang="ts">
import { get_styles } from "../../utils";
import type { Styles } from "@gradio/utils";
import { getContext } from "svelte";
export let style: Styles = {};
export let container: boolean = true;
export let height: number | undefined = undefined;
export let width: number | undefined = undefined;
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let variant: "solid" | "dashed" | "none" = "solid";
@ -12,26 +9,13 @@
export let padding: boolean = true;
export let type: "normal" | "fieldset" = "normal";
export let test_id: string | undefined = undefined;
export let disable: boolean = false;
export let explicit_call: boolean = false;
export let visible = true;
export let allow_overflow = true;
export let scale: number | null = null;
export let min_width: number = 0;
let tag = type === "fieldset" ? "fieldset" : "div";
const parent = getContext<string | null>("BLOCK_KEY");
$: _parent = parent === "column" || parent == "row" ? parent : "column";
$: ({ styles } = explicit_call
? get_styles(style, [])
: disable
? get_styles({ container: false }, ["container"])
: { styles: "" });
$: size_style =
"" +
(typeof style.height === "number" ? `height: ${style.height}px; ` : "") +
(typeof style.width === "number" ? `width: ${style.width}px;` : "");
</script>
<svelte:element
@ -42,9 +26,15 @@
class="block {elem_classes.join(' ')}"
class:padded={padding}
class:border_focus={border_mode === "focus"}
style="{styles} {size_style || null}"
class:hide-container={!explicit_call && !container}
style:height={typeof height === "number" ? height + "px" : undefined}
style:width={typeof width === "number"
? `calc(min(${width}px, 100%))`
: undefined}
style:border-style={variant}
style:overflow={allow_overflow ? "visible" : "hidden"}
style:flex-grow={scale}
style:min-width={`calc(min(${min_width}px, 100%))`}
>
<slot />
</svelte:element>
@ -73,4 +63,12 @@
.hidden {
display: none;
}
.hide-container {
margin: 0;
box-shadow: none;
border-width: 0;
background: transparent;
padding: 0;
overflow: visible;
}
</style>

View File

@ -1,22 +1,16 @@
<script lang="ts">
import { get_styles } from "@gradio/utils";
export let label: string | null = null;
export let Icon: any;
export let show_label: boolean = true;
export let disable: boolean = false;
export let float: boolean = true;
$: ({ styles } = get_styles({ label_container: !disable }, [
"label_container"
]));
</script>
<div
class:hide={!show_label}
class:sr-only={!show_label}
class:float
style={styles}
class:hide-label={disable}
>
<span>
<Icon />
@ -64,4 +58,10 @@
width: calc(var(--block-label-text-size) - 1px);
height: calc(var(--block-label-text-size) - 1px);
}
.hide-label {
box-shadow: none;
border-width: 0;
background: transparent;
overflow: visible;
}
</style>

View File

@ -1,14 +1,8 @@
<script lang="ts">
export let size: "small" | "large" = "small";
export let unpadded_box = false;
</script>
<div
class="empty"
class:small={size === "small"}
class:large={size === "large"}
class:unpadded_box
>
<div class="empty" class:unpadded_box>
<div class="icon">
<slot />
</div>
@ -28,14 +22,6 @@
color: var(--body-text-color);
}
.small {
height: calc(var(--size-32) - 20px);
}
.large {
height: calc(var(--size-64) - 20px);
}
.unpadded_box.small {
min-height: var(--size-32);
}

View File

@ -34,7 +34,7 @@
<BlockLabel {show_label} Icon={Music} float={false} label={label || "Audio"} />
{#if value === null}
<Empty size="small" unpadded_box={true}>
<Empty unpadded_box={true}>
<Music />
</Empty>
{:else}

View File

@ -1,23 +1,22 @@
<script lang="ts">
import { get_styles } from "../../utils";
import type { Styles } from "@gradio/utils";
export let style: Styles = {};
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let variant: "primary" | "secondary" | "stop" = "secondary";
export let size: "sm" | "lg" = style.size || "lg";
export let size: "sm" | "lg" = "lg";
export let disabled: boolean = false;
$: ({ styles } = get_styles(style, ["full_width"]));
export let scale: number = 1;
export let min_width: number | undefined = undefined;
</script>
<button
on:click
class:hide={!visible}
class="{size} {variant} {elem_classes.join(' ')}"
style={styles}
style:flex-grow={scale}
style:min-width={typeof min_width === "number"
? `calc(min(${min_width}px, 100%))`
: null}
id={elem_id}
{disabled}
>

View File

@ -4,7 +4,7 @@
import DOMPurify from "dompurify";
import render_math_in_element from "katex/dist/contrib/auto-render.js";
import { beforeUpdate, afterUpdate, createEventDispatcher } from "svelte";
import type { Styles, SelectData } from "@gradio/utils";
import type { SelectData } from "@gradio/utils";
import type { ThemeMode } from "js/app/src/components/types";
import type { FileData } from "@gradio/upload";
@ -21,7 +21,6 @@
> | null = null;
export let pending_message: boolean = false;
export let feedback: Array<string> | null = null;
export let style: Styles = {};
export let selectable: boolean = false;
export let theme_mode: ThemeMode;
@ -82,12 +81,7 @@
}
</script>
<div
class="wrap"
style:height={`${style.height}px`}
style:max-height={`${style.height}px`}
bind:this={div}
>
<div class="wrap" style:max-height="100%" bind:this={div}>
<div class="message-wrap" use:copy>
{#if value !== null}
{#each value as message_pair, i}
@ -154,8 +148,6 @@
<style>
.wrap {
padding: var(--block-padding);
height: 100%;
max-height: 480px;
overflow-y: auto;
}

View File

@ -50,7 +50,7 @@
<BlockLabel Icon={CodeIcon} {show_label} {label} float={false} />
{#if !value}
<Empty size="large" unpadded_box={true}>
<Empty unpadded_box={true}>
<CodeIcon />
</Empty>
{:else}

View File

@ -20,5 +20,5 @@
{#if value}
<FilePreview {selectable} on:select {value} />
{:else}
<Empty size="large" unpadded_box={true}><File /></Empty>
<Empty unpadded_box={true}><File /></Empty>
{/if}

View File

@ -1,13 +1,11 @@
<script lang="ts">
import { createEventDispatcher, afterUpdate } from "svelte";
import { BlockTitle } from "@gradio/atoms";
import { get_styles } from "@gradio/utils";
import type { Styles, SelectData } from "@gradio/utils";
import type { SelectData } from "@gradio/utils";
export let value: Array<string> = [];
let old_value: Array<string> = value.slice();
export let value_is_output: boolean = false;
export let style: Styles = {};
export let choices: Array<string>;
export let disabled: boolean = false;
export let label: string;
@ -44,19 +42,13 @@
handle_change();
}
}
$: ({ item_container } = get_styles(style, ["item_container"]));
</script>
<BlockTitle {show_label} {info}>{label}</BlockTitle>
<div class="wrap" data-testid="checkbox-group">
{#each choices as choice}
<label
class:disabled
class:selected={value.includes(choice)}
style={item_container}
>
<label class:disabled class:selected={value.includes(choice)}>
<input
{disabled}
on:change={() => toggleChoice(choice)}

View File

@ -1,12 +1,10 @@
<script lang="ts">
import { createEventDispatcher, afterUpdate } from "svelte";
import { BlockTitle } from "@gradio/atoms";
import { get_styles } from "@gradio/utils";
import type { Styles, SelectData } from "@gradio/utils";
import type { SelectData } from "@gradio/utils";
export let value: string | null;
export let value_is_output: boolean = false;
export let style: Styles = {};
export let choices: Array<string>;
export let disabled: boolean = false;
export let label: string;
@ -30,19 +28,13 @@
value_is_output = false;
});
$: value, handle_change();
$: ({ item_container } = get_styles(style, ["item_container"]));
</script>
<BlockTitle {show_label} {info}>{label}</BlockTitle>
<div class="wrap">
{#each choices as choice, i (i)}
<label
class:disabled
class:selected={value === choice}
style={item_container}
>
<label class:disabled class:selected={value === choice}>
<input
{disabled}
bind:group={value}

View File

@ -3,7 +3,6 @@
import { BlockTitle } from "@gradio/atoms";
import { Copy, Check } from "@gradio/icons";
import { fade } from "svelte/transition";
import type { Styles } from "@gradio/utils";
import type { SelectData } from "@gradio/utils";
export let value: string = "";
@ -16,7 +15,7 @@
export let show_label: boolean = true;
export let max_lines: number | false;
export let type: "text" | "password" | "email" = "text";
export let style: Styles = {};
export let show_copy_button: boolean = false;
let el: HTMLTextAreaElement | HTMLInputElement;
let copied = false;
@ -181,7 +180,7 @@
/>
{/if}
{:else}
{#if show_label && style.show_copy_button}
{#if show_label && show_copy_button}
{#if copied}
<button in:fade={{ duration: 300 }}><Check /></button>
{:else}

View File

@ -5,22 +5,22 @@
import { createEventDispatcher } from "svelte";
import { tick } from "svelte";
import type { Styles } from "@gradio/utils";
import { get_styles } from "@gradio/utils";
import { Image } from "@gradio/icons";
import type { FileData } from "@gradio/upload";
import { normalise_file } from "@gradio/upload";
export let container: boolean = true;
export let show_label: boolean = true;
export let label: string;
export let root: string = "";
export let root_url: null | string = null;
export let value: Array<string> | Array<FileData> | null = null;
export let style: Styles = {
grid_cols: [2],
object_fit: "cover",
height: "auto"
};
export let grid_cols: number | Array<number> | undefined = [2];
export let grid_rows: number | Array<number> | undefined = undefined;
export let height: number | "auto" = "auto";
export let preview: boolean;
export let object_fit: "contain" | "cover" | "fill" | "none" | "scale-down" =
"cover";
const dispatch = createEventDispatcher<{
select: SelectData;
@ -41,14 +41,14 @@
);
let prevValue: string[] | FileData[] | null = value;
let selected_image: number | null = null;
let old_selected_image: number | null = null;
let selected_image = preview && value?.length ? 0 : null;
let old_selected_image: number | null = selected_image;
$: if (prevValue !== value) {
// When value is falsy (clear button or first load),
// style.preview determines the selected image
// preview determines the selected image
if (was_reset) {
selected_image = style.preview && value?.length ? 0 : null;
selected_image = preview && value?.length ? 0 : null;
was_reset = false;
// Otherwise we keep the selected_image the same if the
// gallery has at least as many elements as it did before
@ -101,7 +101,7 @@
$: scroll_to_img(selected_image);
let el: Array<HTMLButtonElement> = [];
let container: HTMLDivElement;
let container_element: HTMLDivElement;
async function scroll_to_img(index: number | null) {
if (typeof index !== "number") return;
@ -110,31 +110,56 @@
el[index].focus();
const { left: container_left, width: container_width } =
container.getBoundingClientRect();
container_element.getBoundingClientRect();
const { left, width } = el[index].getBoundingClientRect();
const relative_left = left - container_left;
const pos =
relative_left + width / 2 - container_width / 2 + container.scrollLeft;
relative_left +
width / 2 -
container_width / 2 +
container_element.scrollLeft;
container.scrollTo({
container_element.scrollTo({
left: pos < 0 ? 0 : pos,
behavior: "smooth"
});
}
$: can_zoom = window_height >= height;
$: can_zoom = window_height >= client_height;
function add_height_to_styles(style: Styles): string {
styles = get_styles(style, ["grid_cols", "grid_rows", "object_fit"]).styles;
return styles + ` height: ${style.height}`;
}
$: styles = add_height_to_styles(style);
let height = 0;
let client_height = 0;
let window_height = 0;
let grid_cols_style = "";
let grid_rows_style = "";
$: {
let grid_cols_map = ["", "sm-", "md-", "lg-", "xl-", "2xl-"];
let _grid_cols = Array.isArray(grid_cols) ? grid_cols : [grid_cols];
grid_cols_style = [0, 0, 0, 0, 0, 0]
.map(
(_, i) =>
`--${grid_cols_map[i]}grid-cols: var(--grid-${
_grid_cols?.[i] || _grid_cols?.[_grid_cols?.length - 1]
});`
)
.join(" ");
}
$: {
let grid_rows_map = ["", "sm-", "md-", "lg-", "xl-", "2xl-"];
let _grid_rows = Array.isArray(grid_rows) ? grid_rows : [grid_rows];
grid_rows_style = [0, 0, 0, 0, 0, 0]
.map(
(_, i) =>
`--${grid_rows_map[i]}grid-rows: var(--grid-${
_grid_rows?.[i] || _grid_rows?.[_grid_rows?.length - 1]
});`
)
.join(" ");
}
</script>
<svelte:window bind:innerHeight={window_height} />
@ -144,17 +169,17 @@
{show_label}
Icon={Image}
label={label || "Gallery"}
disable={typeof style.container === "boolean" && !style.container}
disable={container === false}
/>
{/if}
{#if value === null || _value === null || _value.length === 0}
<Empty size="large" unpadded_box={true}><Image /></Empty>
<Empty unpadded_box={true}><Image /></Empty>
{:else}
{#if selected_image !== null}
<div
on:keydown={on_keydown}
class="preview"
class:fixed-height={style.height !== "auto"}
class:fixed-height={height !== "auto"}
>
<ModifyUpload on:clear={() => (selected_image = null)} />
@ -173,7 +198,7 @@
{_value[selected_image][1]}
</div>
{/if}
<div bind:this={container} class="thumbnails scroll-hide">
<div bind:this={container_element} class="thumbnails scroll-hide">
{#each _value as image, i}
<button
bind:this={el[i]}
@ -193,11 +218,16 @@
{/if}
<div
bind:clientHeight={height}
bind:clientHeight={client_height}
class="grid-wrap"
class:fixed-height={!style.height || style.height == "auto"}
class:fixed-height={!height || height == "auto"}
>
<div class="grid-container" style={styles} class:pt-6={show_label}>
<div
class="grid-container"
style="{grid_cols_style} {grid_rows_style}"
style:object_fit
class:pt-6={show_label}
>
{#each _value as [image, caption], i}
<button
class="thumbnail-item thumbnail-lg"

View File

@ -29,7 +29,7 @@
<BlockLabel {show_label} Icon={Image} label={label || "Image"} />
{#if value === null}
<Empty size="large" unpadded_box={true}><Image /></Empty>
<Empty unpadded_box={true}><Image /></Empty>
{:else}
<div class="download">
<a

View File

@ -207,7 +207,7 @@
<img src={plot} />
</div>
{:else}
<Empty size="large" unpadded_box={true}><PlotIcon /></Empty>
<Empty unpadded_box={true}><PlotIcon /></Empty>
{/if}
<style>

View File

@ -1,17 +1,17 @@
<script lang="ts">
import { Button } from "@gradio/button";
import type { Styles } from "@gradio/utils";
import { createEventDispatcher } from "svelte";
import type { FileData } from "@gradio/upload";
export let style: Styles = {};
export let elem_id: string = "";
export let elem_classes: Array<string> = [];
export let visible: boolean = true;
export let size: "sm" | "lg" = style.size || "lg";
export let file_count: string;
export let file_types: Array<string> = ["file"];
export let include_file_metadata = true;
export let size: "sm" | "lg" = "lg";
export let scale: number = 1;
export let min_width: number | undefined = undefined;
export let mode: "static" | "dynamic" = "dynamic";
export let variant: "primary" | "secondary" | "stop" = "secondary";
@ -97,7 +97,8 @@
{elem_classes}
{visible}
on:click={openFileUpload}
{style}
{scale}
{min_width}
disabled={mode === "static"}
>
<slot />

View File

@ -1,3 +1,2 @@
export * from "./color";
export * from "./styles";
export * from "./utils";

View File

@ -1,247 +0,0 @@
export interface Styles {
container?: boolean;
grid_cols?: number | Array<number>;
grid_rows?: number | Array<number>;
height?: "auto" | string | number;
width?: "auto" | string | number;
full_width?: boolean;
equal_height?: boolean;
visible?: boolean;
item_container?: boolean;
color_map?: Record<string, string>;
label_container?: boolean;
gap?: boolean;
size?: "sm" | "lg";
preview?: boolean;
object_fit?: "contain" | "cover" | "fill" | "none" | "scale-down";
show_copy_button?: boolean;
}
type PartialRecord<K extends keyof any, T> = {
[P in K]?: T;
};
type ProcessedStyles = PartialRecord<keyof Styles, string> & {
styles: string;
};
const get_style = <T extends keyof Styles>(styles: Styles, key: T) => {
//@ts-ignore
return style_handlers[key](styles[key]);
};
export function get_styles(
styles: Styles,
allowed_styles: Array<keyof Styles>
): ProcessedStyles {
const processed_styles = allowed_styles.reduce((acc, next) => {
if (styles[next] === undefined || !style_handlers[next]) acc[next] = " ";
else {
acc[next] = ` ${get_style(styles, next)} `;
}
return acc;
}, {} as ProcessedStyles);
processed_styles.styles = ` ${Object.values(processed_styles)
.join(" ")
.replace(/\s+/g, " ")
.trim()} `;
return processed_styles;
}
type StyleHandlers = {
[K in keyof Styles]: (style: Exclude<Styles[K], null | undefined>) => string;
};
const style_handlers: StyleHandlers = {
container(container_visible) {
return container_visible
? ""
: `padding: 0; margin: 0; border-width: 0; box-shadow: none; overflow: visible; background: transparent;`;
},
label_container(visible) {
return visible
? ""
: `border-width: 0; box-shadow: none; overflow: visible; background: transparent;`;
},
grid_cols(grid_cols) {
let grid_cols_map = ["", "sm-", "md-", "lg-", "xl-", "2xl-"];
let _grid_cols = Array.isArray(grid_cols) ? grid_cols : [grid_cols];
return [0, 0, 0, 0, 0, 0]
.map(
(_, i) =>
`--${grid_cols_map[i]}grid-cols: var(--grid-${
_grid_cols?.[i] || _grid_cols?.[_grid_cols?.length - 1]
});`
)
.join(" ");
},
grid_rows(grid_rows) {
let grid_rows_map = ["", "sm-", "md-", "lg-", "xl-", "2xl-"];
let _grid_rows = Array.isArray(grid_rows) ? grid_rows : [grid_rows];
return [0, 0, 0, 0, 0, 0]
.map(
(_, i) =>
`--${grid_rows_map[i]}grid-rows: var(--grid-${
_grid_rows?.[i] || _grid_rows?.[_grid_rows?.length - 1]
});`
)
.join(" ");
},
height(height) {
return height === "auto" ? "height: auto;" : "";
},
full_width(full_width) {
return full_width
? "width: var(--size-full); flex-grow: 1;"
: "flex-grow: 0; width: fit-content;";
},
equal_height(equal_height) {
return equal_height ? "align-items: stretch;" : "align-items: flex-start;";
},
visible(visible) {
return visible ? "" : "display:hidden;";
},
item_container(visible) {
return visible ? "" : "border-width:0;";
},
object_fit(object_fit) {
return `--object-fit: ${object_fit};`;
}
} as const;
export const create_classes = (
styles: Record<string, any>,
prefix: string = ""
): string => {
let classes: Array<string> = [];
let target_styles: Record<string, any> = {};
if (prefix === "") {
target_styles = styles;
} else {
for (const prop in styles) {
if (prop.startsWith(prefix + "_")) {
const propname = prop.substring(prop.indexOf("_") + 1);
target_styles[propname] = styles[prop];
}
}
}
if (target_styles.hasOwnProperty("margin")) {
if (!Array.isArray(target_styles.margin)) {
target_styles.margin = !!target_styles.margin
? [true, true, true, true]
: [false, false, false, false];
}
let margin_map = ["t", "r", "b", "l"];
(target_styles.margin as boolean[]).forEach((margin, i) => {
if (!margin) {
classes.push(`!m${margin_map[i]}-0`);
}
});
}
if (target_styles.hasOwnProperty("border")) {
if (!Array.isArray(target_styles.border)) {
target_styles.border = !!target_styles.border
? [true, true, true, true]
: [false, false, false, false];
}
let border_map = ["t", "r", "b", "l"];
(target_styles.border as boolean[]).forEach((border, i) => {
if (!border) {
classes.push(`!border-${border_map[i]}-0`);
}
});
}
switch (target_styles.rounded) {
case true:
classes.push("!rounded-lg");
break;
case false:
classes.push("!rounded-none");
break;
}
switch (target_styles.full_width) {
case true:
classes.push("w-full");
break;
case false:
classes.push("!grow-0");
break;
}
switch (target_styles.text_color) {
case "red":
classes.push("!text-red-500", "dark:text-red-100");
break;
case "yellow":
classes.push("!text-yellow-500", "dark:text-yellow-100");
break;
case "green":
classes.push("!text-green-500", "dark:text-green-100");
break;
case "blue":
classes.push("!text-blue-500", "dark:text-blue-100");
break;
case "purple":
classes.push("!text-purple-500", "dark:text-purple-100");
break;
case "black":
classes.push("!text-gray-700", "dark:text-gray-50");
break;
}
switch (target_styles.bg_color) {
case "red":
classes.push(
"!bg-red-100 !from-red-100 !to-red-200 !border-red-300",
"dark:!bg-red-700 dark:!from-red-700 dark:!to-red-800 dark:!border-red-900"
);
break;
case "yellow":
classes.push(
"!bg-yellow-100 !from-yellow-100 !to-yellow-200 !border-yellow-300",
"dark:!bg-yellow-700 dark:!from-yellow-700 dark:!to-yellow-800 dark:!border-yellow-900"
);
break;
case "green":
classes.push(
"!bg-green-100 !from-green-100 !to-green-200 !border-green-300",
"dark:!bg-green-700 dark:!from-green-700 dark:!to-green-800 dark:!border-green-900 !text-gray-800"
);
break;
case "blue":
classes.push(
"!bg-blue-100 !from-blue-100 !to-blue-200 !border-blue-300",
"dark:!bg-blue-700 dark:!from-blue-700 dark:!to-blue-800 dark:!border-blue-900"
);
break;
case "purple":
classes.push(
"!bg-purple-100 !from-purple-100 !to-purple-200 !border-purple-300",
"dark:!bg-purple-700 dark:!from-purple-700 dark:!to-purple-800 dark:!border-purple-900"
);
break;
case "black":
classes.push(
"!bg-gray-100 !from-gray-100 !to-gray-200 !border-gray-300",
"dark:!bg-gray-700 dark:!from-gray-700 dark:!to-gray-800 dark:!border-gray-900"
);
case "pink":
classes.push(
"!bg-pink-100 !from-pink-100 !to-pink-200 !border-pink-300",
"dark:!bg-pink-700 dark:!from-pink-700 dark:!to-pink-800 dark:!border-pink-900 !text-gray-800"
);
break;
}
return " " + classes.join(" ");
};

View File

@ -46,7 +46,7 @@
<BlockLabel {show_label} Icon={Video} label={label || "Video"} />
{#if value === null}
<Empty size="large" unpadded_box={true}><Video /></Empty>
<Empty unpadded_box={true}><Video /></Empty>
{:else}
<!-- svelte-ignore a11y-media-has-caption -->
{#key value.data}

View File

@ -1108,10 +1108,14 @@ class TestSpecificUpdate:
"placeholder": None,
"label": None,
"show_label": None,
"type": None,
"interactive": False,
"container": None,
"scale": None,
"min_width": None,
"visible": None,
"value": gr.components._Keywords.NO_VALUE,
"type": None,
"interactive": False,
"show_copy_button": None,
"__type__": "update",
}
@ -1124,10 +1128,14 @@ class TestSpecificUpdate:
"placeholder": None,
"label": None,
"show_label": None,
"type": None,
"interactive": True,
"container": None,
"scale": None,
"min_width": None,
"visible": None,
"value": gr.components._Keywords.NO_VALUE,
"type": None,
"interactive": True,
"show_copy_button": None,
"__type__": "update",
}
@ -1138,6 +1146,11 @@ class TestSpecificUpdate:
"value": "test.mp4",
"__type__": "generic_update",
"interactive": True,
"container": None,
"height": None,
"min_width": None,
"scale": None,
"width": None,
}
)
assert specific_update == {
@ -1147,6 +1160,11 @@ class TestSpecificUpdate:
"visible": True,
"value": "test.mp4",
"interactive": True,
"container": None,
"height": None,
"min_width": None,
"scale": None,
"width": None,
"__type__": "update",
}

View File

@ -87,10 +87,13 @@ class TestTextbox:
"placeholder": None,
"value": "",
"name": "textbox",
"show_copy_button": False,
"show_label": True,
"type": "text",
"label": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -207,7 +210,9 @@ class TestNumber:
"name": "number",
"show_label": True,
"label": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": "num",
"elem_classes": ["first"],
"visible": True,
@ -252,7 +257,9 @@ class TestNumber:
"name": "number",
"show_label": True,
"label": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -368,7 +375,9 @@ class TestSlider:
"name": "slider",
"show_label": True,
"label": "Slide Your Input",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -439,7 +448,9 @@ class TestCheckbox:
"name": "checkbox",
"show_label": True,
"label": "Check Your Input",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -483,7 +494,9 @@ class TestCheckboxGroup:
"name": "checkboxgroup",
"show_label": True,
"label": "Check Your Inputs",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -527,7 +540,9 @@ class TestRadio:
"name": "radio",
"show_label": True,
"label": "Pick Your One Input",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -581,7 +596,9 @@ class TestDropdown:
"name": "dropdown",
"show_label": True,
"label": "Select Your Inputs",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -640,7 +657,11 @@ class TestImage:
"streaming": False,
"show_label": True,
"label": "Upload Your Image",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"height": None,
"width": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -806,7 +827,9 @@ class TestAudio:
"streaming": False,
"show_label": True,
"label": "Upload Your Audio",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -838,7 +861,9 @@ class TestAudio:
"show_label": True,
"label": None,
"source": "upload",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -952,7 +977,9 @@ class TestFile:
"name": "file",
"show_label": True,
"label": "Upload Your File",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1066,7 +1093,9 @@ class TestDataframe:
"max_rows": 20,
"max_cols": None,
"overflow_row_behaviour": "paginate",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1089,7 +1118,9 @@ class TestDataframe:
"name": "dataframe",
"show_label": True,
"label": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1279,7 +1310,11 @@ class TestVideo:
"name": "video",
"show_label": True,
"label": "Upload Your Video",
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"height": None,
"width": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1436,7 +1471,9 @@ class TestTimeseries:
"show_label": True,
"label": "Upload Your Timeseries",
"colors": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1459,7 +1496,9 @@ class TestTimeseries:
"show_label": True,
"label": "Disease",
"colors": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1535,7 +1574,9 @@ class TestLabel:
"num_top_classes": 2,
"value": None,
"label": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1674,7 +1715,9 @@ class TestHighlightedText:
"show_label": True,
"label": None,
"show_legend": False,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1748,7 +1791,12 @@ class TestAnnotatedImage:
"show_label": True,
"label": "sections",
"show_legend": False,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"color_map": None,
"height": None,
"width": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1852,7 +1900,10 @@ class TestChatbot:
"visible": True,
"elem_id": None,
"elem_classes": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"height": None,
"root_url": None,
"selectable": False,
}
@ -1866,7 +1917,9 @@ class TestJSON:
js_output = gr.JSON()
assert js_output.postprocess('{"a":1, "b": 2}'), '"{\\"a\\":1, \\"b\\": 2}"'
assert js_output.get_config() == {
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1921,7 +1974,9 @@ class TestHTML:
"""
html_component = gr.components.HTML("#Welcome onboard", label="HTML Input")
assert {
"style": {},
"container": True,
"min_width": None,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -1982,7 +2037,9 @@ class TestModel3D:
"visible": True,
"elem_id": None,
"elem_classes": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
} == component.get_config()
file = "test/test_files/Box.gltf"
@ -2018,7 +2075,9 @@ class TestColorPicker:
"value": None,
"show_label": True,
"label": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,
@ -2190,7 +2249,9 @@ class TestScatterPlot:
"name": "plot",
"root_url": None,
"show_label": True,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"value": None,
"visible": True,
"bokeh_version": "3.0.3",
@ -2375,7 +2436,9 @@ class TestLinePlot:
"name": "plot",
"root_url": None,
"show_label": True,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"value": None,
"visible": True,
"bokeh_version": "3.0.3",
@ -2539,7 +2602,9 @@ class TestBarPlot:
"name": "plot",
"root_url": None,
"show_label": True,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"value": None,
"visible": True,
"bokeh_version": "3.0.3",
@ -2710,7 +2775,9 @@ class TestCode:
"name": "code",
"show_label": True,
"label": None,
"style": {},
"container": True,
"min_width": 160,
"scale": None,
"elem_id": None,
"elem_classes": None,
"visible": True,