{"version":3,"file":"use-map-zoom.cjs","names":[],"sources":["../../src/br/use-map-zoom.ts"],"sourcesContent":["import { useCallback, useRef, useState, type PointerEvent, type WheelEvent } from \"react\";\n\n/** Pan/zoom transform state. */\nexport interface MapTransform {\n    /** Zoom factor (1 = fit). */\n    k: number;\n    /** X translation in pixels. */\n    x: number;\n    /** Y translation in pixels. */\n    y: number;\n}\n\nconst MIN_K = 1;\nconst MAX_K = 12;\n\nexport interface UseMapZoom {\n    /** SVG `transform` string for the content `<g>`. */\n    transform: string;\n    /** Current zoom factor. */\n    zoom: number;\n    /** True when panned/zoomed away from the initial fit. */\n    isTransformed: boolean;\n    /** Reset to the initial fit. */\n    reset: () => void;\n    /** Handlers to spread on the `<svg>` element. */\n    handlers: {\n        onWheel?: (e: WheelEvent) => void;\n        onPointerDown?: (e: PointerEvent) => void;\n        onPointerMove?: (e: PointerEvent) => void;\n        onPointerUp?: (e: PointerEvent) => void;\n        onPointerLeave?: (e: PointerEvent) => void;\n        onDoubleClick?: () => void;\n        style?: { cursor: string; touchAction: string };\n    };\n}\n\n/**\n * Wheel-zoom (anchored at the cursor) + drag-pan for an SVG map. Returns a\n * `transform` to apply to a content `<g>` and handlers for the `<svg>`. A no-op\n * (identity transform, empty handlers) when `enabled` is false.\n */\nexport function useMapZoom(enabled: boolean): UseMapZoom {\n    const [t, setT] = useState<MapTransform>({ k: 1, x: 0, y: 0 });\n    const drag = useRef<{ x: number; y: number; ox: number; oy: number } | null>(null);\n\n    const reset = useCallback(() => setT({ k: 1, x: 0, y: 0 }), []);\n\n    const onWheel = useCallback((e: WheelEvent) => {\n        e.preventDefault();\n        const rect = e.currentTarget.getBoundingClientRect();\n        const cx = e.clientX - rect.left;\n        const cy = e.clientY - rect.top;\n        setT((prev) => {\n            const factor = e.deltaY < 0 ? 1.15 : 1 / 1.15;\n            const k = Math.max(MIN_K, Math.min(MAX_K, prev.k * factor));\n            const scale = k / prev.k;\n            return { k, x: cx - (cx - prev.x) * scale, y: cy - (cy - prev.y) * scale };\n        });\n    }, []);\n\n    const onPointerDown = useCallback((e: PointerEvent) => {\n        drag.current = { x: e.clientX, y: e.clientY, ox: 0, oy: 0 };\n        e.currentTarget.setPointerCapture?.(e.pointerId);\n    }, []);\n\n    const onPointerMove = useCallback((e: PointerEvent) => {\n        if (!drag.current) return;\n        const dx = e.clientX - drag.current.x;\n        const dy = e.clientY - drag.current.y;\n        drag.current.x = e.clientX;\n        drag.current.y = e.clientY;\n        setT((prev) => ({ ...prev, x: prev.x + dx, y: prev.y + dy }));\n    }, []);\n\n    const endDrag = useCallback((e: PointerEvent) => {\n        drag.current = null;\n        e.currentTarget.releasePointerCapture?.(e.pointerId);\n    }, []);\n\n    if (!enabled) {\n        return {\n            transform: \"\",\n            zoom: 1,\n            isTransformed: false,\n            reset,\n            handlers: {},\n        };\n    }\n\n    const isTransformed = t.k !== 1 || t.x !== 0 || t.y !== 0;\n    return {\n        transform: `translate(${t.x} ${t.y}) scale(${t.k})`,\n        zoom: t.k,\n        isTransformed,\n        reset,\n        handlers: {\n            onWheel,\n            onPointerDown,\n            onPointerMove,\n            onPointerUp: endDrag,\n            onPointerLeave: endDrag,\n            onDoubleClick: reset,\n            style: { cursor: isTransformed ? \"grab\" : \"default\", touchAction: \"none\" },\n        },\n    };\n}\n"],"mappings":"uBAYA,IAAM,EAAQ,EACR,EAAQ,GA4Bd,SAAgB,EAAW,EAA8B,CACrD,GAAM,CAAC,EAAG,IAAA,EAAQ,EAAA,SAAA,CAAuB,CAAE,EAAG,EAAG,EAAG,EAAG,EAAG,CAAE,CAAC,EACvD,GAAA,EAAO,EAAA,OAAA,CAAgE,IAAI,EAE3E,GAAA,EAAQ,EAAA,YAAA,KAAkB,EAAK,CAAE,EAAG,EAAG,EAAG,EAAG,EAAG,CAAE,CAAC,EAAG,CAAC,CAAC,EAExD,GAAA,EAAU,EAAA,YAAA,CAAa,GAAkB,CAC3C,EAAE,eAAe,EACjB,IAAM,EAAO,EAAE,cAAc,sBAAsB,EAC7C,EAAK,EAAE,QAAU,EAAK,KACtB,EAAK,EAAE,QAAU,EAAK,IAC5B,EAAM,GAAS,CACX,IAAM,EAAS,EAAE,OAAS,EAAI,KAAO,EAAI,KACnC,EAAI,KAAK,IAAI,EAAO,KAAK,IAAI,EAAO,EAAK,EAAI,CAAM,CAAC,EACpD,EAAQ,EAAI,EAAK,EACvB,MAAO,CAAE,IAAG,EAAG,GAAM,EAAK,EAAK,GAAK,EAAO,EAAG,GAAM,EAAK,EAAK,GAAK,CAAM,CAC7E,CAAC,CACL,EAAG,CAAC,CAAC,EAEC,GAAA,EAAgB,EAAA,YAAA,CAAa,GAAoB,CACnD,EAAK,QAAU,CAAE,EAAG,EAAE,QAAS,EAAG,EAAE,QAAS,GAAI,EAAG,GAAI,CAAE,EAC1D,EAAE,cAAc,oBAAoB,EAAE,SAAS,CACnD,EAAG,CAAC,CAAC,EAEC,GAAA,EAAgB,EAAA,YAAA,CAAa,GAAoB,CACnD,GAAI,CAAC,EAAK,QAAS,OACnB,IAAM,EAAK,EAAE,QAAU,EAAK,QAAQ,EAC9B,EAAK,EAAE,QAAU,EAAK,QAAQ,EACpC,EAAK,QAAQ,EAAI,EAAE,QACnB,EAAK,QAAQ,EAAI,EAAE,QACnB,EAAM,IAAU,CAAE,GAAG,EAAM,EAAG,EAAK,EAAI,EAAI,EAAG,EAAK,EAAI,CAAG,EAAE,CAChE,EAAG,CAAC,CAAC,EAEC,GAAA,EAAU,EAAA,YAAA,CAAa,GAAoB,CAC7C,EAAK,QAAU,KACf,EAAE,cAAc,wBAAwB,EAAE,SAAS,CACvD,EAAG,CAAC,CAAC,EAEL,GAAI,CAAC,EACD,MAAO,CACH,UAAW,GACX,KAAM,EACN,cAAe,GACf,QACA,SAAU,CAAC,CACf,EAGJ,IAAM,EAAgB,EAAE,IAAM,GAAK,EAAE,IAAM,GAAK,EAAE,IAAM,EACxD,MAAO,CACH,UAAW,aAAa,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,EAAE,GACjD,KAAM,EAAE,EACR,gBACA,QACA,SAAU,CACN,UACA,gBACA,gBACA,YAAa,EACb,eAAgB,EAChB,cAAe,EACf,MAAO,CAAE,OAAQ,EAAgB,OAAS,UAAW,YAAa,MAAO,CAC7E,CACJ,CACJ"}