framer / motion

Open source, production-ready animation and gesture library for React

Home Page:https://framer.com/motion

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[FEATURE] Add useDragThreshold hook for drag cancelation

DanDuongasaur opened this issue · comments

Problem: Drag cannot be cancelled when reaching boundaries

I’m always frustrated when I need to manually handle drag cancellation after a certain threshold is reached. The current method involves accessing componentControls, which is a private API and not ideal for production use.

Solution
I would like to have an onDragThreshold callback handler that is automatically called when a specified threshold is reached during a drag operation. The threshold would be set on the useDragThreshold hook, and the function would be passed into onDrag.

const onDrag = useDragThreshold(threshold, (cancel, bounds) => {
    if (something) {
       // Ability to trigger sideEffects here
        cancel();
     }
});

<motion.div onDrag={onDrag} />

Describe alternatives you've considered
Currently, the workaround involves accessing the private componentControls to stop the drag manually. However, this approach is not suitable for production due to the private nature of componentControls.

const onDrag = (event: any, info: PanInfo) => {
    const dragOffset = info.offset.x;
    const threshold = Math.abs(activeRoundWidth.current * 0.8); // 80% of the active round width

    const cancelDrag = Math.abs(dragOffset) > threshold;
    if (cancelDrag) {
        (dragControls as any).componentControls.forEach((entry: any) => {
            const mouseUpEvent = new MouseEvent("mouseup");
            entry.stop(mouseUpEvent, info);
        });
    }
}

Additional context
Having a dedicated onDragThreshold callback would greatly simplify the code and make it more robust for production use. This feature would enhance the usability of drag interactions by providing a clean and straightforward way to handle drag cancellations based on a threshold.

I am happy to work on this and contribute to the project :)