Skip to content

Commit

Permalink
Tweak gr.Dataframe menu UX (#9601)
Browse files Browse the repository at this point in the history
* * show menu on click
* only show column options in headers

* improve spacing

* add changeset

* fix type check

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
  • Loading branch information
hannahblair and gradio-pr-bot authored Oct 9, 2024
1 parent 6c7a490 commit c078892
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 56 deletions.
6 changes: 6 additions & 0 deletions .changeset/heavy-memes-create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@gradio/dataframe": minor
"gradio": minor
---

feat:Tweak gr.Dataframe menu UX
33 changes: 18 additions & 15 deletions js/dataframe/shared/CellMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
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 on_add_row_above: () => void;
export let on_add_row_below: () => void;
export let on_add_column_left: () => void;
export let on_add_column_right: () => void;
export let row: number;
export let col: number;
export let i18n: I18nFormatter;
let menu_element: HTMLDivElement;
$: is_header = row === -1;
onMount(() => {
position_menu();
});
Expand Down Expand Up @@ -43,19 +44,21 @@
</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)}>
{#if !is_header}
<button on:click={() => on_add_row_above()}>
<Arrow transform="rotate(-90 12 12)" />
{i18n("dataframe.add_row_above")}
</button>
<button on:click={() => on_add_row_below()}>
<Arrow transform="rotate(90 12 12)" />
{i18n("dataframe.add_row_below")}
</button>
{/if}
<button on:click={() => on_add_column_left()}>
<Arrow transform="rotate(180 12 12)" />
{i18n("dataframe.add_column_left")}
</button>
<button on:click={() => on_add_column_right(col + 1)}>
<button on:click={() => on_add_column_right()}>
<Arrow transform="rotate(0 12 12)" />
{i18n("dataframe.add_column_right")}
</button>
Expand Down
192 changes: 151 additions & 41 deletions js/dataframe/shared/Table.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -460,10 +460,13 @@
function handle_click_outside(event: Event): void {
if (
active_cell_menu &&
!(event.target as HTMLElement).closest(".cell-menu")
(active_cell_menu &&
!(event.target as HTMLElement).closest(".cell-menu")) ||
(active_header_menu &&
!(event.target as HTMLElement).closest(".cell-menu"))
) {
active_cell_menu = null;
active_header_menu = null;
}
event.stopImmediatePropagation();
Expand All @@ -477,6 +480,8 @@
selected_header = false;
selected = false;
active_cell = null;
active_cell_menu = null;
active_header_menu = null;
}
function guess_delimitaor(
Expand Down Expand Up @@ -690,12 +695,14 @@
const row_index = position === "above" ? index : index + 1;
add_row(row_index);
active_cell_menu = null;
active_header_menu = null;
}
function add_col_at(index: number, position: "left" | "right"): void {
const col_index = position === "left" ? index : index + 1;
add_col(col_index);
active_cell_menu = null;
active_header_menu = null;
}
onMount(() => {
Expand All @@ -704,6 +711,55 @@
document.removeEventListener("click", handle_click_outside);
};
});
let active_button: {
type: "header" | "cell";
row?: number;
col: number;
} | null = null;
function toggle_header_button(col: number): void {
if (active_button?.type === "header" && active_button.col === col) {
active_button = null;
} else {
active_button = { type: "header", col };
}
}
function toggle_cell_button(row: number, col: number): void {
if (
active_button?.type === "cell" &&
active_button.row === row &&
active_button.col === col
) {
active_button = null;
} else {
active_button = { type: "cell", row, col };
}
}
let active_header_menu: {
col: number;
x: number;
y: number;
} | null = null;
function toggle_header_menu(event: MouseEvent, col: number): void {
event.stopPropagation();
if (active_header_menu && active_header_menu.col === col) {
active_header_menu = null;
} else {
const header = (event.target as HTMLElement).closest("th");
if (header) {
const rect = header.getBoundingClientRect();
active_header_menu = {
col,
x: rect.right,
y: rect.bottom
};
}
}
}
</script>

