mirror of
https://github.com/gradio-app/gradio.git
synced 2025-03-31 12:20:26 +08:00
Implement left and right click in Gallery
component and show implicit images in Gallery
grid (#4995)
* tweak responsive behaviour in gallery * test * add function to move left + right on click * add changeset * fix ts error * Delete soft-eyes-repeat.md * add changeset * add gallery story * change y overflow to scroll --------- Co-authored-by: pngwn <hello@pngwn.io> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
41c83070b0
commit
3f8c210b01
7
.changeset/curly-crabs-sniff.md
Normal file
7
.changeset/curly-crabs-sniff.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@gradio/app": minor
|
||||
"@gradio/gallery": minor
|
||||
"gradio": minor
|
||||
---
|
||||
|
||||
feat:Implement left and right click in `Gallery` component and show implicit images in `Gallery` grid
|
@ -11,74 +11,74 @@
|
||||
control: "text",
|
||||
description: "The gallery label",
|
||||
name: "label",
|
||||
value: "Gradio Button"
|
||||
value: "Gradio Button",
|
||||
},
|
||||
show_label: {
|
||||
options: [true, false],
|
||||
description: "Whether to show the label",
|
||||
control: { type: "boolean" },
|
||||
defaultValue: true
|
||||
defaultValue: true,
|
||||
},
|
||||
grid_cols: {
|
||||
options: [1, 2, 3, 4],
|
||||
description: "The number of colums to show in grid",
|
||||
control: { type: "select" },
|
||||
defaultValue: 2
|
||||
defaultValue: 2,
|
||||
},
|
||||
grid_rows: {
|
||||
options: [1, 2, 3, 4],
|
||||
description: "The number of rows to show in grid",
|
||||
control: { type: "select" },
|
||||
defaultValue: 2
|
||||
defaultValue: 2,
|
||||
},
|
||||
height: {
|
||||
options: ["auto", 500, 600],
|
||||
description: "The height of the grid",
|
||||
control: { type: "select" },
|
||||
defaultValue: "auto"
|
||||
defaultValue: "auto",
|
||||
},
|
||||
preview: {
|
||||
options: [true, false],
|
||||
description: "Whether to start the gallery in preview mode",
|
||||
control: { type: "boolean" },
|
||||
defaultValue: true
|
||||
defaultValue: true,
|
||||
},
|
||||
allow_preview: {
|
||||
options: [true, false],
|
||||
description: "Whether to allow a preview mode in the gallery",
|
||||
control: { type: "boolean" },
|
||||
defaultValue: true
|
||||
defaultValue: true,
|
||||
},
|
||||
object_fit: {
|
||||
options: ["contain", "cover", "fill", "none", "scale-down"],
|
||||
description: "How to display each indivial image in the grid",
|
||||
control: { type: "select" },
|
||||
defaultValue: "contain"
|
||||
defaultValue: "contain",
|
||||
},
|
||||
show_share_button: {
|
||||
options: [true, false],
|
||||
description: "Whether to show the share button in the gallery",
|
||||
control: { type: "boolean" },
|
||||
defaultValue: false
|
||||
}
|
||||
defaultValue: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<Template let:args>
|
||||
<Gallery
|
||||
{...args}
|
||||
value={[
|
||||
[
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/cheetah_running.avif",
|
||||
"A fast cheetah"
|
||||
"A fast cheetah",
|
||||
],
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/cheetah-002.jpg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/cheetah-003.jpg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/cheetah3.webp",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/main-qimg-0bbf31c18a22178cb7a8dd53640a3d05-lq.jpeg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/TheCheethcat.jpg"
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/TheCheethcat.jpg",
|
||||
]}
|
||||
{...args}
|
||||
/>
|
||||
</Template>
|
||||
|
||||
@ -96,7 +96,7 @@
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
grid_rows: 3,
|
||||
grid_cols: 3
|
||||
grid_cols: 3,
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -104,14 +104,14 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
grid_cols: 4
|
||||
grid_cols: 4,
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
name="Gallery with height=600"
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
height: 600
|
||||
height: 600,
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -119,7 +119,7 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
allow_preview: false
|
||||
allow_preview: false,
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -127,7 +127,7 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
preview: true
|
||||
preview: true,
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -135,7 +135,7 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
object_fit: "scale-down"
|
||||
object_fit: "scale-down",
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -143,7 +143,7 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
object_fit: "contain"
|
||||
object_fit: "contain",
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -151,7 +151,7 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
object_fit: "cover"
|
||||
object_fit: "cover",
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -159,7 +159,7 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
object_fit: "none"
|
||||
object_fit: "none",
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -167,7 +167,7 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
object_fit: "fill"
|
||||
object_fit: "fill",
|
||||
}}
|
||||
/>
|
||||
<Story
|
||||
@ -175,6 +175,24 @@
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
show_share_button: true
|
||||
show_share_button: true,
|
||||
}}
|
||||
/>
|
||||
|
||||
<Story
|
||||
name="Gallery with overflow of images"
|
||||
args={{
|
||||
label: "My Cheetah Gallery",
|
||||
show_label: true,
|
||||
grid_rows: 2,
|
||||
grid_cols: 2,
|
||||
height: 400,
|
||||
value: [
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/cheetah-002.jpg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/cheetah-003.jpg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
|
||||
"https://gradio-builds.s3.amazonaws.com/demo-files/cheetah-002.jpg",
|
||||
],
|
||||
}}
|
||||
/>
|
||||
|
@ -10,22 +10,22 @@
|
||||
export let label: string;
|
||||
export let root: string;
|
||||
export let root_url: null | string;
|
||||
export let elem_id: string = "";
|
||||
export let elem_classes: Array<string> = [];
|
||||
export let visible: boolean = true;
|
||||
export let elem_id = "";
|
||||
export let elem_classes: string[] = [];
|
||||
export let visible = true;
|
||||
export let value: (FileData | string | [FileData | string, string])[] | null =
|
||||
null;
|
||||
export let container: boolean = true;
|
||||
export let container = true;
|
||||
export let scale: number | null = null;
|
||||
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 grid_cols: number | number[] | undefined = [2];
|
||||
export let grid_rows: number | number[] | undefined = undefined;
|
||||
export let height: number | "auto" = "auto";
|
||||
export let preview: boolean;
|
||||
export let allow_preview: boolean = true;
|
||||
export let allow_preview = true;
|
||||
export let object_fit: "contain" | "cover" | "fill" | "none" | "scale-down" =
|
||||
"cover";
|
||||
export let show_share_button: boolean = false;
|
||||
export let show_share_button = false;
|
||||
</script>
|
||||
|
||||
<Block
|
||||
|
@ -11,7 +11,6 @@
|
||||
import { normalise_file } from "@gradio/upload";
|
||||
import { format_gallery_for_sharing } from "./utils";
|
||||
|
||||
export let container = true;
|
||||
export let show_label = true;
|
||||
export let label: string;
|
||||
export let root = "";
|
||||
@ -25,7 +24,7 @@
|
||||
export let allow_preview = true;
|
||||
export let object_fit: "contain" | "cover" | "fill" | "none" | "scale-down" =
|
||||
"cover";
|
||||
export let show_share_button: boolean = false;
|
||||
export let show_share_button = false;
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
select: SelectData;
|
||||
@ -74,6 +73,19 @@
|
||||
((selected_image ?? 0) + (_value?.length ?? 0) - 1) % (_value?.length ?? 0);
|
||||
$: next = ((selected_image ?? 0) + 1) % (_value?.length ?? 0);
|
||||
|
||||
function handle_preview_click(event: MouseEvent): void {
|
||||
const element = event.target as HTMLElement;
|
||||
const x = event.clientX;
|
||||
const width = element.offsetWidth;
|
||||
const centerX = width / 2;
|
||||
|
||||
if (x < centerX) {
|
||||
selected_image = previous;
|
||||
} else {
|
||||
selected_image = next;
|
||||
}
|
||||
}
|
||||
|
||||
function on_keydown(e: KeyboardEvent): void {
|
||||
switch (e.code) {
|
||||
case "Escape":
|
||||
@ -99,7 +111,7 @@
|
||||
if (selected_image !== null) {
|
||||
dispatch("select", {
|
||||
index: selected_image,
|
||||
value: _value?.[selected_image][1]
|
||||
value: _value?.[selected_image][1],
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -132,52 +144,18 @@
|
||||
|
||||
container_element?.scrollTo({
|
||||
left: pos < 0 ? 0 : pos,
|
||||
behavior: "smooth"
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
|
||||
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} />
|
||||
|
||||
{#if show_label}
|
||||
<BlockLabel
|
||||
{show_label}
|
||||
Icon={Image}
|
||||
label={label || "Gallery"}
|
||||
|
||||
/>
|
||||
<BlockLabel {show_label} Icon={Image} label={label || "Gallery"} />
|
||||
{/if}
|
||||
{#if value === null || _value === null || _value.length === 0}
|
||||
<Empty unpadded_box={true} size="large"><Image /></Empty>
|
||||
@ -191,7 +169,7 @@
|
||||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<img
|
||||
data-testid="detailed-image"
|
||||
on:click={() => (selected_image = next)}
|
||||
on:click={(event) => handle_preview_click(event)}
|
||||
src={_value[selected_image][0].data}
|
||||
alt={_value[selected_image][1] || ""}
|
||||
title={_value[selected_image][1] || null}
|
||||
@ -235,7 +213,7 @@
|
||||
>
|
||||
<div
|
||||
class="grid-container"
|
||||
style="{grid_cols_style} {grid_rows_style} --object-fit: {object_fit}; height: {height}"
|
||||
style="--grid-cols:{grid_cols}; --grid-rows:{grid_rows}; --object-fit: {object_fit}; height: {height};"
|
||||
class:pt-6={show_label}
|
||||
>
|
||||
{#if show_share_button}
|
||||
@ -374,41 +352,17 @@
|
||||
position: relative;
|
||||
padding: var(--size-2);
|
||||
height: var(--size-full);
|
||||
overflow-y: auto;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.grid-container {
|
||||
display: grid;
|
||||
position: relative;
|
||||
grid-template-rows: var(--grid-rows);
|
||||
grid-template-columns: var(--grid-cols);
|
||||
grid-template-rows: repeat(var(--grid-rows), minmax(100px, 1fr));
|
||||
grid-template-columns: repeat(var(--grid-cols), minmax(100px, 1fr));
|
||||
grid-auto-rows: minmax(100px, 1fr);
|
||||
gap: var(--spacing-lg);
|
||||
}
|
||||
@media (--screen-sm) {
|
||||
.grid-container {
|
||||
grid-template-columns: var(--sm-grid-cols);
|
||||
}
|
||||
}
|
||||
@media (--screen-md) {
|
||||
.grid-container {
|
||||
grid-template-columns: var(--md-grid-cols);
|
||||
}
|
||||
}
|
||||
@media (--screen-lg) {
|
||||
.grid-container {
|
||||
grid-template-columns: var(--lg-grid-cols);
|
||||
}
|
||||
}
|
||||
@media (--screen-xl) {
|
||||
.grid-container {
|
||||
grid-template-columns: var(--xl-grid-cols);
|
||||
}
|
||||
}
|
||||
@media (--screen-xxl) {
|
||||
.grid-container {
|
||||
grid-template-columns: var(--2xl-grid-cols);
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnail-lg > img {
|
||||
width: var(--size-full);
|
||||
|
Loading…
x
Reference in New Issue
Block a user