Open natpbs opened 8 months ago
Nice catch! I agree.
From ChatGPT 4:
To make the drag interaction of your split pane resizer component work on touch screens, you'll need to add touch event listeners in addition to the existing mouse event listeners. The primary touch events you'll want to handle are touchstart
, touchmove
, and touchend
.
Here's how you can modify the existing code to include touch event handling:
Add Touch Event Handlers: Similar to onMouseDown
, onMouseMove
, and onMouseUp
, create corresponding touch event handlers: onTouchStart
, onTouchMove
, and onTouchEnd
.
Adjust Event Handling Logic: Touch events have a different structure than mouse events. For instance, the clientX position is obtained from event.touches[0].clientX
in a touchmove
event.
Bind and Unbind Touch Event Listeners: In the useEffect
hook where you're adding and removing mouse event listeners, do the same for the touch event listeners.
Here is an example of how you might modify your component to handle touch events:
// ... (existing imports and code)
export const VZResizer = ({ side }: { side: Side }) => {
// ... (existing useContext and useRef hooks)
// Modify existing onMouseDown
const onMouseDown = useCallback((event: React.MouseEvent | React.TouchEvent) => {
event.preventDefault();
const clientX = event instanceof MouseEvent ? event.clientX : event.touches[0].clientX;
previousClientX.current = clientX;
setIsDragging(true, side);
document.body.style.cursor = 'col-resize';
}, [setIsDragging, side]);
// New onTouchMove handler
const onTouchMove = useCallback((event: TouchEvent) => {
event.preventDefault();
const clientX = event.touches[0].clientX;
const movementX = clientX - previousClientX.current;
previousClientX.current = clientX;
moveSplitPane(movementX, side);
}, [moveSplitPane, side]);
// ... (modify existing onMouseMove and onMouseUp to handle both mouse and touch events)
useEffect(() => {
if (isDragging) {
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
document.addEventListener('touchmove', onTouchMove, { passive: false });
document.addEventListener('touchend', onMouseUp);
return () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
document.removeEventListener('touchmove', onTouchMove);
document.removeEventListener('touchend', onMouseUp);
};
}
}, [isDragging, onMouseMove, onMouseUp, onTouchMove]);
// ... (rest of the component)
};
In this modification:
onMouseDown
is now handling both mouse and touch start events.onTouchMove
is specifically handling the touch move event.useEffect
hook is now also setting up and cleaning up touch event listeners.With these changes, your resizer should be functional on both mouse-driven and touch-driven devices. Remember to thoroughly test on various devices to ensure compatibility and usability.
The draggable bar that is used to adjust the width of the side panel bar should work with touch or stylus based interactions such as on tablets, phones or convertible laptops.
Currently, it can only be dragged with a mouse.