import type { DragControls } from "./use-drag-controls.js"; import type { Axis, BoundingBox, DragElastic, InertiaOptions, PanInfo } from "framer-motion"; import type { TargetAndTransition, VariantLabels } from "motion-dom"; export interface ResolvedConstraints { x: Partial; y: Partial; } /** * @public */ export interface DragHandlers { /** * Callback function that fires when dragging starts. * * ```jsx * console.log(info.point.x, info.point.y) * } * /> * ``` * * @public */ onDragStart?: (event: PointerEvent, info: PanInfo) => void; /** * Callback function that fires when dragging ends. * * ```jsx * console.log(info.point.x, info.point.y) * } * /> * ``` * * @public */ onDragEnd?: (event: PointerEvent, info: PanInfo) => void; /** * Callback function that fires when the component is dragged. * * ```jsx * console.log(info.point.x, info.point.y) * } * /> * ``` * * @public */ onDrag?: (event: PointerEvent, info: PanInfo) => void; /** * Callback function that fires a drag direction is determined. * * ```jsx * console.log(axis)} * /> * ``` * * @public */ onDirectionLock?: (axis: "x" | "y") => void; /** * Callback function that fires when drag momentum/bounce transition finishes. * * ```jsx * console.log('Drag transition complete')} * /> * ``` * * @public */ onDragTransitionEnd?: () => void; /** * If `dragConstraints` is set to a HTMLElement, this callback will call with the measured drag constraints. * * @public */ onMeasureDragConstraints?: (constraints: BoundingBox) => BoundingBox | void; } export interface DragProps extends DragHandlers { /** * Enable dragging for this element. Set to `false` by default. * Set `true` to drag in both directions. * Set `"x"` or `"y"` to only drag in a specific direction. * * ```jsx * * ``` */ drag?: boolean | "x" | "y"; /** * If true, element will snap back to its origin when dragging ends. * * Enabling this is the equivalent of setting all `dragConstraints` axes to `0` * with `dragElastic={1}`, but when used together `dragConstraints` can define * a wider draggable area and `dragSnapToOrigin` will ensure the element * animates back to its origin on release. */ dragSnapToOrigin?: boolean; /** * If `true`, this will lock dragging to the initially-detected direction. Defaults to `false`. * * ```jsx * * ``` */ dragDirectionLock?: boolean; /** * Allows drag gesture propagation to child components. Set to `false` by * default. * * ```jsx * * ``` */ dragPropagation?: boolean; dragConstraints?: false | Partial | HTMLElement; /** * The degree of movement allowed outside constraints. 0 = no movement, 1 = * full movement. * * Set to `0.5` by default. Can also be set as `false` to disable movement. * * By passing an object of `top`/`right`/`bottom`/`left`, individual values can be set * per constraint. Any missing values will be set to `0`. * * ```jsx * * ``` */ dragElastic?: DragElastic; /** * Apply momentum from the pan gesture to the component when dragging * finishes. Set to `true` by default. * * ```jsx * * ``` */ dragMomentum?: boolean; /** * Allows you to change dragging inertia parameters. * When releasing a draggable Frame, an animation with type `inertia` starts. The animation is based on your dragging velocity. This property allows you to customize it. * See {@link https://framer.com/api/animation/#inertia | Inertia} for all properties you can use. * * ```jsx * * ``` */ dragTransition?: InertiaOptions; /** * By default, if `drag` is defined on a component then an event listener will be attached * to automatically initiate dragging when a user presses down on it. * * By setting `dragListener` to `false`, this event listener will not be created. * * ```jsx * const dragControls = useDragControls() * * function startDrag(event) { * dragControls.start(event, { snapToCursor: true }) * } * * return ( * <> *
* * * ) * ``` */ dragListener?: boolean; /** * Usually, dragging is initiated by pressing down on a component and moving it. For some * use-cases, for instance clicking at an arbitrary point on a video scrubber, we * might want to initiate dragging from a different component than the draggable one. * * By creating a `dragControls` using the `useDragControls` hook, we can pass this into * the draggable component's `dragControls` prop. It exposes a `start` method * that can start dragging from pointer events on other components. * * ```jsx * const dragControls = useDragControls() * * function startDrag(event) { * dragControls.start(event, { snapToCursor: true }) * } * * return ( * <> *
* * * ) * ``` */ dragControls?: DragControls; whileDrag?: VariantLabels | TargetAndTransition; }