mirror of
https://github.com/gradio-app/gradio.git
synced 2025-04-12 12:40:29 +08:00
Change sidebar position (#10582)
* position * position * add changeset * fixes --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
b640df2517
commit
1299267a8a
6
.changeset/real-carrots-sniff.md
Normal file
6
.changeset/real-carrots-sniff.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"@gradio/sidebar": minor
|
||||
"gradio": minor
|
||||
---
|
||||
|
||||
feat:Change sidebar position
|
@ -1 +1 @@
|
||||
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: blocks_sidebar"]}, {"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", "import random\n", "\n", "def generate_pet_name(animal_type, personality):\n", " cute_prefixes = [\"Fluffy\", \"Ziggy\", \"Bubbles\", \"Pickle\", \"Waffle\", \"Mochi\", \"Cookie\", \"Pepper\"]\n", " animal_suffixes = {\n", " \"Cat\": [\"Whiskers\", \"Paws\", \"Mittens\", \"Purrington\"],\n", " \"Dog\": [\"Woofles\", \"Barkington\", \"Waggins\", \"Pawsome\"],\n", " \"Bird\": [\"Feathers\", \"Wings\", \"Chirpy\", \"Tweets\"],\n", " \"Rabbit\": [\"Hops\", \"Cottontail\", \"Bouncy\", \"Fluff\"]\n", " }\n", "\n", " prefix = random.choice(cute_prefixes)\n", " suffix = random.choice(animal_suffixes[animal_type])\n", "\n", " if personality == \"Silly\":\n", " prefix = random.choice([\"Sir\", \"Lady\", \"Captain\", \"Professor\"]) + \" \" + prefix\n", " elif personality == \"Royal\":\n", " suffix += \" the \" + random.choice([\"Great\", \"Magnificent\", \"Wise\", \"Brave\"])\n", "\n", " return f\"{prefix} {suffix}\"\n", "\n", "with gr.Blocks(theme=gr.themes.Soft()) as demo:\n", " with gr.Sidebar():\n", " gr.Markdown(\"# \ud83d\udc3e Pet Name Generator\")\n", " gr.Markdown(\"Use the options below to generate a unique pet name!\")\n", "\n", " animal_type = gr.Dropdown(\n", " choices=[\"Cat\", \"Dog\", \"Bird\", \"Rabbit\"],\n", " label=\"Choose your pet type\",\n", " value=\"Cat\"\n", " )\n", " personality = gr.Radio(\n", " choices=[\"Normal\", \"Silly\", \"Royal\"],\n", " label=\"Personality type\",\n", " value=\"Normal\"\n", " )\n", "\n", " name_output = gr.Textbox(label=\"Your pet's fancy name:\", lines=2)\n", " generate_btn = gr.Button(\"Generate Name! \ud83c\udfb2\", variant=\"primary\")\n", " generate_btn.click(\n", " fn=generate_pet_name,\n", " inputs=[animal_type, personality],\n", " outputs=name_output\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_sidebar"]}, {"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", "import random\n", "\n", "def generate_pet_name(animal_type, personality):\n", " cute_prefixes = [\"Fluffy\", \"Ziggy\", \"Bubbles\", \"Pickle\", \"Waffle\", \"Mochi\", \"Cookie\", \"Pepper\"]\n", " animal_suffixes = {\n", " \"Cat\": [\"Whiskers\", \"Paws\", \"Mittens\", \"Purrington\"],\n", " \"Dog\": [\"Woofles\", \"Barkington\", \"Waggins\", \"Pawsome\"],\n", " \"Bird\": [\"Feathers\", \"Wings\", \"Chirpy\", \"Tweets\"],\n", " \"Rabbit\": [\"Hops\", \"Cottontail\", \"Bouncy\", \"Fluff\"]\n", " }\n", "\n", " prefix = random.choice(cute_prefixes)\n", " suffix = random.choice(animal_suffixes[animal_type])\n", "\n", " if personality == \"Silly\":\n", " prefix = random.choice([\"Sir\", \"Lady\", \"Captain\", \"Professor\"]) + \" \" + prefix\n", " elif personality == \"Royal\":\n", " suffix += \" the \" + random.choice([\"Great\", \"Magnificent\", \"Wise\", \"Brave\"])\n", "\n", " return f\"{prefix} {suffix}\"\n", "\n", "with gr.Blocks(theme=gr.themes.Soft()) as demo:\n", " with gr.Sidebar(position=\"left\"):\n", " gr.Markdown(\"# \ud83d\udc3e Pet Name Generator\")\n", " gr.Markdown(\"Use the options below to generate a unique pet name!\")\n", "\n", " animal_type = gr.Dropdown(\n", " choices=[\"Cat\", \"Dog\", \"Bird\", \"Rabbit\"],\n", " label=\"Choose your pet type\",\n", " value=\"Cat\"\n", " )\n", " personality = gr.Radio(\n", " choices=[\"Normal\", \"Silly\", \"Royal\"],\n", " label=\"Personality type\",\n", " value=\"Normal\"\n", " )\n", "\n", " name_output = gr.Textbox(label=\"Your pet's fancy name:\", lines=2)\n", " generate_btn = gr.Button(\"Generate Name! \ud83c\udfb2\", variant=\"primary\")\n", " generate_btn.click(\n", " fn=generate_pet_name,\n", " inputs=[animal_type, personality],\n", " outputs=name_output\n", " )\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
|
@ -21,7 +21,7 @@ def generate_pet_name(animal_type, personality):
|
||||
return f"{prefix} {suffix}"
|
||||
|
||||
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
||||
with gr.Sidebar():
|
||||
with gr.Sidebar(position="left"):
|
||||
gr.Markdown("# 🐾 Pet Name Generator")
|
||||
gr.Markdown("Use the options below to generate a unique pet name!")
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from gradio_client.documentation import document
|
||||
|
||||
from gradio.blocks import BlockContext
|
||||
@ -31,6 +33,7 @@ class Sidebar(BlockContext, metaclass=ComponentMeta):
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
width: int | str = 320,
|
||||
position: Literal["left", "right"] = "left",
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -40,10 +43,12 @@ class Sidebar(BlockContext, metaclass=ComponentMeta):
|
||||
elem_classes: An optional string or list of strings that are assigned as the class of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, this layout will not be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
width: The width of the sidebar, specified in pixels if a number is passed, or in CSS units if a string is passed.
|
||||
position: The position of the sidebar in the layout, either "left" or "right". Defaults to "left".
|
||||
"""
|
||||
self.label = label
|
||||
self.open = open
|
||||
self.width = width
|
||||
self.position = position
|
||||
BlockContext.__init__(
|
||||
self,
|
||||
visible=visible,
|
||||
|
@ -5,6 +5,7 @@
|
||||
import type { Gradio } from "@gradio/utils";
|
||||
import Column from "@gradio/column";
|
||||
export let open = true;
|
||||
export let position: "left" | "right" = "left";
|
||||
export let loading_status: LoadingStatus;
|
||||
export let gradio: Gradio<{
|
||||
expand: never;
|
||||
@ -21,6 +22,7 @@
|
||||
|
||||
<Sidebar
|
||||
bind:open
|
||||
bind:position
|
||||
{width}
|
||||
on:expand={() => gradio.dispatch("expand")}
|
||||
on:collapse={() => gradio.dispatch("collapse")}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
export let open = true;
|
||||
export let width: number | string;
|
||||
export let position: "left" | "right" = "left";
|
||||
|
||||
// Using a temporary variable to animate the sidebar opening at the start
|
||||
let mounted = false;
|
||||
@ -22,7 +23,10 @@
|
||||
const parent_rect = sidebar_div.closest(".wrap")?.getBoundingClientRect();
|
||||
if (!parent_rect) return;
|
||||
const sidebar_rect = sidebar_div.getBoundingClientRect();
|
||||
const available_space = parent_rect.left;
|
||||
const available_space =
|
||||
position === "left"
|
||||
? parent_rect.left
|
||||
: window.innerWidth - parent_rect.right;
|
||||
overlap_amount = Math.max(0, sidebar_rect.width - available_space + 30);
|
||||
}
|
||||
|
||||
@ -30,7 +34,6 @@
|
||||
sidebar_div.closest(".wrap")?.classList.add("sidebar-parent");
|
||||
check_overlap();
|
||||
window.addEventListener("resize", check_overlap);
|
||||
|
||||
const update_parent_overlap = (): void => {
|
||||
document.documentElement.style.setProperty(
|
||||
"--overlap-amount",
|
||||
@ -39,7 +42,9 @@
|
||||
};
|
||||
update_parent_overlap();
|
||||
mounted = true;
|
||||
return () => window.removeEventListener("resize", check_overlap);
|
||||
return () => {
|
||||
window.removeEventListener("resize", check_overlap);
|
||||
};
|
||||
});
|
||||
|
||||
// We need to wait for the component to be mounted before we can set the open state
|
||||
@ -50,8 +55,9 @@
|
||||
<div
|
||||
class="sidebar"
|
||||
class:open={_open}
|
||||
class:right={position === "right"}
|
||||
bind:this={sidebar_div}
|
||||
style="width: {width_css}; left: calc({width_css} * -1)"
|
||||
style="width: {width_css}; {position}: calc({width_css} * -1)"
|
||||
>
|
||||
<button
|
||||
on:click={() => {
|
||||
@ -94,13 +100,20 @@
|
||||
:global(.sidebar-parent) {
|
||||
display: flex !important;
|
||||
padding-left: 0;
|
||||
transition: padding-left 0.3s ease-in-out;
|
||||
padding-right: 0;
|
||||
transition:
|
||||
padding-left 0.3s ease-in-out,
|
||||
padding-right 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
:global(.sidebar-parent:has(.sidebar.open)) {
|
||||
:global(.sidebar-parent:has(.sidebar.open:not(.right))) {
|
||||
padding-left: var(--overlap-amount);
|
||||
}
|
||||
|
||||
:global(.sidebar-parent:has(.sidebar.open.right)) {
|
||||
padding-right: var(--overlap-amount);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -108,20 +121,24 @@
|
||||
top: 0;
|
||||
height: 100%;
|
||||
background-color: var(--background-fill-secondary);
|
||||
box-shadow: var(--size-1) 0 var(--size-2) rgba(100, 89, 89, 0.1);
|
||||
transform: translateX(0%);
|
||||
transition: transform 0.3s ease-in-out;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.sidebar.open {
|
||||
.sidebar.open:not(.right) {
|
||||
transform: translateX(100%);
|
||||
box-shadow: var(--size-1) 0 var(--size-2) rgba(100, 89, 89, 0.1);
|
||||
}
|
||||
|
||||
.sidebar.open.right {
|
||||
transform: translateX(-100%);
|
||||
box-shadow: calc(var(--size-1) * -1) 0 var(--size-2) rgba(100, 89, 89, 0.1);
|
||||
}
|
||||
|
||||
.toggle-button {
|
||||
position: absolute;
|
||||
top: var(--size-4);
|
||||
right: calc(var(--size-8) * -1);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
@ -129,17 +146,32 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: right 0.3s ease-in-out;
|
||||
transition: all 0.3s ease-in-out;
|
||||
width: var(--size-8);
|
||||
height: var(--size-8);
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.open .toggle-button {
|
||||
.sidebar:not(.right) .toggle-button {
|
||||
right: calc(var(--size-8) * -1);
|
||||
}
|
||||
|
||||
.sidebar.right .toggle-button {
|
||||
left: calc(var(--size-8) * -1);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.open:not(.right) .toggle-button {
|
||||
right: var(--size-2-5);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.open.right .toggle-button {
|
||||
left: auto;
|
||||
right: var(--size-2-5);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
.chevron {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -163,4 +195,8 @@
|
||||
padding-right: var(--size-8);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sidebar.right .sidebar-content {
|
||||
padding-left: var(--size-8);
|
||||
}
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user