{"version":3,"file":"useSwipeGesture.cjs","sources":["../../../../src/hooks/useSwipeGesture/useSwipeGesture.ts"],"sourcesContent":["import {\n    type MouseEventHandler,\n    type MutableRefObject,\n    type PointerEventHandler,\n    useCallback,\n    useRef,\n} from \"react\";\n\nexport type SwipeChangeHandler<T extends HTMLElement> = (\n    event: React.MouseEvent<T> | React.PointerEvent<T>,\n    pressed: boolean,\n) => void;\n\ntype Point = { x: number; y: number };\n\nfunction getGesturePointFromEvent<T extends HTMLElement>(\n    event: React.PointerEvent<T>,\n): Point {\n    return {\n        x: event.clientX,\n        y: event.clientY,\n    };\n}\n\ntype SwipeGestureOptions<T extends HTMLElement> = {\n    onClick?: MouseEventHandler<T>;\n    onChange?: SwipeChangeHandler<T>;\n    onPointerDown?: PointerEventHandler<T>;\n    onPointerUp?: PointerEventHandler<T>;\n    onPointerMove?: PointerEventHandler<T>;\n    onPointerCancel?: PointerEventHandler<T>;\n};\n\n/**\n * Logikk for å håndtere en swipe, for eksempel brukt i toggle switch.\n *\n * @param options Callbacks for de ulike stegene i en swipe-gesture\n * @returns Handlers for de ulike stegene i en swipe-gesture\n */\nexport function useSwipeGesture<T extends HTMLElement>(\n    options: SwipeGestureOptions<T>,\n): {\n    swipeHandled: MutableRefObject<\"on\" | \"off\" | false>;\n    gestureHandlers: {\n        onClick: MouseEventHandler<T>;\n        onPointerDown: PointerEventHandler<T>;\n        onPointerMove: PointerEventHandler<T>;\n        onPointerUp: PointerEventHandler<T>;\n        onPointerCancel: PointerEventHandler<T>;\n    };\n} {\n    const swipeHandled = useRef<\"on\" | \"off\" | false>(false);\n    const gestureStartPosition = useRef<Point>();\n\n    const {\n        onClick,\n        onChange,\n        onPointerCancel,\n        onPointerDown,\n        onPointerMove,\n        onPointerUp,\n    } = options;\n\n    const handleClick: MouseEventHandler<T> = useCallback(\n        (event) => {\n            if (!swipeHandled.current) {\n                onClick?.(event);\n            }\n            swipeHandled.current = false; // sørg for at vi får klikke igjen etter swipes\n        },\n        [onClick],\n    );\n\n    const handleGestureStart: PointerEventHandler<T> = useCallback(\n        (event) => {\n            event.preventDefault();\n\n            (event.target as T).setPointerCapture?.(event.pointerId);\n            gestureStartPosition.current = getGesturePointFromEvent(event);\n            swipeHandled.current = false;\n\n            onPointerDown?.(event);\n        },\n        [onPointerDown],\n    );\n\n    const handleGestureMove: PointerEventHandler<T> = useCallback(\n        (event) => {\n            event.preventDefault();\n\n            if (!gestureStartPosition.current) {\n                return;\n            }\n\n            const { x: currentX } = getGesturePointFromEvent(event);\n            const { x: startX } = gestureStartPosition.current;\n\n            if (\n                currentX - startX > 10 &&\n                onChange &&\n                swipeHandled.current !== \"on\"\n            ) {\n                onChange(event, true);\n                swipeHandled.current = \"on\";\n                gestureStartPosition.current = getGesturePointFromEvent(event);\n            } else if (\n                startX - currentX > 10 &&\n                onChange &&\n                swipeHandled.current !== \"off\"\n            ) {\n                onChange(event, false);\n                swipeHandled.current = \"off\";\n                gestureStartPosition.current = getGesturePointFromEvent(event);\n            }\n\n            onPointerMove?.(event);\n        },\n        [onPointerMove, onChange],\n    );\n\n    const handleGestureEnd: PointerEventHandler<T> = useCallback(\n        (event) => {\n            event.preventDefault();\n\n            (event.target as T).releasePointerCapture?.(event.pointerId);\n            gestureStartPosition.current = undefined;\n\n            event.type === \"pointerup\"\n                ? onPointerUp?.(event)\n                : onPointerCancel?.(event);\n        },\n        [onPointerUp, onPointerCancel],\n    );\n\n    return {\n        swipeHandled,\n        gestureHandlers: {\n            onClick: handleClick,\n            onPointerDown: handleGestureStart,\n            onPointerMove: handleGestureMove,\n            onPointerUp: handleGestureEnd,\n            onPointerCancel: handleGestureEnd,\n        },\n    };\n}\n"],"names":["getGesturePointFromEvent","event","x","clientX","y","clientY","options","swipeHandled","useRef","gestureStartPosition","onClick","onChange","onPointerCancel","onPointerDown","onPointerMove","onPointerUp","handleClick","useCallback","current","handleGestureStart","preventDefault","target","setPointerCapture","pointerId","handleGestureMove","currentX","startX","handleGestureEnd","releasePointerCapture","type","gestureHandlers"],"mappings":"yGAeA,SAASA,EACLC,GAEA,MAAO,CACHC,EAAGD,EAAME,QACTC,EAAGH,EAAMI,QAEjB,yBAiBO,SACHC,GAWA,MAAMC,EAAeC,EAAAA,QAA6B,GAC5CC,EAAuBD,EAAAA,UAGzBE,QAAAA,EACAC,SAAAA,EACAC,gBAAAA,EACAC,cAAAA,EACAC,cAAAA,EACAC,YAAAA,GACAT,EAEEU,EAAoCC,EAAAA,YACrChB,IACQM,EAAaW,SACdR,IAAUT,GAEdM,EAAaW,SAAU,GAE3B,CAACR,IAGCS,EAA6CF,EAAAA,YAC9ChB,IACGA,EAAMmB,iBAELnB,EAAMoB,OAAaC,oBAAoBrB,EAAMsB,WAC9Cd,EAAqBS,QAAUlB,EAAyBC,GACxDM,EAAaW,SAAU,EAEvBL,IAAgBZ,IAEpB,CAACY,IAGCW,EAA4CP,EAAAA,YAC7ChB,IAGG,GAFAA,EAAMmB,kBAEDX,EAAqBS,QACtB,OAGJ,MAAQhB,EAAGuB,GAAazB,EAAyBC,IACzCC,EAAGwB,GAAWjB,EAAqBS,QAGvCO,EAAWC,EAAS,IACpBf,GACyB,OAAzBJ,EAAaW,SAEbP,EAASV,GAAO,GAChBM,EAAaW,QAAU,KACvBT,EAAqBS,QAAUlB,EAAyBC,IAExDyB,EAASD,EAAW,IACpBd,GACyB,QAAzBJ,EAAaW,UAEbP,EAASV,GAAO,GAChBM,EAAaW,QAAU,MACvBT,EAAqBS,QAAUlB,EAAyBC,IAG5Da,IAAgBb,IAEpB,CAACa,EAAeH,IAGdgB,EAA2CV,EAAAA,YAC5ChB,IACGA,EAAMmB,iBAELnB,EAAMoB,OAAaO,wBAAwB3B,EAAMsB,WAClDd,EAAqBS,aAAU,EAEhB,cAAfjB,EAAM4B,KACAd,IAAcd,GACdW,IAAkBX,IAE5B,CAACc,EAAaH,IAGlB,MAAO,CACHL,aAAAA,EACAuB,gBAAiB,CACbpB,QAASM,EACTH,cAAeM,EACfL,cAAeU,EACfT,YAAaY,EACbf,gBAAiBe,GAG7B"}