diff --git a/packages/frontend-core/src/components/grid/layout/GridBody.svelte b/packages/frontend-core/src/components/grid/layout/GridBody.svelte index bbd36a0e6d..762985a4db 100644 --- a/packages/frontend-core/src/components/grid/layout/GridBody.svelte +++ b/packages/frontend-core/src/components/grid/layout/GridBody.svelte @@ -35,7 +35,7 @@
- + {#each $renderedRows as row, idx} { e.preventDefault() - debouncedHandleWheel(e.deltaX, e.deltaY, e.clientY) + updateScroll(e.deltaX, e.deltaY, e.clientY) // If a context menu was visible, hide it if ($menu.visible) { menu.actions.close() } } - const debouncedHandleWheel = domDebounce((deltaX, deltaY, clientY) => { + + // Handles touch start events + const handleTouchStart = e => { + if (!e.touches?.[0]) return + initialTouchX = e.touches[0].clientX + initialTouchY = e.touches[0].clientY + } + + // Handles touch move events and updates scroll state + const handleTouchMove = e => { + if (!e.touches?.[0]) return + e.preventDefault() + + // Compute delta from previous event, and update scroll + const deltaX = initialTouchX - e.touches[0].clientX + const deltaY = initialTouchY - e.touches[0].clientY + updateScroll(deltaX, deltaY) + + // Store position to reference in next event + initialTouchX = e.touches[0].clientX + initialTouchY = e.touches[0].clientY + + // If a context menu was visible, hide it + if ($menu.visible) { + menu.actions.close() + } + } + + // Updates the scroll offset by a certain delta, and ensure scrolling + // stays within sensible bounds. Debounced for performance. + const updateScroll = domDebounce((deltaX, deltaY, clientY) => { const { top, left } = $scroll // Calculate new scroll top @@ -55,15 +89,19 @@ }) // Hover row under cursor - const y = clientY - $bounds.top + (newScrollTop % $rowHeight) - const hoveredRow = $renderedRows[Math.floor(y / $rowHeight)] - hoveredRowId.set(hoveredRow?._id) + if (clientY != null) { + const y = clientY - $bounds.top + (newScrollTop % $rowHeight) + const hoveredRow = $renderedRows[Math.floor(y / $rowHeight)] + hoveredRowId.set(hoveredRow?._id) + } })
($focusedCellId = null)} >
diff --git a/packages/frontend-core/src/components/grid/layout/NewRow.svelte b/packages/frontend-core/src/components/grid/layout/NewRow.svelte index 6a926ca02c..7a1aed14ba 100644 --- a/packages/frontend-core/src/components/grid/layout/NewRow.svelte +++ b/packages/frontend-core/src/components/grid/layout/NewRow.svelte @@ -205,7 +205,7 @@ {/if}
- +
{#each $renderedColumns as column, columnIdx} {@const cellId = `new-${column.name}`} diff --git a/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte b/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte index 9f38841f7a..82b29f1535 100644 --- a/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte +++ b/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte @@ -64,7 +64,7 @@
($hoveredRowId = null)}> - + {#each $renderedRows as row, idx} {@const rowSelected = !!$selectedRows[row._id]} {@const rowHovered = $hoveredRowId === row._id} diff --git a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte index 315c3d21e5..ad9cb78808 100644 --- a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte @@ -53,18 +53,27 @@ } } + const getLocation = e => { + return { + y: e.touches?.[0]?.clientY ?? e.clientY, + x: e.touches?.[0]?.clientX ?? e.clientX, + } + } + // V scrollbar drag handlers const startVDragging = e => { e.preventDefault() - initialMouse = e.clientY + initialMouse = getLocation(e).y initialScroll = $scrollTop document.addEventListener("mousemove", moveVDragging) + document.addEventListener("touchmove", moveVDragging) document.addEventListener("mouseup", stopVDragging) + document.addEventListener("touchend", stopVDragging) isDraggingV = true closeMenu() } const moveVDragging = domDebounce(e => { - const delta = e.clientY - initialMouse + const delta = getLocation(e).y - initialMouse const weight = delta / availHeight const newScrollTop = initialScroll + weight * $maxScrollTop scroll.update(state => ({ @@ -74,22 +83,26 @@ }) const stopVDragging = () => { document.removeEventListener("mousemove", moveVDragging) + document.removeEventListener("touchmove", moveVDragging) document.removeEventListener("mouseup", stopVDragging) + document.removeEventListener("touchend", stopVDragging) isDraggingV = false } // H scrollbar drag handlers const startHDragging = e => { e.preventDefault() - initialMouse = e.clientX + initialMouse = getLocation(e).x initialScroll = $scrollLeft document.addEventListener("mousemove", moveHDragging) + document.addEventListener("touchmove", moveHDragging) document.addEventListener("mouseup", stopHDragging) + document.addEventListener("touchend", stopHDragging) isDraggingH = true closeMenu() } const moveHDragging = domDebounce(e => { - const delta = e.clientX - initialMouse + const delta = getLocation(e).x - initialMouse const weight = delta / availWidth const newScrollLeft = initialScroll + weight * $maxScrollLeft scroll.update(state => ({ @@ -99,7 +112,9 @@ }) const stopHDragging = () => { document.removeEventListener("mousemove", moveHDragging) + document.removeEventListener("touchmove", moveHDragging) document.removeEventListener("mouseup", stopHDragging) + document.removeEventListener("touchend", stopHDragging) isDraggingH = false } @@ -109,6 +124,7 @@ class="v-scrollbar" style="--size:{ScrollBarSize}px; top:{barTop}px; height:{barHeight}px;" on:mousedown={startVDragging} + on:touchstart={startVDragging} class:dragging={isDraggingV} /> {/if} @@ -117,6 +133,7 @@ class="h-scrollbar" style="--size:{ScrollBarSize}px; left:{barLeft}px; width:{barWidth}px;" on:mousedown={startHDragging} + on:touchstart={startHDragging} class:dragging={isDraggingH} /> {/if}