diff --git a/components/splitter/SplitBar.tsx b/components/splitter/SplitBar.tsx index bd1af5b165..0884668013 100644 --- a/components/splitter/SplitBar.tsx +++ b/components/splitter/SplitBar.tsx @@ -52,6 +52,14 @@ const SplitBar: React.FC = (props) => { } }; + const onTouchStart: React.TouchEventHandler = (e) => { + if (resizable && e.touches.length === 1) { + const touch = e.touches[0]; + setStartPos([touch.pageX, touch.pageY]); + onOffsetStart(index); + } + }; + React.useEffect(() => { if (startPos) { const onMouseMove = (e: MouseEvent) => { @@ -67,12 +75,31 @@ const SplitBar: React.FC = (props) => { onOffsetEnd(); }; + const handleTouchMove = (e: TouchEvent) => { + if (e.touches.length === 1) { + const touch = e.touches[0]; + const offsetX = touch.pageX - startPos[0]; + const offsetY = touch.pageY - startPos[1]; + + onOffsetUpdate(index, offsetX, offsetY); + } + }; + + const handleTouchEnd = () => { + setStartPos(null); + onOffsetEnd(); + }; + + window.addEventListener('touchmove', handleTouchMove); + window.addEventListener('touchend', handleTouchEnd); window.addEventListener('mousemove', onMouseMove); window.addEventListener('mouseup', onMouseUp); return () => { window.removeEventListener('mousemove', onMouseMove); window.removeEventListener('mouseup', onMouseUp); + window.removeEventListener('touchmove', handleTouchMove); + window.removeEventListener('touchend', handleTouchEnd); }; } }, [startPos]); @@ -95,6 +122,7 @@ const SplitBar: React.FC = (props) => { [`${splitBarPrefixCls}-dragger-active`]: active, })} onMouseDown={onMouseDown} + onTouchStart={onTouchStart} /> {/* Start Collapsible */} diff --git a/components/splitter/__tests__/index.test.tsx b/components/splitter/__tests__/index.test.tsx index e3e029095c..42f7d8635c 100644 --- a/components/splitter/__tests__/index.test.tsx +++ b/components/splitter/__tests__/index.test.tsx @@ -113,6 +113,27 @@ describe('Splitter', () => { fireEvent.mouseUp(draggerEle); } + function mockTouchDrag(draggerEle: HTMLElement, offset: number) { + // Down + const touchStart = createEvent.touchStart(draggerEle, { + touches: [{}], + }); + (touchStart as any).touches[0].pageX = 0; + (touchStart as any).touches[0].pageY = 0; + fireEvent(draggerEle, touchStart); + + // Move + const touchMove = createEvent.touchMove(draggerEle, { + touches: [{}], + }); + (touchMove as any).touches[0].pageX = offset; + (touchMove as any).touches[0].pageY = offset; + fireEvent(draggerEle, touchMove); + + // Up + fireEvent.touchEnd(draggerEle); + } + it('The mousemove should work fine', async () => { const onResize = jest.fn(); const onResizeEnd = jest.fn(); @@ -132,6 +153,25 @@ describe('Splitter', () => { expect(onResizeEnd).toHaveBeenCalledWith([0, 100]); }); + it('The touchMove should work fine', async () => { + const onResize = jest.fn(); + const onResizeEnd = jest.fn(); + + const { container } = render( + , + ); + + // Right + mockTouchDrag(container.querySelector('.ant-splitter-bar-dragger')!, 40); + expect(onResize).toHaveBeenCalledWith([90, 10]); + expect(onResizeEnd).toHaveBeenCalledWith([90, 10]); + + // Left + mockTouchDrag(container.querySelector('.ant-splitter-bar-dragger')!, -200); + expect(onResize).toHaveBeenCalledWith([0, 100]); + expect(onResizeEnd).toHaveBeenCalledWith([0, 100]); + }); + it('with min', () => { const onResize = jest.fn(); const onResizeEnd = jest.fn();