From 338d9526c040dcc3afe5b2bd5e96fff6ab365abb Mon Sep 17 00:00:00 2001 From: Zammad Nasir <136105139+ZammadNasir@users.noreply.github.com> Date: Sat, 14 Feb 2026 19:19:50 +0500 Subject: [PATCH 1/4] fix: add touch-action: none to Separator for touch device support Fixes #662 (#664) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Relates to #662 This PR resolves an issue where dragging the resizable handle on touch devices (tablets and mobile phones) caused the panel to jump or snap to the edge of the container, making it impossible to resize panels accurately with touch interactions. ## Root Cause The issue was caused by the browser's default touch gesture handling. When a user attempted to drag the resize handle on a touch device, the browser would interpret the touch movement as a potential scroll or pan gesture and fire a `pointercancel` event, which interrupted the drag operation and caused erratic behavior. ## Solution Added `touch-action: none` CSS property to the `Separator` component. This CSS property instructs the browser to disable all default touch behaviors (scrolling, zooming, panning) on the resize handle element, allowing the pointer events to be handled exclusively by the resize logic. The `touch-action: none` property: - Prevents the browser from firing `pointercancel` events during drag operations - Ensures smooth and continuous pointer tracking during touch interactions - Does not affect mouse-based interactions - Is the standard approach for implementing custom drag interactions on touch devices ## Changes - Added `touchAction: "none"` to the `Separator` component's inline styles ## Testing Tested on: - ✅ Android devices (Chrome browser) - ✅ Chrome DevTools mobile emulation - ✅ Desktop browsers (Chrome, Firefox) - no regression - ⚠️ iOS devices - not tested (would appreciate testing from reviewers) ### Before - Touch dragging caused panels to jump to extreme positions - Resize handle was unresponsive or erratic on touch devices - Drag operations would randomly stop mid-gesture ### After - Smooth, predictable touch dragging behavior - Resize handle follows finger movement accurately - Consistent behavior across touch and mouse interactions ## Breaking Changes None. This is a bug fix that only affects the CSS styling of the resize handle. ## Additional Notes This is a minimal, non-invasive fix that follows web standards for handling touch interactions in custom drag operations. The `touch-action` CSS property is widely supported across all modern browsers. If there are concerns about iOS compatibility, I'm happy to add additional testing or iterate on the solution. However, `touch-action: none` is the standard approach recommended by MDN and browser vendors for preventing default touch behaviors during custom pointer interactions. ``` ## Commit Message ``` fix: add touch-action: none to Separator for touch device support Fixes #662 On touch devices, the browser's default gesture handling would fire pointercancel events during drag operations, causing panels to jump to extreme positions. Adding touch-action: none prevents the browser from interpreting touch movements as gestures, allowing smooth touch dragging. Tested on Android devices and Chrome DevTools mobile emulation. ``` ## Files Changed ``` lib/components/separator/Separator.tsx --- lib/components/separator/Separator.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/components/separator/Separator.tsx b/lib/components/separator/Separator.tsx index 6208555e6..db6459be3 100644 --- a/lib/components/separator/Separator.tsx +++ b/lib/components/separator/Separator.tsx @@ -162,7 +162,8 @@ export function Separator({ cursor, ...style, flexGrow: 0, - flexShrink: 0 + flexShrink: 0, + touchAction: "none" // Disable touch scrolling while dragging }} tabIndex={disabled ? undefined : 0} /> From 8f5e5f39d23547c078cd84809a71751994876c5d Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Sat, 14 Feb 2026 09:21:41 -0500 Subject: [PATCH 2/4] Update CHANGELOG with pending release changes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4b303494..c3e0338b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- [664](https://github.com/bvaughn/react-resizable-panels/pull/664): Resize actions sometimes "jump" on touch devices + ## 4.6.3 - Fixed a problem with project logo not displaying correctly in the README for the Firefox browser. From f07e6479b8afcf06c528952f11617a634726c927 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Sat, 14 Feb 2026 09:57:07 -0500 Subject: [PATCH 3/4] Prevent layout jump when resizing on touch devices (#665) Resolves #662 Previously I had code that attempted to tell the browser that I would handle touch interactions. It worked by setting `touch-action: none` in response to a "pointerdown" event: https://github.com/bvaughn/react-resizable-panels/blob/8f5e5f39d23547c078cd84809a71751994876c5d/lib/global/cursor/updateCursorStyle.ts#L41 Apparently this isn't soon enough in some cases, and sometimes the _first_ touch interaction on mobile would jump. This commit expands the `touch-action` styles to apply to the `Group` and `Panel` elements (it's not an inherited style) as well the `Separator`. --- CHANGELOG.md | 2 +- lib/components/group/Group.tsx | 10 +++++++++- lib/components/panel/Panel.tsx | 9 ++++++++- lib/components/separator/Separator.tsx | 7 ++++++- lib/global/cursor/updateCursorStyle.ts | 2 +- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3e0338b4..5c72b3d0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -- [664](https://github.com/bvaughn/react-resizable-panels/pull/664): Resize actions sometimes "jump" on touch devices +- [664](https://github.com/bvaughn/react-resizable-panels/pull/664), [665](https://github.com/bvaughn/react-resizable-panels/pull/665): Resize actions sometimes "jump" on touch devices ## 4.6.3 diff --git a/lib/components/group/Group.tsx b/lib/components/group/Group.tsx index b5d67c39d..35ef37f30 100644 --- a/lib/components/group/Group.tsx +++ b/lib/components/group/Group.tsx @@ -356,10 +356,18 @@ export function Group({ height: "100%", width: "100%", overflow: "hidden", + ...style, + display: "flex", flexDirection: orientation === "horizontal" ? "row" : "column", - flexWrap: "nowrap" + flexWrap: "nowrap", + + // Inform the browser that the library is handling touch events for this element + // but still allow users to scroll content within panels in the non-resizing direction + // NOTE This is not an inherited style + // See github.com/bvaughn/react-resizable-panels/issues/662 + touchAction: orientation === "horizontal" ? "pan-y" : "pan-x" }} > {children} diff --git a/lib/components/panel/Panel.tsx b/lib/components/panel/Panel.tsx index 1b68d20f7..01b840808 100644 --- a/lib/components/panel/Panel.tsx +++ b/lib/components/panel/Panel.tsx @@ -72,6 +72,7 @@ export function Panel({ const { getPanelStyles, id: groupId, + orientation, registerPanel, togglePanelDisabled } = useGroupContext(); @@ -176,7 +177,13 @@ export function Panel({ maxWidth: "100%", flexGrow: 1, - ...style + ...style, + + // Inform the browser that the library is handling touch events for this element + // but still allow users to scroll content within panels in the non-resizing direction + // NOTE This is not an inherited style + // See github.com/bvaughn/react-resizable-panels/issues/662 + touchAction: orientation === "horizontal" ? "pan-y" : "pan-x" }} > {children} diff --git a/lib/components/separator/Separator.tsx b/lib/components/separator/Separator.tsx index db6459be3..07c3c681c 100644 --- a/lib/components/separator/Separator.tsx +++ b/lib/components/separator/Separator.tsx @@ -160,10 +160,15 @@ export function Separator({ style={{ flexBasis: "auto", cursor, + ...style, + flexGrow: 0, flexShrink: 0, - touchAction: "none" // Disable touch scrolling while dragging + + // Inform the browser that the library is handling touch events for this element + // See github.com/bvaughn/react-resizable-panels/issues/662 + touchAction: "none" }} tabIndex={disabled ? undefined : 0} /> diff --git a/lib/global/cursor/updateCursorStyle.ts b/lib/global/cursor/updateCursorStyle.ts index 0c9671b13..bf9fb9f1e 100644 --- a/lib/global/cursor/updateCursorStyle.ts +++ b/lib/global/cursor/updateCursorStyle.ts @@ -38,7 +38,7 @@ export function updateCursorStyle(ownerDocument: Document) { state: interactionState.state }); - const nextStyle = `*, *:hover {cursor: ${cursorStyle} !important; ${interactionState.state === "active" ? "touch-action: none;" : ""} }`; + const nextStyle = `*, *:hover {cursor: ${cursorStyle} !important; }`; if (prevStyle === nextStyle) { return; } From 6f932fd6e5a92f72cfa32996e14c45e9ebb6a3ad Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Sat, 14 Feb 2026 09:57:53 -0500 Subject: [PATCH 4/4] 4.6.3 -> 4.6.4 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c72b3d0a..5b5b5551d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 4.6.4 - [664](https://github.com/bvaughn/react-resizable-panels/pull/664), [665](https://github.com/bvaughn/react-resizable-panels/pull/665): Resize actions sometimes "jump" on touch devices diff --git a/package.json b/package.json index ca497735d..13eb26c9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-resizable-panels", - "version": "4.6.3", + "version": "4.6.4", "type": "module", "author": "Brian Vaughn (https://github.com/bvaughn/)", "contributors": [