<svelte:window
Expand Down Expand Up @@ -822,40 +878,58 @@
class:focus={header_edit === i || selected_header === i}
aria-sort={get_sort_status(value, sort_by, sort_direction)}
style="width: var(--cell-width-{i});"
on:click={() => {
toggle_header_button(i);
}}
>
<div class="cell-wrap">
<EditableCell
bind:value={_headers[i].value}
bind:el={els[id].input}
{latex_delimiters}
{line_breaks}
edit={header_edit === i}
on:keydown={end_header_edit}
on:dblclick={() => edit_header(i)}
{select_on_focus}
header
{root}
/>

<!-- TODO: fix -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions-->
<div
class:sorted={sort_by === i}
class:des={sort_by === i && sort_direction === "des"}
class="sort-button {sort_direction} "
on:click={() => handle_sort(i)}
>
<svg
width="1em"
height="1em"
viewBox="0 0 9 7"
fill="none"
xmlns="http://www.w3.org/2000/svg"
<div class="header-content">
<EditableCell
bind:value={_headers[i].value}
bind:el={els[id].input}
{latex_delimiters}
{line_breaks}
edit={header_edit === i}
on:keydown={end_header_edit}
on:dblclick={() => edit_header(i)}
{select_on_focus}
header
{root}
/>
<!-- TODO: fix -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions-->
<div
class:sorted={sort_by === i}
class:des={sort_by === i && sort_direction === "des"}
class="sort-button {sort_direction}"
on:click={(event) => {
event.stopPropagation();
handle_sort(i);
}}
>
<path d="M4.49999 0L8.3971 6.75H0.602875L4.49999 0Z" />
</svg>
<svg
width="1em"
height="1em"
viewBox="0 0 9 7"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M4.49999 0L8.3971 6.75H0.602875L4.49999 0Z" />
</svg>
</div>
</div>

{#if editable}
<button
class="cell-menu-button"
class:visible={active_button?.type === "header" &&
active_button.col === i}
on:click={(event) => toggle_header_menu(event, i)}
>
</button>
{/if}
</div>
</th>
{/each}
Expand All @@ -866,7 +940,10 @@
<td
tabindex="0"
on:touchstart={() => start_edit(index, j)}
on:click={() => handle_cell_click(index, j)}
on:click={() => {
handle_cell_click(index, j);
toggle_cell_button(index, j);
}}
on:dblclick={() => start_edit(index, j)}
style:width="var(--cell-width-{j})"
style={styling?.[index]?.[j] || ""}
Expand All @@ -892,9 +969,9 @@
{#if editable}
<button
class="cell-menu-button"
class:visible={active_cell &&
active_cell.row === index &&
active_cell.col === j}
class:visible={active_button?.type === "cell" &&
active_button.row === index &&
active_button.col === j}
on:click={(event) => toggle_cell_menu(event, index, j)}
>
Expand Down Expand Up @@ -923,6 +1000,19 @@
/>
{/if}

{#if active_header_menu !== null}
<CellMenu
{i18n}
x={active_header_menu.x}
y={active_header_menu.y}
col={active_header_menu.col}
row={-1}
on_add_column_left={() => add_col_at(active_header_menu?.col ?? -1, "left")}
on_add_column_right={() =>
add_col_at(active_header_menu?.col ?? -1, "right")}
/>
{/if}

<style>
.button-wrap:hover svg {
color: var(--color-accent);
Expand Down Expand Up @@ -1077,9 +1167,19 @@
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
outline: none;
height: var(--size-full);
min-height: var(--size-9);
overflow: hidden;
}
.header-content {
display: flex;
align-items: center;
overflow: hidden;
flex-grow: 1;
min-width: 0;
}
.row_odd {
Expand All @@ -1102,11 +1202,15 @@
}
.cell-menu-button {
flex-shrink: 0;
display: none;
background-color: var(--block-background-fill);
border: 1px solid var(--border-color-primary);
border-radius: var(--block-radius);
width: var(--size-5);
height: var(--size-5);
min-width: var(--size-5);
padding: 0;
margin-right: var(--spacing-sm);
z-index: var(--layer-2);
}
Expand All @@ -1116,12 +1220,18 @@
}
.cell-menu-button.visible {
display: block;
display: flex;
align-items: center;
justify-content: center;
}
@media (hover: hover) {
.cell-wrap:hover .cell-menu-button {
display: block;
}
th .cell-wrap {
padding-right: var(--spacing-sm);
}
th .header-content {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

0 comments on commit c078892

Please sign in to comment.