CoolFace
Datasetpublic

gradio/frontend

sourceHugging Faceupdated 1d agoView on Hugging Face
1likes442kdownloads
TableCell.svelte331 linesDownload Raw Back to shared
1<script lang="ts">2	import EditableCell from "./EditableCell.svelte";3	import CellMenuButton from "./CellMenuButton.svelte";4	import type { I18nFormatter } from "js/core/src/gradio_helper";5	import type { Datatype } from "./utils/utils";6	import type { CellValue } from "./types";7	import { is_cell_in_selection } from "./utils/selection_utils";8 9	export let value: CellValue;10	export let index: number;11	export let j: number;12	export let actual_pinned_columns: number;13	export let get_cell_width: (index: number) => string;14	export let handle_cell_click: (15		event: MouseEvent,16		row: number,17		col: number18	) => void;19	export let handle_blur: (20		event: CustomEvent<{21			blur_event: FocusEvent;22			coords: [number, number];23		}>24	) => void;25	export let toggle_cell_menu: (26		event: MouseEvent,27		row: number,28		col: number29	) => void;30	export let is_cell_selected: (31		coords: [number, number],32		selected_cells: [number, number][]33	) => string;34	export let should_show_cell_menu: (35		coords: [number, number],36		selected_cells: [number, number][],37		editable: boolean38	) => boolean;39	export let selected_cells: [number, number][];40	export let copy_flash: boolean;41	export let active_cell_menu: {42		row: number;43		col: number;44		x: number;45		y: number;46	} | null;47	export let styling: string | undefined;48	export let latex_delimiters: {49		left: string;50		right: string;51		display: boolean;52	}[];53	export let line_breaks: boolean;54	export let datatype: Datatype;55	export let editing: [number, number] | false;56	export let max_chars: number | undefined;57	export let editable: boolean;58	export let is_static = false;59	export let i18n: I18nFormatter;60	export let components: Record<string, any> = {};61	export let el: {62		cell: HTMLTableCellElement | null;63		input: HTMLTextAreaElement | null;64	};65	export let handle_select_column: (col: number) => void;66	export let handle_select_row: (row: number) => void;67	export let is_dragging: boolean;68	export let display_value: string | undefined;69	export let wrap = false;70 71	function get_cell_position(col_index: number): string {72		if (col_index >= actual_pinned_columns) {73			return "auto";74		}75 76		if (col_index === 0) {77			return "0";78		}79 80		const previous_widths = Array(col_index)81			.fill(0)82			.map((_, idx) => {83				return get_cell_width(idx);84			})85			.join(" + ");86 87		return `calc(${previous_widths})`;88	}89 90	$: cell_classes = is_cell_selected([index, j], selected_cells || []);91	$: is_in_selection = is_cell_in_selection([index, j], selected_cells);92	$: has_no_top = cell_classes.includes("no-top");93	$: has_no_bottom = cell_classes.includes("no-bottom");94	$: has_no_left = cell_classes.includes("no-left");95	$: has_no_right = cell_classes.includes("no-right");96</script>97 98<td99	class:pinned-column={j < actual_pinned_columns}100	class:last-pinned={j === actual_pinned_columns - 1}101	tabindex={j < actual_pinned_columns ? -1 : 0}102	bind:this={el.cell}103	data-row={index}104	data-col={j}105	data-testid={`cell-${index}-${j}`}106	on:mousedown={(e) => handle_cell_click(e, index, j)}107	on:contextmenu|preventDefault={(e) => toggle_cell_menu(e, index, j)}108	style="width: {get_cell_width(j)}; left: {get_cell_position(j)}; {styling ||109		''}"110	class:flash={copy_flash && is_in_selection}111	class:cell-selected={is_in_selection}112	class:no-top={has_no_top}113	class:no-bottom={has_no_bottom}114	class:no-left={has_no_left}115	class:no-right={has_no_right}116	class:menu-active={active_cell_menu &&117		active_cell_menu.row === index &&118		active_cell_menu.col === j}119	class:dragging={is_dragging}120>121	<div class="cell-wrap">122		<EditableCell123			bind:value124			bind:el={el.input}125			display_value={display_value !== undefined126				? display_value127				: String(value)}128			{latex_delimiters}129			{line_breaks}130			{editable}131			{is_static}132			edit={editing && editing[0] === index && editing[1] === j}133			{datatype}134			on:focus={() => {135				const row = index;136				const col = j;137				if (!selected_cells.some(([r, c]) => r === row && c === col)) {138					selected_cells = [[row, col]];139				}140			}}141			on:blur={handle_blur}142			{max_chars}143			{i18n}144			{components}145			show_selection_buttons={selected_cells.length === 1 &&146				selected_cells[0][0] === index &&147				selected_cells[0][1] === j}148			coords={[index, j]}149			on_select_column={handle_select_column}150			on_select_row={handle_select_row}151			{is_dragging}152			wrap_text={wrap}153		/>154		{#if editable && should_show_cell_menu([index, j], selected_cells, editable)}155			<CellMenuButton on_click={(event) => toggle_cell_menu(event, index, j)} />156		{/if}157	</div>158</td>159 160<style>161	td {162		--ring-color: transparent;163		position: relative;164		outline: none;165		box-shadow: inset 0 0 0 1px var(--ring-color);166		padding: 0;167		border-right-width: 0px;168		border-left-width: 1px;169		border-style: solid;170		border-color: var(--border-color-primary);171	}172 173	.cell-wrap {174		display: flex;175		align-items: center;176		justify-content: flex-start;177		outline: none;178		min-height: var(--size-9);179		position: relative;180		height: 100%;181		padding: var(--size-2);182		box-sizing: border-box;183		margin: 0;184		gap: var(--size-1);185		overflow: visible;186		min-width: 0;187		border-radius: var(--table-radius);188	}189 190	.cell-selected {191		--ring-color: var(--color-accent);192		box-shadow: inset 0 0 0 2px var(--ring-color);193		z-index: 2;194		position: relative;195	}196 197	.cell-selected :global(.cell-menu-button) {198		display: flex;199	}200 201	.flash.cell-selected {202		animation: flash-color 700ms ease-out;203	}204 205	@keyframes flash-color {206		0%,207		30% {208			background: var(--color-accent-copied);209		}210 211		100% {212			background: transparent;213		}214	}215 216	.pinned-column {217		position: sticky;218		z-index: 3;219		border-right: none;220	}221 222	.pinned-column:nth-child(odd) {223		background: var(--table-odd-background-fill);224	}225 226	.pinned-column:nth-child(even) {227		background: var(--table-even-background-fill);228	}229 230	td:first-child {231		border-left-width: 0px;232	}233 234	:global(tr:last-child) td:first-child {235		border-bottom-left-radius: var(--table-radius);236	}237 238	:global(tr:last-child) td:last-child {239		border-bottom-right-radius: var(--table-radius);240	}241 242	.dragging {243		cursor: crosshair;244	}245 246	/* Add back the cell selection border styles */247	.cell-selected.no-top {248		box-shadow:249			inset 2px 0 0 var(--ring-color),250			inset -2px 0 0 var(--ring-color),251			inset 0 -2px 0 var(--ring-color);252	}253 254	.cell-selected.no-bottom {255		box-shadow:256			inset 2px 0 0 var(--ring-color),257			inset -2px 0 0 var(--ring-color),258			inset 0 2px 0 var(--ring-color);259	}260 261	.cell-selected.no-left {262		box-shadow:263			inset 0 2px 0 var(--ring-color),264			inset -2px 0 0 var(--ring-color),265			inset 0 -2px 0 var(--ring-color);266	}267 268	.cell-selected.no-right {269		box-shadow:270			inset 0 2px 0 var(--ring-color),271			inset 2px 0 0 var(--ring-color),272			inset 0 -2px 0 var(--ring-color);273	}274 275	.cell-selected.no-top.no-left {276		box-shadow:277			inset -2px 0 0 var(--ring-color),278			inset 0 -2px 0 var(--ring-color);279	}280 281	.cell-selected.no-top.no-right {282		box-shadow:283			inset 2px 0 0 var(--ring-color),284			inset 0 -2px 0 var(--ring-color);285	}286 287	.cell-selected.no-bottom.no-left {288		box-shadow:289			inset -2px 0 0 var(--ring-color),290			inset 0 2px 0 var(--ring-color);291	}292 293	.cell-selected.no-bottom.no-right {294		box-shadow:295			inset 2px 0 0 var(--ring-color),296			inset 0 2px 0 var(--ring-color);297	}298 299	.cell-selected.no-top.no-bottom {300		box-shadow:301			inset 2px 0 0 var(--ring-color),302			inset -2px 0 0 var(--ring-color);303	}304 305	.cell-selected.no-left.no-right {306		box-shadow:307			inset 0 2px 0 var(--ring-color),308			inset 0 -2px 0 var(--ring-color);309	}310 311	.cell-selected.no-top.no-left.no-right {312		box-shadow: inset 0 -2px 0 var(--ring-color);313	}314 315	.cell-selected.no-bottom.no-left.no-right {316		box-shadow: inset 0 2px 0 var(--ring-color);317	}318 319	.cell-selected.no-left.no-top.no-bottom {320		box-shadow: inset -2px 0 0 var(--ring-color);321	}322 323	.cell-selected.no-right.no-top.no-bottom {324		box-shadow: inset 2px 0 0 var(--ring-color);325	}326 327	.cell-selected.no-top.no-bottom.no-left.no-right {328		box-shadow: none;329	}330</style>331 
gradio/frontend · CoolFace