Skip to content

Instantly share code, notes, and snippets.

@mattgperry
Created March 31, 2020 07:50
Show Gist options
  • Save mattgperry/f670bbc09a223d6fe5814d6764188c33 to your computer and use it in GitHub Desktop.
Save mattgperry/f670bbc09a223d6fe5814d6764188c33 to your computer and use it in GitHub Desktop.
Framer Motion drag utils
import * as React from "react"
import sync from "framesync"
import { MotionPlugins } from "../../motion/context/MotionPluginContext"
import { act } from "react-dom/test-utils"
import { fireEvent } from "@testing-library/dom"
export type Point = {
x: number
y: number
}
const pos: Point = {
x: 0,
y: 0,
}
export const frame = {
postRender: () => new Promise(resolve => sync.postRender(resolve)),
}
type Deferred<T> = {
promise: Promise<T>
resolve: unknown extends T ? () => void : (value: T) => void
}
export function deferred<T>(): Deferred<T> {
const def = {} as Deferred<T>
def.promise = new Promise(resolve => {
def.resolve = resolve as any
})
return def
}
export const drag = (element: any, triggerElement?: any) => {
pos.x = 0
pos.y = 0
fireEvent.mouseDown(triggerElement || element)
const controls = {
to: async (x: number, y: number) => {
pos.x = x
pos.y = y
await act(async () => {
fireEvent.mouseMove(document.body, { buttons: 1 })
await frame.postRender()
})
return controls
},
end: () => {
fireEvent.mouseUp(element)
},
}
return controls
}
export const sleep = (ms: number) =>
new Promise(resolve => setTimeout(resolve, ms))
export const MockDrag = ({ children }: { children: React.ReactNode }) => (
<MotionPlugins transformPagePoint={() => pos}>{children}</MotionPlugins>
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment