Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
inference-widgets
/
packages
/widgets
/src
/lib
/components
/InferenceWidget
/shared
/WidgetTableInput
/WidgetTableInput.svelte
<script lang="ts"> | |
import type { HighlightCoordinates } from "../types.js"; | |
import { onMount, tick } from "svelte"; | |
import { scrollToMax } from "../../../../utils/ViewUtils.js"; | |
import IconRow from "../../..//Icons/IconRow.svelte"; | |
export let onChange: (table: (string | number)[][]) => void; | |
export let highlighted: HighlightCoordinates; | |
export let table: (string | number)[][] = [[]]; | |
export let canAddRow = true; | |
export let canAddCol = true; | |
export let isLoading = false; | |
export let isDisabled = false; | |
let initialTable: (string | number)[][] = [[]]; | |
let tableContainerEl: HTMLElement; | |
onMount(() => { | |
initialTable = table.map((row) => row.map((cell) => cell)); | |
}); | |
async function addCol() { | |
const updatedTable = table.map((row, colIndex) => [...row, colIndex === 0 ? `Header ${table[0].length + 1}` : ""]); | |
onChange(updatedTable); | |
await scrollTableToRight(); | |
} | |
export async function scrollTableToRight(): Promise<void> { | |
await tick(); | |
scrollToMax(tableContainerEl, "x"); | |
} | |
function addRow() { | |
const updatedTable = [...table, Array(table[0].length).fill("")]; | |
onChange(updatedTable); | |
} | |
function editCell(e: Event, [x, y]: [number, number]) { | |
const value = (e.target as HTMLElement)?.innerText; | |
const updatedTable = table.map((row, rowIndex) => | |
rowIndex === y ? row.map((col, colIndex) => (colIndex === x ? value : col)) : row | |
); | |
onChange(updatedTable); | |
} | |
function onKeyDown(e: KeyboardEvent) { | |
if (e.code === "Enter") { | |
(e.target as HTMLElement)?.blur(); | |
} | |
} | |
function resetTable() { | |
const updatedTable = initialTable; | |
onChange(updatedTable); | |
} | |
</script> | |
<div class="overflow-auto" bind:this={tableContainerEl}> | |
{#if table.length > 1} | |
<table class="table-question-answering"> | |
<thead> | |
<tr> | |
{#each table[0] as header, x} | |
<th | |
contenteditable={canAddCol && !isLoading && !isDisabled} | |
class="h-6 border-2 border-gray-100" | |
on:keydown={onKeyDown} | |
on:input={(e) => editCell(e, [x, 0])} | |
> | |
{header} | |
</th> | |
{/each} | |
</tr> | |
</thead> | |
<tbody> | |
{#each table.slice(1) as row, y} | |
<tr class={highlighted[`${y}`] ?? "bg-white"}> | |
{#each row as cell, x} | |
<td | |
class={(highlighted[`${y}-${x}`] ?? "border-gray-100") + " h-6 border-2"} | |
contenteditable={!isLoading && !isDisabled} | |
on:keydown={onKeyDown} | |
on:input={(e) => editCell(e, [x, y + 1])}>{cell}</td | |
> | |
{/each} | |
</tr> | |
{/each} | |
</tbody> | |
</table> | |
{/if} | |
</div> | |
<div class="mb-1 flex flex-wrap"> | |
{#if canAddRow} | |
<button class="btn-widget mt-2 mr-1.5 flex-1 lg:flex-none" on:click={addRow} type="button"> | |
<IconRow classNames="mr-2" /> | |
Add row | |
</button> | |
{/if} | |
{#if canAddCol} | |
<button class="btn-widget mt-2 flex-1 lg:mr-1.5 lg:flex-none" on:click={addCol} type="button"> | |
<IconRow classNames="transform rotate-90 mr-1" /> | |
Add col | |
</button> | |
{/if} | |
<button class="btn-widget mt-2 flex-1 lg:ml-auto lg:flex-none" on:click={resetTable} type="button"> | |
Reset table | |
</button> | |
</div> | |