@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 3.44 kB
Source Map (JSON)
{"version":3,"file":"useSheetDrag.mjs","names":[],"sources":["../../../src/base-ui/FloatingSheet/useSheetDrag.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\ninterface UseSheetDragOptions {\n enabled: boolean;\n onDragChange: (draggedDistance: number) => void;\n onDragEnd: (draggedDistance: number, velocity: number) => void;\n}\n\nexport function useSheetDrag({ onDragChange, onDragEnd, enabled }: UseSheetDragOptions) {\n const [isDragging, setIsDragging] = useState(false);\n const startY = useRef(0);\n const startTime = useRef(0);\n const draggingRef = useRef(false);\n\n // Store latest callbacks in refs to avoid stale closures in document listeners\n const onDragChangeRef = useRef(onDragChange);\n const onDragEndRef = useRef(onDragEnd);\n onDragChangeRef.current = onDragChange;\n onDragEndRef.current = onDragEnd;\n\n useEffect(() => {\n if (!draggingRef.current) return;\n\n const onMouseMove = (e: MouseEvent) => {\n e.preventDefault();\n const draggedDistance = startY.current - e.clientY;\n onDragChangeRef.current(draggedDistance);\n };\n\n const onMouseUp = (e: MouseEvent) => {\n draggingRef.current = false;\n setIsDragging(false);\n\n const draggedDistance = startY.current - e.clientY;\n const elapsed = Date.now() - startTime.current;\n const velocity = elapsed > 0 ? Math.abs(draggedDistance) / elapsed : 0;\n onDragEndRef.current(draggedDistance, velocity);\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n return () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n };\n }, [isDragging]);\n\n const onMouseDown = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!enabled) return;\n if (event.button !== 0) return; // left click only\n\n const target = event.target as HTMLElement;\n if (target.closest?.('[data-no-drag]')) return;\n\n event.preventDefault(); // prevent text selection during drag\n\n startY.current = event.clientY;\n startTime.current = Date.now();\n draggingRef.current = true;\n setIsDragging(true);\n },\n [enabled],\n );\n\n return {\n isDragging,\n handleProps: {\n onMouseDown,\n },\n };\n}\n"],"mappings":";;AAQA,SAAgB,aAAa,EAAE,cAAc,WAAW,WAAgC;CACtF,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,SAAS,OAAO,CAAC;CACvB,MAAM,YAAY,OAAO,CAAC;CAC1B,MAAM,cAAc,OAAO,KAAK;CAGhC,MAAM,kBAAkB,OAAO,YAAY;CAC3C,MAAM,eAAe,OAAO,SAAS;CACrC,gBAAgB,UAAU;CAC1B,aAAa,UAAU;CAEvB,gBAAgB;EACd,IAAI,CAAC,YAAY,SAAS;EAE1B,MAAM,eAAe,MAAkB;GACrC,EAAE,eAAe;GACjB,MAAM,kBAAkB,OAAO,UAAU,EAAE;GAC3C,gBAAgB,QAAQ,eAAe;EACzC;EAEA,MAAM,aAAa,MAAkB;GACnC,YAAY,UAAU;GACtB,cAAc,KAAK;GAEnB,MAAM,kBAAkB,OAAO,UAAU,EAAE;GAC3C,MAAM,UAAU,KAAK,IAAI,IAAI,UAAU;GACvC,MAAM,WAAW,UAAU,IAAI,KAAK,IAAI,eAAe,IAAI,UAAU;GACrE,aAAa,QAAQ,iBAAiB,QAAQ;EAChD;EAEA,SAAS,iBAAiB,aAAa,WAAW;EAClD,SAAS,iBAAiB,WAAW,SAAS;EAC9C,aAAa;GACX,SAAS,oBAAoB,aAAa,WAAW;GACrD,SAAS,oBAAoB,WAAW,SAAS;EACnD;CACF,GAAG,CAAC,UAAU,CAAC;CAoBf,OAAO;EACL;EACA,aAAa,EACX,aArBgB,aACjB,UAA4C;GAC3C,IAAI,CAAC,SAAS;GACd,IAAI,MAAM,WAAW,GAAG;GAGxB,IADe,MAAM,OACV,UAAU,gBAAgB,GAAG;GAExC,MAAM,eAAe;GAErB,OAAO,UAAU,MAAM;GACvB,UAAU,UAAU,KAAK,IAAI;GAC7B,YAAY,UAAU;GACtB,cAAc,IAAI;EACpB,GACA,CAAC,OAAO,CAMI,EACZ;CACF;AACF"}