Skip to content

Commit

Permalink
Update gr.Dataframe UI with action popover (#9575)
Browse files Browse the repository at this point in the history
* add dialog for actions

* add changeset

* add story

* add changeset

* * remove temp select column
* change open dialog UX in mobile

* fix border

* fix test

---------

Co-authored-by: gradio-pr-bot <[email protected]>
  • Loading branch information
hannahblair and gradio-pr-bot authored Oct 8, 2024
1 parent 4617e60 commit 4ec2feb
Show file tree
Hide file tree
Showing 6 changed files with 313 additions and 96 deletions.
7 changes: 7 additions & 0 deletions .changeset/large-buttons-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@gradio/core": minor
"@gradio/dataframe": minor
"gradio": minor
---

feat:Update gr.Dataframe UI with action popover
8 changes: 6 additions & 2 deletions js/core/src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@
},
"dataframe": {
"incorrect_format": "Incorrect format, only CSV and TSV files are supported",
"new_column": "New column",
"new_row": "New row"
"new_column": "Add column",
"new_row": "New row",
"add_row_above": "Add row above",
"add_row_below": "Add row below",
"add_column_left": "Add column to the left",
"add_column_right": "Add column to the right"
},
"dropdown": {
"dropdown": "Dropdown"
Expand Down
31 changes: 30 additions & 1 deletion js/dataframe/Dataframe.stories.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<script lang="ts">
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import Table from "./shared/Table.svelte";
import { within } from "@testing-library/dom";
import { userEvent } from "@storybook/test";
import { get } from "svelte/store";
import { format } from "svelte-i18n";
</script>

<Meta
Expand All @@ -17,7 +21,7 @@
/>

<Template let:args>
<Table {...args} i18n={(s) => s} />
<Table {...args} i18n={get(format)} />
</Template>

<Story
Expand Down Expand Up @@ -161,3 +165,28 @@
editable: false
}}
/>

<Story
name="Dataframe with dialog interactions"
args={{
values: [
[800, 100, 400],
[200, 800, 700]
],
col_count: [3, "dynamic"],
row_count: [2, "dynamic"],
headers: ["Math", "Reading", "Writing"],
editable: true
}}
play={async ({ canvasElement }) => {
const canvas = within(canvasElement);

const cell = canvas.getByText("200");
userEvent.click(cell);
const open_dialog_btn = canvas.getAllByText("");
await userEvent.click(open_dialog_btn[0]);

const add_row_btn = canvas.getByText("Add row above");
await userEvent.click(add_row_btn);
}}
/>
10 changes: 10 additions & 0 deletions js/dataframe/shared/Arrow.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script lang="ts">
export let transform: string;
</script>

<svg viewBox="0 0 24 24" width="16" height="16">
<path
d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"
{transform}
/>
</svg>
108 changes: 108 additions & 0 deletions js/dataframe/shared/CellMenu.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<script lang="ts">
import { onMount } from "svelte";
import Arrow from "./Arrow.svelte";
import type { I18nFormatter } from "js/utils/src";
export let x: number;
export let y: number;
export let on_add_row_above: (index: number) => void;
export let on_add_row_below: (index: number) => void;
export let on_add_column_left: (index: number) => void;
export let on_add_column_right: (index: number) => void;
export let row: number;
export let col: number;
export let i18n: I18nFormatter;
let menu_element: HTMLDivElement;
onMount(() => {
position_menu();
});
function position_menu(): void {
if (!menu_element) return;
const viewport_width = window.innerWidth;
const viewport_height = window.innerHeight;
const menu_rect = menu_element.getBoundingClientRect();
let new_x = x - 30;
let new_y = y - 20;
if (new_x + menu_rect.width > viewport_width) {
new_x = x - menu_rect.width + 10;
}
if (new_y + menu_rect.height > viewport_height) {
new_y = y - menu_rect.height + 10;
}
menu_element.style.left = `${new_x}px`;
menu_element.style.top = `${new_y}px`;
}
</script>

<div bind:this={menu_element} class="cell-menu">
<button on:click={() => on_add_row_above(row)}>
<Arrow transform="rotate(-90 12 12)" />
{i18n("dataframe.add_row_above")}
</button>
<button on:click={() => on_add_row_below(row)}>
<Arrow transform="rotate(90 12 12)" />
{i18n("dataframe.add_row_below")}
</button>
<button on:click={() => on_add_column_left(col)}>
<Arrow transform="rotate(180 12 12)" />
{i18n("dataframe.add_column_left")}
</button>
<button on:click={() => on_add_column_right(col + 1)}>
<Arrow transform="rotate(0 12 12)" />
{i18n("dataframe.add_column_right")}
</button>
</div>

<style>
.cell-menu {
position: fixed;
z-index: var(--layer-2);
background: var(--background-fill-primary);
border: 1px solid var(--border-color-primary);
border-radius: var(--radius-sm);
padding: var(--size-1);
display: flex;
flex-direction: column;
gap: var(--size-1);
box-shadow: var(--shadow-drop-lg);
min-width: 150px;
}
.cell-menu button {
background: none;
border: none;
cursor: pointer;
text-align: left;
padding: var(--size-1) var(--size-2);
border-radius: var(--radius-sm);
color: var(--body-text-color);
font-size: var(--text-sm);
transition:
background-color 0.2s,
color 0.2s;
display: flex;
align-items: center;
gap: var(--size-2);
}
.cell-menu button:hover {
background-color: var(--background-fill-secondary);
}
.cell-menu button :global(svg) {
fill: currentColor;
transition: fill 0.2s;
}
.cell-menu button:hover :global(svg) {
fill: var(--color-accent);
}
</style>
Loading

0 comments on commit 4ec2feb

Please sign in to comment.