From 1916c79f2e05e6e182f29f2430a5906356c7fcaa Mon Sep 17 00:00:00 2001 From: Ali Abid Date: Thu, 30 Sep 2021 18:20:54 +0000 Subject: [PATCH] expand kitchen sink; add grass, peach themes. --- demo/kitchen_sink.py | 79 ++- frontend/src/components/output/carousel.jsx | 20 +- frontend/src/gradio.jsx | 11 +- frontend/src/index.jsx | 7 +- frontend/src/static/img/arrow-left.svg | 56 ++ frontend/src/static/img/arrow-right.svg | 56 ++ frontend/src/themes/defaults.scss | 47 +- .../src/themes/{compact.scss => grass.scss} | 184 +++--- frontend/src/themes/huggingface.scss | 16 +- frontend/src/themes/peach.scss | 532 ++++++++++++++++++ gradio/frontend/asset-manifest.json | 6 +- gradio/frontend/index.html | 2 +- gradio/inputs.py | 7 +- gradio/interface.py | 4 +- 14 files changed, 879 insertions(+), 148 deletions(-) create mode 100644 frontend/src/static/img/arrow-left.svg create mode 100644 frontend/src/static/img/arrow-right.svg rename frontend/src/themes/{compact.scss => grass.scss} (60%) create mode 100644 frontend/src/themes/peach.scss diff --git a/demo/kitchen_sink.py b/demo/kitchen_sink.py index c8ff619067..2cf5321e17 100755 --- a/demo/kitchen_sink.py +++ b/demo/kitchen_sink.py @@ -1,58 +1,77 @@ import gradio as gr import numpy as np -from typing import List - CHOICES = ["foo", "bar", "baz"] - -def generate_tone(note=0, octave=1, duration=3): - sr = 48000 - a4_freq, tones_from_a4 = 440, 12 * (octave - 4) + (note - 9) - frequency = a4_freq * 2 ** (tones_from_a4 / 12) - duration = int(duration) - audio = np.linspace(0, duration, duration * sr) - audio = (20000 * np.sin(audio * (2 * np.pi * frequency))).astype(np.int16) - return sr, audio - - -def fn( - *args, - **kwargs, -): +def fn(text1, text2, num, slider1, slider2, single_checkbox, + checkboxes, radio, dropdown, im1, im2, im3, im4, video, audio1, + audio2, file, df1, df2): return ( - "Sample output text", + (text1 if single_checkbox else text2) + + ", selected:" + ", ".join(checkboxes), # Text { - "positive": 0.287, - "negative": 0.517, - "neutral": 0.197, - }, - generate_tone(), - np.ones((300, 300, 3)), + "positive": num / (num + slider1 + slider2), + "negative": slider1 / (num + slider1 + slider2), + "neutral": slider2 / (num + slider1 + slider2), + }, # Label + (audio1[0], np.flipud(audio1[1])) if audio1 is not None else "audio/cantina.wav", # Audio + np.flipud(im1) if im1 is not None else "images/2.jpg", # Image + video, # Video + [("Height", 70), ("Weight", 150), ("BMI", "22"), (dropdown, 42)], # KeyValues + [("The", "art"), (" ", None), ("quick", "adj"), (" ", None), + ("brown", "adj"), (" ", None), ("fox", "noun")], # HighlightedText + {"name": "Jane", "age": 34, "children": checkboxes}, # JSON + "", # HTML + "files/titanic.csv", + np.ones((4, 3)), # Dataframe + [im for im in [im1, im2, im3, im4, "images/1.jpg"] if im is not None], # Carousel + df2 # Timeseries ) iface = gr.Interface( fn, inputs=[ - gr.inputs.Textbox(label="Textbox"), + gr.inputs.Textbox(default="Lorem ipsum", label="Textbox"), + gr.inputs.Textbox(lines=3, placeholder="Type here..", + label="Textbox 2"), gr.inputs.Number(label="Number", default=42), - gr.inputs.Slider(label="Slider"), + gr.inputs.Slider(minimum=10, maximum=20, default=15, + label="Slider: 10 - 20"), + gr.inputs.Slider(maximum=20, step=0.04, + label="Slider: step @ 0.04"), gr.inputs.Checkbox(label="Checkbox"), - gr.inputs.CheckboxGroup(label="CheckboxGroup", choices=CHOICES), - gr.inputs.Radio(label="Radio", choices=CHOICES), + gr.inputs.CheckboxGroup(label="CheckboxGroup", + choices=CHOICES, default=CHOICES[0:2]), + gr.inputs.Radio(label="Radio", choices=CHOICES, default=CHOICES[2]), gr.inputs.Dropdown(label="Dropdown", choices=CHOICES), gr.inputs.Image(label="Image", optional=True), + gr.inputs.Image(label="Image w/ Cropper", + tool="select", optional=True), + gr.inputs.Image(label="Sketchpad", source="canvas", optional=True), + gr.inputs.Image(label="Webcam", source="webcam", optional=True), gr.inputs.Video(label="Video", optional=True), gr.inputs.Audio(label="Audio", optional=True), + gr.inputs.Audio(label="Microphone", + source="microphone", optional=True), gr.inputs.File(label="File", optional=True), gr.inputs.Dataframe(), + gr.inputs.Timeseries(x="time", y="value", optional=True), ], outputs=[ gr.outputs.Textbox(), gr.outputs.Label(), - gr.outputs.Audio(type="numpy"), - gr.outputs.Image(type="numpy"), + gr.outputs.Audio(), + gr.outputs.Image(), + gr.outputs.Video(), + gr.outputs.KeyValues(), + gr.outputs.HighlightedText(), + gr.outputs.JSON(), + gr.outputs.HTML(), + gr.outputs.File(), + gr.outputs.Dataframe(), + gr.outputs.Carousel("image"), + gr.outputs.Timeseries(x="time", y="value") ], theme="huggingface" ) diff --git a/frontend/src/components/output/carousel.jsx b/frontend/src/components/output/carousel.jsx index 06ab4cbdcb..4393ce4e00 100644 --- a/frontend/src/components/output/carousel.jsx +++ b/frontend/src/components/output/carousel.jsx @@ -2,6 +2,8 @@ import React from "react"; import BaseComponent from "../base_component"; import ComponentExample from "../component_example"; import { output_component_map } from "../../components"; +import arrowRight from "../../static/img/arrow-right.svg"; +import arrowLeft from "../../static/img/arrow-left.svg"; class CarouselOutput extends BaseComponent { constructor(props) { @@ -52,27 +54,13 @@ class CarouselOutput extends BaseComponent { })}
{this.state.carousel_index + 1} / {this.props.value.length}
diff --git a/frontend/src/gradio.jsx b/frontend/src/gradio.jsx index 63952f2554..4c19537ab9 100644 --- a/frontend/src/gradio.jsx +++ b/frontend/src/gradio.jsx @@ -10,17 +10,14 @@ import logo_error from "./static/img/logo_error.png"; import logo from "./static/img/logo.svg"; import("./themes/defaults.scss"); import("./themes/huggingface.scss"); -import("./themes/compact.scss"); +import("./themes/grass.scss"); +import("./themes/peach.scss"); export class GradioPage extends React.Component { render() { return ( -
-
+
+
{this.props.title ? (

{this.props.title}

diff --git a/frontend/src/index.jsx b/frontend/src/index.jsx index 3885e84f52..23983b3302 100644 --- a/frontend/src/index.jsx +++ b/frontend/src/index.jsx @@ -81,12 +81,17 @@ function load_config(config) { head.appendChild(style); style.appendChild(document.createTextNode(config.css)); } + let target = document.getElementById(config.target || "root"); + if (config.theme !== null && config.theme.startsWith("dark")) { + target.classList.add("dark"); + config.theme = config.theme.substring(4); + } ReactDOM.render( , - document.getElementById(config.target || "root") + target ); } } diff --git a/frontend/src/static/img/arrow-left.svg b/frontend/src/static/img/arrow-left.svg new file mode 100644 index 0000000000..fbedab001e --- /dev/null +++ b/frontend/src/static/img/arrow-left.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/frontend/src/static/img/arrow-right.svg b/frontend/src/static/img/arrow-right.svg new file mode 100644 index 0000000000..6655169df0 --- /dev/null +++ b/frontend/src/static/img/arrow-right.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/frontend/src/themes/defaults.scss b/frontend/src/themes/defaults.scss index f207d3e3d2..08444a34ab 100644 --- a/frontend/src/themes/defaults.scss +++ b/frontend/src/themes/defaults.scss @@ -28,10 +28,6 @@ @apply min-h-full flex flex-col; } -.gradio_bg.dark { - @apply bg-gray-600 text-gray-50; -} - .login { @apply container mt-8; form { @@ -47,13 +43,18 @@ @apply p-2 block; } .submit { - @apply bg-yellow-500 hover:bg-yellow-400 transition px-4 py-2 rounded text-white font-semibold cursor-pointer mt-4; + @apply bg-yellow-500 hover:bg-yellow-400 dark:hover:bg-yellow-600 transition px-4 py-2 rounded text-white font-semibold cursor-pointer mt-4; } } -.gradio_page[theme="default"] .gradio_interface { +.gradio_bg[theme="default"] { + @apply dark:bg-gray-500; +} + + +.gradio_bg[theme="default"] .gradio_interface { .loading { - @apply absolute right-2 flex items-center gap-2; + @apply dark:text-gray-50 absolute right-2 flex items-center gap-2; } .loading img { @apply h-5 ml-2 inline-block; @@ -74,14 +75,14 @@ @apply flex-1; } .component_set { - @apply bg-gray-50 p-2 rounded flex flex-col flex-1 gap-2; + @apply bg-gray-50 dark:bg-gray-700 p-2 rounded flex flex-col flex-1 gap-2 dark:drop-shadow-xl; min-height: 36px; } .panel_header { - @apply mb-1 uppercase text-sm font-semibold; + @apply mb-1 uppercase text-sm font-semibold dark:text-gray-50; } .panel_button { - @apply flex-1 p-3 rounded bg-gray-50 hover:bg-gray-100 transition font-semibold focus:outline-none; + @apply bg-gray-50 hover:bg-gray-100 dark:bg-gray-700 dark:hover:bg-gray-600 dark:text-gray-50 flex-1 p-3 rounded transition font-semibold focus:outline-none; } .panel_button.disabled { @apply text-gray-400 cursor-not-allowed; @@ -206,7 +207,7 @@ .input_image { @apply w-full h-80 relative; .upload_zone { - @apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10; + @apply border-gray-300 text-gray-400 dark:border-gray-500 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; } .image_preview_holder { @apply w-full h-full flex justify-center items-center bg-gray-200 relative inline-block; @@ -383,7 +384,7 @@ @apply appearance-none w-5 h-5 bg-yellow-500 rounded cursor-pointer; } .value { - @apply inline-block mx-auto mt-1 px-2 py-0.5 bg-gray-200 rounded text-gray-700; + @apply text-gray-700 inline-block mx-auto mt-1 px-2 py-0.5 rounded; } .interpret_range { @apply flex h-6; @@ -403,7 +404,7 @@ @apply bg-red-200 text-red-500 p-2 rounded font-semibold; } audio { - @apply w-full border-2 border-gray-300 rounded; + @apply w-full; } .interpret_range { @apply flex h-4; @@ -415,7 +416,7 @@ .input_video { @apply w-full h-80; .upload_zone { - @apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10; + @apply border-gray-300 text-gray-400 dark:border-gray-500 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; } .video_preview_holder { @apply w-full h-full flex justify-center items-center bg-gray-200; @@ -427,7 +428,7 @@ .input_file { @apply w-full h-80; .upload_zone { - @apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10; + @apply border-gray-300 text-gray-400 dark:border-gray-500 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; } .file_preview_holder { @apply w-full h-full flex flex-col justify-center items-center relative inline-block; @@ -442,7 +443,7 @@ .input_timeseries { @apply w-full h-96; .upload_zone { - @apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10; + @apply border-gray-300 text-gray-400 dark:border-gray-500 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; } .file_preview_holder { @apply w-full h-full flex flex-col justify-center items-center relative inline-block; @@ -457,6 +458,7 @@ @apply w-full bg-white border-gray-400 rounded box-border p-1 whitespace-pre-wrap; } .output_label { + @apply dark:text-gray-50; .output_class { @apply font-bold text-2xl py-8 px-4 flex-grow flex items-center justify-center; } @@ -488,7 +490,7 @@ } .output_audio { audio { - @apply w-full border-2 border-gray-300 rounded; + @apply w-full; } } .output_highlightedtext { @@ -521,7 +523,7 @@ } } .output_file { - @apply w-full h-80; + @apply w-full h-80 dark:text-gray-50; .file_display { @apply w-full h-full flex flex-col justify-center items-center relative inline-block; } @@ -533,6 +535,7 @@ } } .output_dataframe { + @apply dark:text-gray-50; table { thead { @apply font-bold border-gray-200 border-b-2; @@ -561,9 +564,13 @@ .output_carousel { @apply flex flex-col gap-2; .carousel_control { - @apply flex gap-4 justify-center items-center mt-4; + @apply flex gap-4 justify-center items-center my-1; .carousel_index { - @apply text-2xl font-semibold; + min-width: 60px; + @apply text-xl text-center font-semibold; + } + button img { + @apply h-3 mt-0.5; } } } diff --git a/frontend/src/themes/compact.scss b/frontend/src/themes/grass.scss similarity index 60% rename from frontend/src/themes/compact.scss rename to frontend/src/themes/grass.scss index da5a4eeb4a..2d8ca655e0 100644 --- a/frontend/src/themes/compact.scss +++ b/frontend/src/themes/grass.scss @@ -6,9 +6,13 @@ html { font-size: 14px; } -.gradio_page[theme="compact"] .gradio_interface { +.gradio_bg[theme="grass"] { + @apply dark:bg-gray-600 dark:text-gray-50; +} + +.gradio_bg[theme="grass"] .gradio_interface { .loading { - @apply absolute right-1; + @apply absolute dark:text-gray-50 right-2 flex items-center gap-2 text-xs; } .loading img { @apply h-5; @@ -29,13 +33,17 @@ html { @apply flex-1; } .component_set { - @apply bg-gray-50 p-2 rounded flex flex-col flex-1 gap-2; + @apply bg-gray-50 dark:bg-gray-800 p-2 flex flex-col flex-1 gap-2; + min-height: 36px; } .panel_header { - @apply mb-1 uppercase text-sm font-semibold; + @apply mb-1 uppercase text-xs text-gray-600 dark:text-gray-200 font-semibold; + } + .component:hover .panel_header { + @apply text-green-600 dark:text-green-500; } .panel_button { - @apply flex-1 p-3 rounded bg-gray-50 hover:bg-gray-100 transition font-semibold focus:outline-none; + @apply flex-1 p-3 bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:text-gray-50 transition font-semibold focus:outline-none; } .panel_button.disabled { @apply text-gray-400 cursor-not-allowed; @@ -49,12 +57,12 @@ html { .flag { @apply relative; .dropcontent { - @apply hidden absolute top-8 left-0 bg-white border-gray-200 border-2 w-full; + @apply hidden absolute top-8 left-0 bg-white border-gray-200 dark:bg-gray-500 dark:text-gray-50 border-2 w-full; div { @apply p-2; } div:hover { - @apply bg-gray-100; + @apply bg-gray-100 dark:bg-gray-700; } } } @@ -66,12 +74,6 @@ html { .screenshot_set { @apply hidden flex hidden flex-grow; } - .panel_button.left_panel_button { - @apply rounded-tr-none rounded-br-none; - } - .panel_button.right_panel_button { - @apply rounded-tl-none rounded-bl-none bg-gray-200 hover:bg-gray-200; - } .examples { h4 { @apply text-lg font-semibold my-2; @@ -85,19 +87,16 @@ html { .shortcut { @apply block text-xs; } - .examples_control button { - @apply bg-gray-100 hover:bg-gray-200 p-2; - } - .examples_table { - @apply table-auto p-2 bg-gray-100 mt-4 rounded; + .examples_table:not(.gallery) { + @apply bg-gray-50 border-gray-100 dark:bg-gray-700 dark:text-gray-50 dark:border-none table-auto p-2 mt-4 rounded border; tbody tr { @apply cursor-pointer; } thead { - @apply border-b-2 border-gray-300; + @apply border-gray-100 dark:border-gray-800 border-b-2; } tbody tr:hover { - @apply bg-green-500 text-white; + @apply bg-indigo-500 dark:bg-indigo-900 text-white; } tbody tr.selected { @apply font-bold; @@ -107,23 +106,41 @@ html { @apply py-2 px-4; } } + .examples_table.gallery { + @apply block; + tbody { + @apply flex gap-2 flex-wrap ; + } + thead { + @apply hidden; + } + tbody td:hover { + @apply bg-indigo-500 dark:bg-indigo-900 text-white; + } + tbody tr.selected { + @apply font-bold; + } + td { + @apply bg-gray-50 dark:bg-gray-700 cursor-pointer p-2 rounded; + } + } .pages { @apply flex gap-1 items-center mt-2; } .page { - @apply px-2 py-1 bg-gray-100 rounded; + @apply bg-gray-100 dark:bg-gray-700 dark:text-gray-50 px-2 py-1 rounded; } .page.selected { - @apply bg-gray-300; + @apply bg-gray-300 dark:bg-gray-800; } } /* Input Components */ .input_text { textarea { - @apply w-full bg-white border-gray-400 rounded box-border p-1 resize-none; + @apply w-full bg-white dark:bg-gray-200 dark:text-blue-900 dark:font-semibold focus:ring-2 focus:ring-inset focus:ring-green-500 outline-none box-border p-1 resize-none; } input { - @apply w-full bg-white border-gray-400 rounded box-border p-1; + @apply w-full bg-white dark:bg-gray-200 dark:text-blue-900 dark:font-semibold focus:ring-2 focus:ring-inset focus:ring-green-500 outline-none box-border p-1; } .interpretation { .interpretation_box { @@ -133,7 +150,7 @@ html { } .input_number { input { - @apply w-full bg-white border-gray-400 rounded box-border p-1; + @apply w-full bg-white bg-white dark:bg-gray-200 dark:text-blue-900 dark:font-semibold focus:ring-2 focus:ring-inset focus:ring-green-500 outline-none box-border p-1; } .interpretation { @apply flex h-6; @@ -143,9 +160,9 @@ html { } } .input_image { - @apply w-full h-80 relative; + @apply w-full h-48 relative; .upload_zone { - @apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10; + @apply bg-gray-200 hover:bg-gray-100 dark:bg-gray-500 dark:hover:bg-gray-400 text-gray-600 dark:text-gray-50 transition w-full h-full flex justify-center items-center text-xl text-center cursor-pointer leading-10; } .image_preview_holder { @apply w-full h-full flex justify-center items-center bg-gray-200 relative inline-block; @@ -159,7 +176,7 @@ html { width: 800px; @apply flex justify-end gap-1; button { - @apply px-2 py-1 text-xl bg-black text-white font-semibold rounded-t; + @apply px-2 py-1 text-xl bg-black text-white font-semibold; } } .tui-image-editor-header-buttons { @@ -190,28 +207,25 @@ html { .input_radio { @apply flex flex-wrap gap-2; .radio_item { - @apply bg-gray-200 text-gray-700 py-2 px-4 font-semibold rounded cursor-pointer flex items-center gap-1; + @apply bg-gray-200 text-gray-700 p-1.5 font-semibold cursor-pointer flex items-center gap-1; } .radio_item.selected { @apply bg-green-500 text-white; } .radio_circle { - @apply w-4 h-4 bg-white rounded-full box-border; - } - .selected .radio_circle { - @apply border-4 border-green-600; + @apply hidden; } } .input_checkbox_group { @apply flex flex-wrap gap-2; .checkbox_item { - @apply bg-gray-200 text-gray-700 py-2 px-4 font-semibold rounded cursor-pointer flex items-center gap-1; + @apply bg-gray-200 text-gray-700 p-1.5 font-semibold cursor-pointer flex items-center gap-1; } .checkbox_item.selected { @apply bg-green-500 text-white; } .checkbox { - @apply w-4 h-4 bg-white; + @apply hidden; .check { @apply hidden; } @@ -245,7 +259,7 @@ html { .input_checkbox { @apply flex flex-wrap gap-2; .checkbox_item { - @apply bg-gray-200 text-gray-700 py-2 px-4 font-semibold rounded cursor-pointer flex items-center gap-1; + @apply bg-gray-200 text-gray-700 p-1.5 font-semibold cursor-pointer flex items-center gap-1; } .checkbox_item.selected { @apply bg-green-500 text-white; @@ -285,7 +299,7 @@ html { .input_dropdown { @apply inline-block relative; .selector { - @apply bg-gray-200 text-gray-700 py-2 px-4 font-semibold rounded inline-flex items-center; + @apply bg-gray-200 text-gray-700 p-1.5 font-semibold inline-flex items-center; } .caret { @apply ml-1 fill-current h-4 w-4; @@ -294,13 +308,13 @@ html { @apply absolute hidden text-gray-700 pt-1 max-h-80 overflow-y-auto z-10; } .dropdown_item:first-child { - @apply rounded-t; + @apply-t; } .dropdown_item { @apply bg-gray-200 hover:bg-gray-400 hover:text-gray-50 py-2 px-4 block whitespace-nowrap cursor-pointer; } .dropdown_item:last-child { - @apply rounded-b; + @apply-b; } :hover .dropdown_menu { @apply block; @@ -312,17 +326,17 @@ html { .input_slider { @apply text-center; .range { - @apply w-full appearance-none bg-gray-200 hover:bg-gray-200 transition rounded h-4; + @apply dark:bg-gray-200 focus:border-2 focus:border-green-400 box-border w-full appearance-none h-4; } .range::-webkit-slider-thumb { -webkit-appearance: none; - @apply appearance-none w-5 h-5 bg-green-500 rounded cursor-pointer; + @apply appearance-none w-5 h-5 bg-green-500 cursor-pointer; } .range::-moz-range-thumb { - @apply appearance-none w-5 h-5 bg-green-500 rounded cursor-pointer; + @apply appearance-none w-5 h-5 bg-green-500 cursor-pointer; } .value { - @apply inline-block mx-auto mt-1 px-2 py-0.5 bg-gray-200 rounded text-gray-700; + @apply inline-block mx-auto mt-0.5 px-2 text-sm; } .interpret_range { @apply flex h-6; @@ -336,13 +350,13 @@ html { @apply hidden; } .start { - @apply bg-gray-200 p-2 rounded font-semibold; + @apply bg-gray-200 dark:bg-gray-500 dark:text-gray-50 p-1.5 font-semibold; } .stop { - @apply bg-red-200 text-red-500 p-2 rounded font-semibold; + @apply bg-red-200 text-red-500 p-1.5 font-semibold; } audio { - @apply w-full border-2 border-gray-300 rounded; + @apply w-full; } .interpret_range { @apply flex h-4; @@ -352,9 +366,9 @@ html { } } .input_video { - @apply w-full h-80; + @apply w-full h-48; .upload_zone { - @apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10; + @apply bg-gray-200 hover:bg-gray-100 dark:bg-gray-500 dark:hover:bg-gray-400 text-gray-600 dark:text-gray-50 transition w-full h-full flex justify-center items-center text-xl text-center cursor-pointer leading-10; } .video_preview_holder { @apply w-full h-full flex justify-center items-center bg-gray-200; @@ -364,9 +378,9 @@ html { } } .input_file { - @apply w-full h-80; + @apply w-full h-48; .upload_zone { - @apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 text-center cursor-pointer leading-10; + @apply bg-gray-200 hover:bg-gray-100 dark:bg-gray-500 dark:hover:bg-gray-400 text-gray-600 dark:text-gray-50 transition w-full h-full flex justify-center items-center text-xl text-center cursor-pointer leading-10; } .file_preview_holder { @apply w-full h-full flex flex-col justify-center items-center relative inline-block; @@ -375,17 +389,29 @@ html { @apply text-6xl p-6; } .file_size { - @apply text-2xl p-2; + @apply text-2xl p-1.5; } } + .input_timeseries { + @apply w-full h-60; + .upload_zone { + @apply bg-gray-200 hover:bg-gray-100 dark:bg-gray-500 dark:hover:bg-gray-400 text-gray-600 dark:text-gray-50 transition w-full h-full flex justify-center items-center text-xl text-center cursor-pointer leading-10; + } + .file_preview_holder { + @apply w-full h-full flex flex-col justify-center items-center relative inline-block; + } + .js-plotly-plot, .plotly.js-plotly-plot * { + position: static !important; + } + } /* Output Components */ .output_text { word-break: break-word; - @apply w-full bg-white border-gray-400 rounded box-border p-1 whitespace-pre-wrap; + @apply w-full bg-white dark:text-blue-900 dark:font-semibold dark:bg-gray-200 border-gray-400 box-border p-1 whitespace-pre-wrap; } .output_label { .output_class { - @apply font-bold text-2xl py-8 px-4 flex-grow flex items-center justify-center; + @apply font-bold text-xl py-6 px-4 flex-grow flex items-center justify-center; } .confidence_intervals { @apply flex text-xl; @@ -397,14 +423,14 @@ html { @apply flex flex-grow flex-col items-baseline; } .label { - @apply overflow-hidden whitespace-nowrap h-7 mb-1 overflow-ellipsis text-right; + @apply overflow-hidden whitespace-nowrap h-5 mb-1 overflow-ellipsis text-right text-sm; } .confidence { - @apply bg-gray-400 text-white flex justify-end overflow-hidden whitespace-nowrap h-7 mb-1 px-1; + @apply bg-green-500 text-white font-semibold flex justify-end overflow-hidden whitespace-nowrap h-5 mb-1 px-1 text-sm; } } .output_image { - @apply w-full h-80; + @apply w-full h-48; .image_preview_holder { @apply w-full h-full flex justify-center items-center bg-gray-200 relative inline-block; } @@ -415,7 +441,7 @@ html { } .output_audio { audio { - @apply w-full border-2 border-gray-300 rounded; + @apply w-full; } } .output_highlightedtext { @@ -431,37 +457,67 @@ html { } .output_keyvalues { table { - @apply bg-white; + @apply bg-white dark:bg-gray-200 dark:text-blue-900; thead { @apply font-bold; } td, th { - @apply p-2; + @apply p-1.5; } } } .output_video { - @apply w-full h-80 object-contain flex justify-center; + @apply w-full h-48 object-contain flex justify-center; video { @apply h-full; } } .output_file { - @apply bg-gray-200 hover:bg-gray-100 transition inline-block rounded; + @apply bg-gray-200 hover:bg-gray-100 text-gray-600 transition inline-block; .file_name { - @apply text-lg p-2; + @apply text-lg p-1.5; } .file_size { @apply hidden; } } + .output_dataframe { + table { + thead { + @apply font-bold border-gray-200 border-b-2; + } + th { + @apply transition cursor-pointer; + } + th:hover { + @apply bg-gray-200; + } + td, + th { + @apply px-4; + } + } + .pages { + @apply flex gap-1 items-center; + } + .page { + @apply px-2 py-1 bg-gray-200; + } + .page.selected { + @apply bg-gray-300; + } + } .output_carousel { @apply flex flex-col gap-2; .carousel_control { - @apply flex gap-4 justify-center items-center mt-4; + @apply flex gap-4 justify-center items-center my-1; .carousel_index { - @apply text-2xl font-semibold; + min-width: 60px; + @apply text-xl text-center font-semibold; + } + button img { + @apply h-3 mt-0.5 dark:invert; } } } diff --git a/frontend/src/themes/huggingface.scss b/frontend/src/themes/huggingface.scss index 8b905c74ae..a3205c7a77 100644 --- a/frontend/src/themes/huggingface.scss +++ b/frontend/src/themes/huggingface.scss @@ -2,7 +2,11 @@ @tailwind components; @tailwind utilities; -.gradio_page[theme="huggingface"] .gradio_interface { +.gradio_bg[theme="huggingface"] { + @apply dark:bg-gray-600 dark:text-gray-50; +} + +.gradio_bg[theme="huggingface"] .gradio_interface { .loading { @apply text-gray-700 dark:text-gray-50 absolute right-2 flex items-center gap-2 text-sm; } @@ -431,7 +435,7 @@ } .output_audio { audio { - @apply w-full border-2 border-gray-300 dark:border-none rounded; + @apply w-full; } } .output_highlightedtext { @@ -503,9 +507,13 @@ .output_carousel { @apply flex flex-col gap-2; .carousel_control { - @apply flex gap-4 justify-center items-center mt-4; + @apply flex gap-4 justify-center items-center my-1; .carousel_index { - @apply text-2xl font-semibold; + min-width: 60px; + @apply text-xl text-center font-semibold; + } + button img { + @apply h-3 mt-0.5 dark:invert; } } } diff --git a/frontend/src/themes/peach.scss b/frontend/src/themes/peach.scss new file mode 100644 index 0000000000..720fcd436d --- /dev/null +++ b/frontend/src/themes/peach.scss @@ -0,0 +1,532 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +.gradio_bg[theme="peach"] { + @apply bg-red-50 dark:bg-yellow-700; +} + + +.gradio_bg[theme="peach"] .gradio_interface { + .loading { + @apply dark:text-gray-50 absolute right-2 flex items-center gap-2; + } + .loading img { + @apply h-5 ml-2 inline-block; + } + .panels { + @apply flex flex-wrap justify-center gap-4; + } + .panels.unaligned { + @apply flex-col sm:flex-row items-stretch sm:items-start + } + .panels.horizontal { + @apply flex-col sm:flex-row items-stretch; + } + .panels.vertical { + @apply flex-col items-stretch; + } + .panel { + @apply flex-1; + } + .component_set { + @apply bg-red-100 dark:bg-yellow-900 p-2 rounded-lg flex flex-col flex-1 gap-2 dark:drop-shadow-xl; + min-height: 36px; + } + .panel_header { + @apply font-serif dark:text-gray-50 mb-1 text-sm; + } + .panel_button { + @apply bg-gray-50 hover:bg-gray-100 dark:bg-yellow-900 dark:hover:bg-yellow-800 dark:text-gray-50 flex-1 p-3 rounded-lg transition font-semibold focus:outline-none; + } + .panel_button.disabled { + @apply text-gray-400 dark:text-yellow-700 cursor-not-allowed; + } + .panel_button.submit { + @apply bg-red-500 dark:bg-yellow-900 dark:hover:bg-yellow-900 hover:bg-red-400 text-white; + } + .panel_buttons { + @apply flex gap-4 my-4; + } + .flag { + @apply relative; + .dropcontent { + @apply hidden absolute top-8 left-0 bg-white border-gray-200 border-2 w-full; + div { + @apply p-2; + } + div:hover { + @apply bg-gray-100; + } + } + } + .flag:hover:not(.disabled) { + .dropcontent { + @apply block; + } + } + .screenshot_set { + @apply hidden flex hidden flex-grow; + } + .panel_button.left_panel_button { + @apply rounded-tr-none rounded-br-none; + } + .panel_button.right_panel_button { + @apply rounded-tl-none rounded-bl-none hover:bg-gray-200; + } + .examples { + h4 { + @apply text-lg font-semibold my-2; + } + .examples_control_left { + @apply flex gap-2; + } + .shortcut { + @apply block text-xs; + } + .examples_control button { + @apply bg-gray-100 hover:p-2; + } + .examples_table:not(.gallery) { + @apply table-auto p-2 bg-gray-100 mt-4 rounded; + tbody tr { + @apply cursor-pointer; + } + thead { + @apply border-b-2 border-gray-300; + } + tbody tr:hover { + @apply bg-red-500 dark:bg-black dark:bg-opacity-30 text-white; + } + tbody tr.selected { + @apply font-bold; + } + td, + th { + @apply py-2 px-4; + } + } + .examples_table.gallery { + @apply block; + tbody { + @apply flex gap-2 flex-wrap ; + } + thead { + @apply hidden; + } + tbody td:hover { + @apply bg-red-500 dark:bg-black dark:bg-opacity-30 text-white; + } + tbody tr.selected { + @apply font-bold; + } + td { + @apply cursor-pointer p-2 rounded-lg bg-gray-100; + } + } + .pages { + @apply flex gap-1 items-center mt-2; + } + .page { + @apply px-2 py-1 bg-gray-100 rounded; + } + .page.selected { + @apply bg-gray-300; + } + } + /* Input Components */ + .input_text { + textarea { + @apply w-full bg-white dark:bg-gray-100 border-gray-400 rounded-lg box-border p-1 resize-none; + } + input { + @apply w-full bg-white dark:bg-gray-100 border-gray-400 rounded-lg box-border p-1; + } + .interpretation { + .interpretation_box { + @apply inline-block whitespace-pre-wrap; + } + } + } + .input_number { + input { + @apply w-full bg-white dark:bg-gray-100 border-gray-400 rounded-lg box-border p-1; + } + .interpretation { + @apply flex h-6; + .interpretation_box { + @apply flex-grow; + } + } + } + .input_image { + @apply w-full h-80 relative; + .upload_zone { + @apply border-red-300 text-red-400 dark:border-none dark:text-gray-50 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; + } + .image_preview_holder { + @apply w-full h-full flex justify-center items-center relative inline-block; + } + .edit_button { + @apply absolute top-1 right-1 bg-red-500 dark:bg-black dark:bg-opacity-30 text-white px-2 py-1; + } + .image_editor { + @apply fixed w-screen h-screen top-0 left-0 bg-black bg-opacity-50 z-40 flex flex-col justify-center items-center; + .image_editor_buttons { + width: 800px; + @apply flex justify-end gap-1; + button { + @apply px-2 py-1 text-xl bg-black text-white font-semibold rounded-t; + } + } + .tui-image-editor-header-buttons { + @apply hidden; + } + .tui-colorpicker-palette-button { + width: 12px; + height: 12px; + } + } + .image_preview, + video { + @apply w-full h-full object-contain; + } + .sketch > div { + @apply bg-white; + } + .snapshot { + @apply absolute bottom-0 w-full bg-white bg-opacity-90 py-3 font-bold text-lg text-center; + } + .interpretation { + @apply w-full h-full absolute top-0 left-0 flex justify-center items-center opacity-90 hover:opacity-20 transition; + } + } + .input_image_example { + @apply h-24; + } + .input_radio { + @apply flex flex-wrap gap-2; + .radio_item { + @apply bg-red-200 text-gray-700 dark:text-gray-50 dark:bg-black dark:bg-opacity-10 py-2 px-4 font-semibold rounded-lg cursor-pointer flex items-center gap-1; + } + .radio_item.selected { + @apply bg-red-500 dark:bg-black dark:bg-opacity-30 text-white; + } + .radio_circle { + @apply w-4 h-4 bg-white rounded-full box-border; + } + .selected .radio_circle { + @apply border-4 border-red-600 dark:border-gray-800; + } + } + .input_checkbox_group { + @apply flex flex-wrap gap-2; + .checkbox_item { + @apply bg-red-200 text-gray-700 dark:text-gray-50 dark:bg-black dark:bg-opacity-10 py-2 px-4 font-semibold rounded-lg cursor-pointer flex items-center gap-1; + } + .checkbox_item.selected { + @apply bg-red-500 dark:bg-black dark:bg-opacity-30 text-white; + } + .checkbox { + @apply w-4 h-4 bg-white; + .check { + @apply hidden; + } + } + .selected .checkbox { + @apply bg-red-600 dark:bg-gray-800; + .check { + @apply block; + } + } + .check line { + stroke: white; + stroke-width: 4; + stroke-linecap: round; + } + .interpretation { + @apply flex; + .interpretation_box { + @apply flex-grow h-4 w-4; + } + .interpret_check { + @apply w-full h-full; + } + .interpret_check line { + stroke: gray; + stroke-width: 4; + stroke-linecap: round; + } + } + } + .input_checkbox { + @apply flex flex-wrap gap-2; + .checkbox_item { + @apply bg-red-200 text-gray-700 dark:text-gray-50 dark:bg-black dark:bg-opacity-10 py-2 px-4 font-semibold rounded-lg cursor-pointer flex items-center gap-1; + } + .checkbox_item.selected { + @apply bg-red-500 dark:bg-black dark:bg-opacity-30 text-white; + } + .checkbox { + @apply w-4 h-4 bg-white; + .check { + @apply hidden; + } + } + .selected .checkbox { + @apply bg-red-600 dark:bg-gray-800; + .check { + @apply block; + } + } + .check line { + stroke: white; + stroke-width: 4; + stroke-linecap: round; + } + .interpretation { + @apply flex; + .interpretation_box { + @apply flex-grow h-4 w-4; + } + .interpret_check { + @apply w-full h-full; + } + .interpret_check line { + stroke: gray; + stroke-width: 4; + stroke-linecap: round; + } + } + } + .input_dropdown { + @apply inline-block relative; + .selector { + @apply bg-red-200 text-gray-700 dark:bg-black dark:bg-opacity-30 dark:text-gray-50 py-2 px-4 font-semibold rounded-lg inline-flex items-center; + } + .caret { + @apply ml-1 fill-current h-4 w-4; + } + .dropdown_menu { + @apply absolute hidden text-gray-700 pt-1 max-h-80 overflow-y-auto z-10; + } + .dropdown_item:first-child { + @apply rounded-t; + } + .dropdown_item { + @apply bg-red-200 hover:bg-red-400 hover:text-gray-50 dark:bg-yellow-800 dark:text-gray-50 dark:hover:bg-yellow-900 py-2 px-4 block whitespace-nowrap cursor-pointer; + } + .dropdown_item:last-child { + @apply rounded-b; + } + :hover .dropdown_menu { + @apply block; + } + .interpretation_box { + @apply p-1; + } + } + .input_slider { + @apply text-center; + .range { + @apply hover:bg-white dark:bg-gray-100 w-full appearance-none transition rounded-full h-4; + } + .range::-webkit-slider-thumb { + -webkit-appearance: none; + @apply appearance-none w-5 h-5 bg-red-500 dark:bg-gray-800 rounded-full cursor-pointer; + } + .range::-moz-range-thumb { + @apply appearance-none w-5 h-5 bg-red-500 dark:bg-gray-800 rounded-full cursor-pointer; + } + .value { + @apply text-gray-700 dark:text-gray-50 inline-block mx-auto mt-1 px-2 py-0.5 rounded-lg; + } + .interpret_range { + @apply flex h-6; + div { + @apply flex-grow; + } + } + } + .input_audio { + .audio-react-recorder { + @apply hidden; + } + .start { + @apply p-2 rounded-lg font-semibold; + } + .stop { + @apply bg-red-200 text-red-500 p-2 rounded-lg font-semibold; + } + audio { + @apply w-full; + } + .interpret_range { + @apply flex h-4; + div { + @apply flex-grow h-full; + } + } + } + .input_video { + @apply w-full h-80; + .upload_zone { + @apply border-red-300 text-red-400 dark:border-none dark:text-gray-50 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; + } + .video_preview_holder { + @apply w-full h-full flex justify-center items-center bg-gray-200; + } + .video_preview { + @apply w-full h-full object-contain; + } + } + .input_file { + @apply w-full h-80; + .upload_zone { + @apply border-red-300 text-red-400 dark:border-none dark:text-gray-50 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; + } + .file_preview_holder { + @apply w-full h-full flex flex-col justify-center items-center relative inline-block; + } + .file_name { + @apply text-6xl p-6; + } + .file_size { + @apply text-2xl p-2; + } + } + .input_timeseries { + @apply w-full h-96; + .upload_zone { + @apply border-red-300 text-red-400 dark:border-none dark:text-gray-50 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10; + } + .file_preview_holder { + @apply w-full h-full flex flex-col justify-center items-center relative inline-block; + } + .js-plotly-plot, .plotly.js-plotly-plot * { + position: static !important; + } + } + /* Output Components */ + .output_text { + word-break: break-word; + @apply w-full bg-white border-gray-400 rounded-lg box-border p-1 whitespace-pre-wrap; + } + .output_label { + @apply dark:text-gray-50; + .output_class { + @apply font-bold text-2xl py-8 px-4 flex-grow flex items-center justify-center; + } + .confidence_intervals { + @apply flex text-xl; + } + .labels { + @apply mr-1; + } + .confidences { + @apply flex flex-grow flex-col items-baseline; + } + .label { + @apply overflow-hidden whitespace-nowrap h-7 mb-1 overflow-ellipsis text-right; + } + .confidence { + @apply bg-red-500 dark:bg-black dark:bg-opacity-30 text-white flex justify-end overflow-hidden whitespace-nowrap h-7 mb-1 px-1; + } + } + .output_image { + @apply w-full h-80; + .image_preview_holder { + @apply w-full h-full flex justify-center items-center relative inline-block; + } + .image_preview, + video { + @apply w-full h-full object-contain; + } + } + .output_audio { + audio { + @apply w-full; + } + } + .output_highlightedtext { + .category_legend { + @apply flex flex-wrap gap-4 mb-2; + .category-label { + @apply flex gap-2; + } + .colorbox { + @apply w-6; + } + } + } + .output_keyvalues { + table { + @apply bg-white; + thead { + @apply font-bold; + } + td, + th { + @apply p-2; + } + } + } + .output_video { + @apply w-full h-80 object-contain flex justify-center; + video { + @apply h-full; + } + } + .output_file { + @apply w-full h-80 dark:text-gray-50; + .file_display { + @apply w-full h-full flex flex-col justify-center items-center relative inline-block; + } + .file_name { + @apply text-6xl p-6; + } + .file_size { + @apply text-2xl p-2; + } + } + .output_dataframe { + @apply dark:text-gray-50; + table { + thead { + @apply font-bold border-gray-200 border-b-2; + } + th { + @apply transition cursor-pointer; + } + th:hover { + @apply bg-gray-200; + } + td, + th { + @apply px-4; + } + } + .pages { + @apply flex gap-1 items-center; + } + .page { + @apply px-2 py-1 bg-gray-200; + } + .page.selected { + @apply bg-gray-300; + } + } + .output_carousel { + @apply flex flex-col gap-2; + .carousel_control { + @apply flex gap-4 justify-center items-center my-1; + .carousel_index { + min-width: 60px; + @apply text-xl text-center font-semibold; + } + button img { + @apply h-3 mt-0.5; + } + } + } +} diff --git a/gradio/frontend/asset-manifest.json b/gradio/frontend/asset-manifest.json index babcefb636..3412f3c065 100644 --- a/gradio/frontend/asset-manifest.json +++ b/gradio/frontend/asset-manifest.json @@ -1,15 +1,17 @@ { "files": { - "main.css": "/static/css/main.0e1c8a10.css", + "main.css": "/static/css/main.b12b2171.css", "main.js": "/static/bundle.js", "index.html": "/index.html", "static/bundle.js.LICENSE.txt": "/static/bundle.js.LICENSE.txt", + "static/media/arrow-left.e497f657.svg": "/static/media/arrow-left.e497f657.svg", + "static/media/arrow-right.ea6059fd.svg": "/static/media/arrow-right.ea6059fd.svg", "static/media/logo.411acfd1.svg": "/static/media/logo.411acfd1.svg", "static/media/logo_loading.e93acd82.jpg": "/static/media/logo_loading.e93acd82.jpg" }, "entrypoints": [ "static/bundle.css", - "static/css/main.0e1c8a10.css", + "static/css/main.b12b2171.css", "static/bundle.js" ] } \ No newline at end of file diff --git a/gradio/frontend/index.html b/gradio/frontend/index.html index 2079390d50..56d0e6b43f 100644 --- a/gradio/frontend/index.html +++ b/gradio/frontend/index.html @@ -8,4 +8,4 @@ window.config = {{ config|tojson }}; } catch (e) { window.config = {}; - }Gradio
\ No newline at end of file + }Gradio
\ No newline at end of file diff --git a/gradio/inputs.py b/gradio/inputs.py index c86d407406..86661eb6ac 100644 --- a/gradio/inputs.py +++ b/gradio/inputs.py @@ -1193,23 +1193,26 @@ class Timeseries(InputComponent): Demos: fraud_detector.py """ - def __init__(self, x=None, y=None, label=None): + def __init__(self, x=None, y=None, label=None, optional=False): """ Parameters: x (str): Column name of x (time) series. None if csv has no headers, in which case first column is x series. y (Union[str, List[str]]): Column name of y series, or list of column names if multiple series. None if csv has no headers, in which case every column after first is a y series. label (str): component name in interface. + optional (bool): If True, the interface can be submitted with no uploaded csv file, in which case the input value is None. """ self.x = x if isinstance(y, str): y = [y] self.y = y + self.optional = optional super().__init__(label) def get_template_context(self): return { "x": self.x, "y": self.y, + "optional": self.optional, **super().get_template_context() } @@ -1220,6 +1223,8 @@ class Timeseries(InputComponent): } def preprocess(self, x): + if x is None: + return x dataframe = pd.DataFrame(data=x["data"], columns=x["headers"]) if x["range"] is not None: dataframe = dataframe.loc[dataframe[self.x or 0] >= x["range"][0]] diff --git a/gradio/interface.py b/gradio/interface.py index df220cf58d..ce4c38fb82 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -89,7 +89,7 @@ class Interface: description (str): a description for the interface; if provided, appears above the input and output components. article (str): an expanded article explaining the interface; if provided, appears below the input and output components. Accepts Markdown and HTML content. thumbnail (str): path to image or src to use as display picture for models listed in gradio.app/hub - theme (str): Theme to use - one of "default", "compact", "huggingface", or "darkhuggingface". + theme (str): Theme to use - one of "default", "huggingface", "grass", "peach". Add "dark" prefix, e.g. "darkpeach" or "darkdefault" for darktheme. css (str): custom css or path to custom css file to use with interface. server_port (int): will start gradio app on this port (if available) server_name (str): to make app accessible on local network set to "0.0.0.0". @@ -144,7 +144,7 @@ class Interface: self.article = article self.thumbnail = thumbnail theme = theme if theme is not None else os.getenv("GRADIO_THEME", "default") - if theme not in ("default", "compact", "huggingface", "darkhuggingface"): + if theme not in ("default", "huggingface", "grass", "peach", "darkdefault", "darkhuggingface", "darkgrass", "darkpeach"): raise ValueError("Invalid theme name.") self.theme = theme self.height = height