From ccc89379da60d6de7ddd70a8c82236255d51c94e Mon Sep 17 00:00:00 2001 From: Jakob Hjelmer Nielsen Date: Tue, 10 Dec 2019 14:39:02 +0100 Subject: [PATCH] .add touch events to useResizeColumns (#1748) .add onTouchStart to mergeProps .add touch-action css to resizer .mod increase resizer width or it is very hard to activate using touch devices --- .size-snapshot.json | 19 +++++++ examples/column-resizing/src/App.js | 6 +-- src/plugin-hooks/useResizeColumns.js | 80 ++++++++++++++++++++++------ 3 files changed, 87 insertions(+), 18 deletions(-) diff --git a/.size-snapshot.json b/.size-snapshot.json index 427b197..ebe2195 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -17,5 +17,24 @@ "code": 8444 } } + }, + "dist\\index.js": { + "bundled": 105386, + "minified": 49565, + "gzipped": 13008 + }, + "dist\\index.es.js": { + "bundled": 104543, + "minified": 48815, + "gzipped": 12856, + "treeshaked": { + "rollup": { + "code": 80, + "import_statements": 21 + }, + "webpack": { + "code": 8444 + } + } } } diff --git a/examples/column-resizing/src/App.js b/examples/column-resizing/src/App.js index 4355c4e..7048e2a 100644 --- a/examples/column-resizing/src/App.js +++ b/examples/column-resizing/src/App.js @@ -35,18 +35,18 @@ const Styles = styled.div` border-right: 0; } - ${'' /* The resizer styles! */} - .resizer { display: inline-block; background: blue; - width: 5px; + width: 10px; height: 100%; position: absolute; right: 0; top: 0; transform: translateX(50%); z-index: 1; + ${'' /* prevents from scrolling while dragging on touch devices */} + touch-action:none; &.isResizing { background: red; diff --git a/src/plugin-hooks/useResizeColumns.js b/src/plugin-hooks/useResizeColumns.js index d2a6a35..a96149d 100644 --- a/src/plugin-hooks/useResizeColumns.js +++ b/src/plugin-hooks/useResizeColumns.js @@ -106,27 +106,76 @@ const useInstanceBeforeDimensions = instance => { } }) - const onMouseDown = (e, header) => { + const onResizeStart = (e, header) => { + let isTouchEvent = false + if (e.type === 'touchstart') { + // lets not respond to multiple touches (e.g. 2 or 3 fingers) + if (e.touches && e.touches.length > 1) { + return + } + isTouchEvent = true + } const headersToResize = getLeafHeaders(header) const headerIdWidths = headersToResize.map(d => [d.id, d.totalWidth]) - const clientX = e.clientX + const clientX = isTouchEvent ? Math.round(e.touches[0].clientX) : e.clientX - const onMouseMove = e => { - const clientX = e.clientX + const dispatchMove = clientXPos => { + dispatch({ type: actions.columnResizing, clientX: clientXPos }) + } + const dispatchEnd = () => dispatch({ type: actions.columnDoneResizing }) - dispatch({ type: actions.columnResizing, clientX }) + const handlersAndEvents = { + mouse: { + moveEvent: 'mousemove', + moveHandler: e => dispatchMove(e.clientX), + upEvent: 'mouseup', + upHandler: e => { + document.removeEventListener( + 'mousemove', + handlersAndEvents.mouse.moveHandler + ) + document.removeEventListener( + 'mouseup', + handlersAndEvents.mouse.upHandler + ) + dispatchEnd() + }, + }, + touch: { + moveEvent: 'touchmove', + moveHandler: e => { + if (e.cancelable) { + e.preventDefault() + e.stopPropagation() + } + dispatchMove(e.touches[0].clientX) + return false + }, + upEvent: 'touchend', + upHandler: e => { + document.removeEventListener( + handlersAndEvents.touch.moveEvent, + handlersAndEvents.touch.moveHandler + ) + document.removeEventListener( + handlersAndEvents.touch.upEvent, + handlersAndEvents.touch.moveHandler + ) + dispatchEnd() + }, + }, } - const onMouseUp = e => { - document.removeEventListener('mousemove', onMouseMove) - document.removeEventListener('mouseup', onMouseUp) - - dispatch({ type: actions.columnDoneResizing }) - } - - document.addEventListener('mousemove', onMouseMove) - document.addEventListener('mouseup', onMouseUp) + const events = isTouchEvent + ? handlersAndEvents.touch + : handlersAndEvents.mouse + document.addEventListener(events.moveEvent, events.moveHandler, { + passive: false, + }) + document.addEventListener(events.upEvent, events.upHandler, { + passive: false, + }) dispatch({ type: actions.columnStartResizing, @@ -155,7 +204,8 @@ const useInstanceBeforeDimensions = instance => { header.getResizerProps = userProps => { return mergeProps( { - onMouseDown: e => e.persist() || onMouseDown(e, header), + onMouseDown: e => e.persist() || onResizeStart(e, header), + onTouchStart: e => e.persist() || onResizeStart(e, header), style: { cursor: 'ew-resize', },