From 5af397a98ae5a1795f66197f54eafc23ef50c3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Zimbr=C3=B3n?= Date: Fri, 16 Feb 2024 14:29:17 -0600 Subject: [PATCH 1/5] feat(DataGrid): :sparkles: Add resizable columns Now you can set resizable columns or all columns resizable prop --- .../src/lib/actions/dragAndDrop.ts | 19 ++++- .../src/lib/actions/resizeColumn.ts | 58 ++++++++++++++ .../src/lib/components/Datagrid.svelte | 77 +++++++++++++++++-- .../src/lib/components/TextboxCell.svelte | 2 +- packages/svelte-datagrid/src/lib/types.ts | 1 + 5 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 packages/svelte-datagrid/src/lib/actions/resizeColumn.ts diff --git a/packages/svelte-datagrid/src/lib/actions/dragAndDrop.ts b/packages/svelte-datagrid/src/lib/actions/dragAndDrop.ts index 0ac828a..039938b 100644 --- a/packages/svelte-datagrid/src/lib/actions/dragAndDrop.ts +++ b/packages/svelte-datagrid/src/lib/actions/dragAndDrop.ts @@ -12,9 +12,23 @@ export const dragAndDrop: Action = ( { draggable, dragEnd, dragStart }: ActionParams = {} ) => { if (draggable) { - node.draggable = true; - node.addEventListener('dragstart', (e) => { + const div = e.target as HTMLElement; + const isRezisable = div.classList.contains('resizable'); + + if (isRezisable) { + const resizableWidth = parseInt( + window.getComputedStyle(div, '::after').width.replace('px', '') + ); + + const clickPosition = e.clientX - div.getBoundingClientRect().left; + + if (clickPosition >= div.offsetWidth - resizableWidth - 2) { + e.preventDefault(); + return; + } + } + dragStart && dragStart(e); node.classList.add('dragging'); }); @@ -27,7 +41,6 @@ export const dragAndDrop: Action = ( return { destroy() { - node.draggable = false; node.removeEventListener('dragstart', () => {}); node.removeEventListener('dragend', () => {}); } diff --git a/packages/svelte-datagrid/src/lib/actions/resizeColumn.ts b/packages/svelte-datagrid/src/lib/actions/resizeColumn.ts new file mode 100644 index 0000000..d99e3b9 --- /dev/null +++ b/packages/svelte-datagrid/src/lib/actions/resizeColumn.ts @@ -0,0 +1,58 @@ +import type { Action } from 'svelte/action'; + +interface ActionParams { + resizable?: boolean; + startResize?: () => void; + endResize?: () => void; + onResize?: (data: number) => void; +} + +export const reziseColumn: Action = ( + node, + { resizable, onResize, startResize, endResize }: ActionParams = {} +) => { + if (!resizable) return; + + let lastX = 0; + + const mouseMoveEvent = (e: MouseEvent) => { + if (!onResize) return; + if (e.clientX === lastX) return; + lastX = e.clientX; + onResize(lastX - node.getBoundingClientRect().left); + }; + + const mouseDownEvent = (e: MouseEvent) => { + if (e.button !== 0) { + return; + } + lastX = e.clientX; + + // get node width and style ::after + const nodeAfterWidth = parseInt( + window.getComputedStyle(node, ':after').width.replace('px', '') + ); + const clickPosition = e.clientX - node.getBoundingClientRect().left; + + if (clickPosition < node.offsetWidth - nodeAfterWidth - 2) return; + + startResize && startResize(); + + document.addEventListener('mousemove', mouseMoveEvent); + document.addEventListener('mouseup', mouseUpEvent); + }; + + const mouseUpEvent = () => { + endResize && endResize(); + document.removeEventListener('mousemove', mouseMoveEvent); + }; + + node.addEventListener('mousedown', mouseDownEvent); + + return { + destroy() { + document.removeEventListener('mousedown', mouseDownEvent); + node.removeEventListener('mouseup', () => mouseUpEvent); + } + }; +}; diff --git a/packages/svelte-datagrid/src/lib/components/Datagrid.svelte b/packages/svelte-datagrid/src/lib/components/Datagrid.svelte index ce58bec..fec02cc 100644 --- a/packages/svelte-datagrid/src/lib/components/Datagrid.svelte +++ b/packages/svelte-datagrid/src/lib/components/Datagrid.svelte @@ -1,4 +1,6 @@ @@ -145,6 +147,7 @@ on:valueUpdated={onValueUpdated} on:scroll={gridScrolled} on:columnsSwapped={({ detail }) => console.log(detail)} + {allColumnsResizable} /> @@ -175,6 +178,10 @@
+