From cfa033ea860f7f6e5be883976d12a9534024a8b9 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Feb 2026 05:36:46 +0000 Subject: [PATCH 1/6] fix: allow drag to start from child button and link elements Child buttons and links no longer block drag gestures from starting since they don't have click-and-move actions of their own. Only form controls where text selection or direct interaction is expected (input, textarea, select) will still block drag. https://claude.ai/code/session_01YKHLcB3ZviYXCsrWZzmyou --- .../gestures/drag/__tests__/index.test.tsx | 139 +++++++++++++++--- .../press/utils/is-keyboard-accessible.ts | 17 +-- 2 files changed, 125 insertions(+), 31 deletions(-) diff --git a/packages/framer-motion/src/gestures/drag/__tests__/index.test.tsx b/packages/framer-motion/src/gestures/drag/__tests__/index.test.tsx index f2607d493c..75aea1ea18 100644 --- a/packages/framer-motion/src/gestures/drag/__tests__/index.test.tsx +++ b/packages/framer-motion/src/gestures/drag/__tests__/index.test.tsx @@ -1004,7 +1004,60 @@ describe("keyboard accessible elements", () => { expect(x.get()).toBeGreaterThanOrEqual(100) }) - test("drag gesture does not start when clicking a child button", async () => { + test("drag gesture starts on a motion.input with drag prop", async () => { + const onDragStart = jest.fn() + const x = motionValue(0) + const Component = () => ( + + + + ) + + const { getByTestId, rerender } = render() + rerender() + + const pointer = await drag(getByTestId("draggable-input")).to(100, 100) + pointer.end() + + await nextFrame() + + expect(onDragStart).toBeCalledTimes(1) + expect(x.get()).toBeGreaterThanOrEqual(100) + }) + + test("drag gesture starts on a motion.a with drag prop", async () => { + const onDragStart = jest.fn() + const x = motionValue(0) + const Component = () => ( + + + + ) + + const { getByTestId, rerender } = render() + rerender() + + const pointer = await drag(getByTestId("draggable-link")).to(100, 100) + pointer.end() + + await nextFrame() + + expect(onDragStart).toBeCalledTimes(1) + expect(x.get()).toBeGreaterThanOrEqual(100) + }) + + test("drag gesture does not start when clicking a child input", async () => { const onDragStart = jest.fn() const x = motionValue(0) const Component = () => ( @@ -1015,7 +1068,7 @@ describe("keyboard accessible elements", () => { onDragStart={onDragStart} style={{ x }} > - + ) @@ -1025,7 +1078,7 @@ describe("keyboard accessible elements", () => { const pointer = await drag( getByTestId("draggable"), - getByTestId("child-button") + getByTestId("child-input") ).to(100, 100) pointer.end() @@ -1035,51 +1088,93 @@ describe("keyboard accessible elements", () => { expect(x.get()).toBe(0) }) - test("drag gesture starts on a motion.input with drag prop", async () => { + test("drag gesture does not start when clicking a child textarea", async () => { const onDragStart = jest.fn() const x = motionValue(0) const Component = () => ( - + > +