diff --git a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx index dcb8dd6dd4..0e3d5eb928 100644 --- a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx +++ b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.test.tsx @@ -280,6 +280,82 @@ describe("FlatSlider", () => { expect(onCommit).toHaveBeenCalledWith(10); act(() => root.unmount()); }); + + it("commits continuously while dragging, not just on the initial pointerdown", () => { + const onCommit = vi.fn(); + const { host, root } = renderInto( + , + ); + const track = host.querySelector('[data-flat-slider-track="true"]'); + if (!track) throw new Error("expected a track element"); + Object.defineProperty(track, "getBoundingClientRect", { + value: () => ({ left: 0, width: 200, top: 0, height: 20, right: 200, bottom: 20 }), + }); + act(() => { + track.dispatchEvent( + new PointerEvent("pointerdown", { bubbles: true, clientX: 20, pointerId: 1 }), + ); + }); + expect(onCommit).toHaveBeenLastCalledWith(10); + act(() => { + track.dispatchEvent( + new PointerEvent("pointermove", { bubbles: true, clientX: 160, pointerId: 1 }), + ); + }); + expect(onCommit).toHaveBeenLastCalledWith(80); + act(() => { + track.dispatchEvent( + new PointerEvent("pointermove", { bubbles: true, clientX: 100, pointerId: 1 }), + ); + }); + expect(onCommit).toHaveBeenLastCalledWith(50); + act(() => { + track.dispatchEvent(new PointerEvent("pointerup", { bubbles: true, pointerId: 1 })); + }); + act(() => root.unmount()); + }); + + it("ignores pointermove once a drag has ended (pointer capture released)", () => { + const onCommit = vi.fn(); + const { host, root } = renderInto( + , + ); + const track = host.querySelector('[data-flat-slider-track="true"]'); + if (!track) throw new Error("expected a track element"); + Object.defineProperty(track, "getBoundingClientRect", { + value: () => ({ left: 0, width: 200, top: 0, height: 20, right: 200, bottom: 20 }), + }); + act(() => { + track.dispatchEvent( + new PointerEvent("pointerdown", { bubbles: true, clientX: 20, pointerId: 1 }), + ); + track.dispatchEvent(new PointerEvent("pointerup", { bubbles: true, pointerId: 1 })); + }); + onCommit.mockClear(); + act(() => { + track.dispatchEvent( + new PointerEvent("pointermove", { bubbles: true, clientX: 160, pointerId: 1 }), + ); + }); + expect(onCommit).not.toHaveBeenCalled(); + act(() => root.unmount()); + }); }); describe("FlatSlider — Grade extensions", () => { diff --git a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx index f2cdf6220b..52eba79a3e 100644 --- a/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx +++ b/packages/studio/src/components/editor/propertyPanelFlatPrimitives.tsx @@ -262,8 +262,18 @@ export function FlatSlider({ className={`relative h-5 flex-1 ${disabled ? "cursor-not-allowed" : "cursor-pointer"}`} onPointerDown={(e) => { if (disabled) return; + e.currentTarget.setPointerCapture(e.pointerId); commitFromClientX(e.clientX, e.currentTarget.getBoundingClientRect()); }} + onPointerMove={(e) => { + if (disabled || !e.currentTarget.hasPointerCapture(e.pointerId)) return; + commitFromClientX(e.clientX, e.currentTarget.getBoundingClientRect()); + }} + onPointerUp={(e) => { + if (e.currentTarget.hasPointerCapture(e.pointerId)) { + e.currentTarget.releasePointerCapture(e.pointerId); + } + }} >
{centerTick && (