From 8624bdbbbf32405520714ff1d5567e53a13d443f Mon Sep 17 00:00:00 2001 From: didierfranc Date: Wed, 15 Jan 2025 18:02:36 +0100 Subject: [PATCH] feat: resizable columns --- src/lib/components/Table/Table.svelte | 51 ++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/lib/components/Table/Table.svelte b/src/lib/components/Table/Table.svelte index 702e169..0ddcb39 100644 --- a/src/lib/components/Table/Table.svelte +++ b/src/lib/components/Table/Table.svelte @@ -22,6 +22,10 @@ let sortedBy = $state(null); let sortDirection = $state<'asc' | 'desc'>('asc'); + let columnWidths = $state>({}); + let isResizing = $state(null); + let startX = $state(0); + let startWidth = $state(0); $effect(() => { sortedBy = null; @@ -61,19 +65,40 @@ sortDirection = 'asc'; } } + + function startResize(e: MouseEvent, columnName: string) { + isResizing = columnName; + startX = e.pageX; + startWidth = columnWidths[columnName] || 100; + window.addEventListener('mousemove', handleResize); + window.addEventListener('mouseup', stopResize); + } + + function handleResize(e: MouseEvent) { + if (!isResizing) return; + const width = startWidth + (e.pageX - startX); + columnWidths[isResizing] = Math.max(50, width); + } + + function stopResize() { + isResizing = null; + window.removeEventListener('mousemove', handleResize); + window.removeEventListener('mouseup', stopResize); + } {#each columns as { name, type }} - {/each} @@ -86,7 +111,10 @@ {@const isNumberType = type.toLowerCase().includes('int') || type.toLowerCase().includes('float')} {@const isDateType = type.toLowerCase().includes('date')} -
handleSort(name)}> + handleSort(name)}>
{name} ({type.replace(/Nullable\((.*)\)/, '$1')}) {#if sortedBy === name} {sortDirection === 'asc' ? '↑' : '↓'} {/if}
+
startResize(e, name)} />
+
{formatValue(value)}
@@ -107,7 +135,7 @@ cursor: default; position: relative; white-space: nowrap; - overflow: auto; + overflow: hidden; } .text-right { @@ -116,7 +144,7 @@ .th-content, .td-content { - overflow: auto; + overflow: hidden; white-space: nowrap; color: hsl(0deg 0% 80%); position: relative; @@ -148,6 +176,21 @@ border-bottom: 1px solid hsl(0deg 0% 12%); font-weight: 400; cursor: pointer; + user-select: none; + } + + .resize-handle { + position: absolute; + right: 0; + top: 0; + bottom: 0; + width: 4px; + cursor: col-resize; + background-color: transparent; + } + + .resize-handle:hover { + background-color: hsl(0deg 0% 30%); } table {