import * as React from 'react'; /** * Because dragging and mouse clicks are non trivial, this implementation of DragEvent consumes the mouseDown event; * which means that 'onClick' doesn't work for anything that uses these events. * * We can compensate for that by having a listener for 'onMouseUpEnd' for the consumer of this event (see Brush) * * But in order to differentiate between a drag and a click, we need to pair up the mouseDowns with the MouseUps and * only allow 'legal' mouseUps with the mouseActionState. * * A 'mouseUp' is only legal if it can be paired with a previous "mouseDown". * * If a 'mouseUp' happens after another 'mouseUp' (without a "mouseDown" in between) * then it is not legal and the 'mouseActionState' will be null. * * The consumer (Brush, in this example) keeps track of whether or not the drag happens. * * We need differentiation because: * * The issue is that when the drag is over, both the onBrushEnd (x or y) and then the * onMouseUpEnd handlers get triggered; because of multiple mouseUp events. * * We want one or the other, not both. (a response to a range drag or to a single click) * * Each time there is a drag, there is ONE mouseDownEvent, then mousemove events, then one MouseUp Event that * triggers the onBrushEnd. * * Most of the time, there are additional onMouseUpEvents after that. (we will call them phantom mouseUps) * * We only want the first onMouseUp event to be legal. * So we check that the previous 'mouseActionState' was a mouseDownEvent ('mouseDownHappened'), and if so set the mouse state to a 'mouseUpHappened'. * * When the next mouseUp Event happens (without a proper, previous matching mouseDown Event), * then mouseActionState will be set to null. * * When the singleclick happens, it will check if the mouseActionState says 'mouseDownHappened'; if so; then it is a legal * mouseUp; and the mouseActionState will be set to 'mouseUpHappened'. If the mouse state is *anything* other then ''mouseDownHappened', then * the mouseActionState is set to null. * * The consumer checks the mouseActionState, and only fires the event if the mouseActionState is 'mouseUpHappened' * * And thus we have some history and can pair mouse ups with mouse downs and assure that phantom clicks * do not cause wonky behavior. * * Removing the phantom clicks entirely is a MUCH harder problem; because this is a clicker used by people with events. * * We are putting the mouseEvent into the event so that the consumer for the 'onMouseUpEnd' can use it, since that consumer * is a mouseListener and needs the mouseEvent information. * * isShiftDown is added for mouse down events */ export interface DragEvent { type: 'drag' | 'dragend'; initialX: number; initialY: number; direction: 'x' | 'y' | null; x: number; y: number; mouseActionState: 'mouseUpHappened' | 'mouseDownHappened' | null; mouseEvent?: React.MouseEvent; isShiftDown?: boolean; } interface UseDragEventProps { onMouseDown: (e: React.MouseEvent) => any; } export declare const useDragEvent: () => [DragEvent, UseDragEventProps]; export {};