Add support for resizing columns on mobile

This commit is contained in:
Andrew Kingston 2024-04-17 11:55:44 +01:00
parent f8087f0fb3
commit c11139914f
5 changed files with 27 additions and 14 deletions

View File

@ -20,3 +20,10 @@ export const getColumnIcon = column => {
return result || "Text" return result || "Text"
} }
export const parseEventLocation = e => {
return {
x: e.clientX ?? e.touches?.[0]?.clientX,
y: e.clientY ?? e.touches?.[0]?.clientY,
}
}

View File

@ -33,6 +33,7 @@
class="resize-slider" class="resize-slider"
class:visible={activeColumn === column.name} class:visible={activeColumn === column.name}
on:mousedown={e => resize.actions.startResizing(column, e)} on:mousedown={e => resize.actions.startResizing(column, e)}
on:touchstart={e => resize.actions.startResizing(column, e)}
on:dblclick={() => resize.actions.resetSize(column)} on:dblclick={() => resize.actions.resetSize(column)}
style={getStyle(column, offset, $scrollLeft)} style={getStyle(column, offset, $scrollLeft)}
> >

View File

@ -2,6 +2,7 @@
import { getContext } from "svelte" import { getContext } from "svelte"
import { domDebounce } from "../../../utils/utils" import { domDebounce } from "../../../utils/utils"
import { DefaultRowHeight, ScrollBarSize } from "../lib/constants" import { DefaultRowHeight, ScrollBarSize } from "../lib/constants"
import { parseEventLocation } from "../lib/utils"
const { const {
scroll, scroll,
@ -53,17 +54,10 @@
} }
} }
const getLocation = e => {
return {
y: e.touches?.[0]?.clientY ?? e.clientY,
x: e.touches?.[0]?.clientX ?? e.clientX,
}
}
// V scrollbar drag handlers // V scrollbar drag handlers
const startVDragging = e => { const startVDragging = e => {
e.preventDefault() e.preventDefault()
initialMouse = getLocation(e).y initialMouse = parseEventLocation(e).y
initialScroll = $scrollTop initialScroll = $scrollTop
document.addEventListener("mousemove", moveVDragging) document.addEventListener("mousemove", moveVDragging)
document.addEventListener("touchmove", moveVDragging) document.addEventListener("touchmove", moveVDragging)
@ -73,7 +67,7 @@
closeMenu() closeMenu()
} }
const moveVDragging = domDebounce(e => { const moveVDragging = domDebounce(e => {
const delta = getLocation(e).y - initialMouse const delta = parseEventLocation(e).y - initialMouse
const weight = delta / availHeight const weight = delta / availHeight
const newScrollTop = initialScroll + weight * $maxScrollTop const newScrollTop = initialScroll + weight * $maxScrollTop
scroll.update(state => ({ scroll.update(state => ({
@ -92,7 +86,7 @@
// H scrollbar drag handlers // H scrollbar drag handlers
const startHDragging = e => { const startHDragging = e => {
e.preventDefault() e.preventDefault()
initialMouse = getLocation(e).x initialMouse = parseEventLocation(e).x
initialScroll = $scrollLeft initialScroll = $scrollLeft
document.addEventListener("mousemove", moveHDragging) document.addEventListener("mousemove", moveHDragging)
document.addEventListener("touchmove", moveHDragging) document.addEventListener("touchmove", moveHDragging)
@ -102,7 +96,7 @@
closeMenu() closeMenu()
} }
const moveHDragging = domDebounce(e => { const moveHDragging = domDebounce(e => {
const delta = getLocation(e).x - initialMouse const delta = parseEventLocation(e).x - initialMouse
const weight = delta / availWidth const weight = delta / availWidth
const newScrollLeft = initialScroll + weight * $maxScrollLeft const newScrollLeft = initialScroll + weight * $maxScrollLeft
scroll.update(state => ({ scroll.update(state => ({

View File

@ -1,4 +1,5 @@
import { get, writable, derived } from "svelte/store" import { get, writable, derived } from "svelte/store"
import { parseEventLocation } from "../lib/utils"
const reorderInitialState = { const reorderInitialState = {
sourceColumn: null, sourceColumn: null,
@ -85,7 +86,7 @@ export const createActions = context => {
// Callback when moving the mouse when reordering columns // Callback when moving the mouse when reordering columns
const onReorderMouseMove = e => { const onReorderMouseMove = e => {
// Immediately handle the current position // Immediately handle the current position
const x = e.clientX ?? e.touches?.[0]?.clientX const { x } = parseEventLocation(e)
reorder.update(state => ({ reorder.update(state => ({
...state, ...state,
latestX: x, latestX: x,

View File

@ -1,5 +1,6 @@
import { writable, get, derived } from "svelte/store" import { writable, get, derived } from "svelte/store"
import { MinColumnWidth, DefaultColumnWidth } from "../lib/constants" import { MinColumnWidth, DefaultColumnWidth } from "../lib/constants"
import { parseEventLocation } from "../lib/utils"
const initialState = { const initialState = {
initialMouseX: null, initialMouseX: null,
@ -24,6 +25,8 @@ export const createActions = context => {
// Starts resizing a certain column // Starts resizing a certain column
const startResizing = (column, e) => { const startResizing = (column, e) => {
const { x } = parseEventLocation(e)
// Prevent propagation to stop reordering triggering // Prevent propagation to stop reordering triggering
e.stopPropagation() e.stopPropagation()
ui.actions.blur() ui.actions.blur()
@ -39,7 +42,7 @@ export const createActions = context => {
width: column.width, width: column.width,
left: column.left, left: column.left,
initialWidth: column.width, initialWidth: column.width,
initialMouseX: e.clientX, initialMouseX: x,
column: column.name, column: column.name,
columnIdx, columnIdx,
}) })
@ -47,12 +50,16 @@ export const createActions = context => {
// Add mouse event listeners to handle resizing // Add mouse event listeners to handle resizing
document.addEventListener("mousemove", onResizeMouseMove) document.addEventListener("mousemove", onResizeMouseMove)
document.addEventListener("mouseup", stopResizing) document.addEventListener("mouseup", stopResizing)
document.addEventListener("touchmove", onResizeMouseMove)
document.addEventListener("touchend", stopResizing)
document.addEventListener("touchcancel", stopResizing)
} }
// Handler for moving the mouse to resize columns // Handler for moving the mouse to resize columns
const onResizeMouseMove = e => { const onResizeMouseMove = e => {
const { initialMouseX, initialWidth, width, columnIdx } = get(resize) const { initialMouseX, initialWidth, width, columnIdx } = get(resize)
const dx = e.clientX - initialMouseX const { x } = parseEventLocation(e)
const dx = x - initialMouseX
const newWidth = Math.round(Math.max(MinColumnWidth, initialWidth + dx)) const newWidth = Math.round(Math.max(MinColumnWidth, initialWidth + dx))
// Ignore small changes // Ignore small changes
@ -87,6 +94,9 @@ export const createActions = context => {
resize.set(initialState) resize.set(initialState)
document.removeEventListener("mousemove", onResizeMouseMove) document.removeEventListener("mousemove", onResizeMouseMove)
document.removeEventListener("mouseup", stopResizing) document.removeEventListener("mouseup", stopResizing)
document.removeEventListener("touchmove", onResizeMouseMove)
document.removeEventListener("touchend", stopResizing)
document.removeEventListener("touchcancel", stopResizing)
// Persist width if it changed // Persist width if it changed
if ($resize.width !== $resize.initialWidth) { if ($resize.width !== $resize.initialWidth) {