@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 3.42 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,MAAM;CACnD,MAAM,SAAS,OAAO,EAAE;CACxB,MAAM,YAAY,OAAO,EAAE;CAC3B,MAAM,cAAc,OAAO,MAAM;CAGjC,MAAM,kBAAkB,OAAO,aAAa;CAC5C,MAAM,eAAe,OAAO,UAAU;AACtC,iBAAgB,UAAU;AAC1B,cAAa,UAAU;AAEvB,iBAAgB;AACd,MAAI,CAAC,YAAY,QAAS;EAE1B,MAAM,eAAe,MAAkB;AACrC,KAAE,gBAAgB;GAClB,MAAM,kBAAkB,OAAO,UAAU,EAAE;AAC3C,mBAAgB,QAAQ,gBAAgB;;EAG1C,MAAM,aAAa,MAAkB;AACnC,eAAY,UAAU;AACtB,iBAAc,MAAM;GAEpB,MAAM,kBAAkB,OAAO,UAAU,EAAE;GAC3C,MAAM,UAAU,KAAK,KAAK,GAAG,UAAU;GACvC,MAAM,WAAW,UAAU,IAAI,KAAK,IAAI,gBAAgB,GAAG,UAAU;AACrE,gBAAa,QAAQ,iBAAiB,SAAS;;AAGjD,WAAS,iBAAiB,aAAa,YAAY;AACnD,WAAS,iBAAiB,WAAW,UAAU;AAC/C,eAAa;AACX,YAAS,oBAAoB,aAAa,YAAY;AACtD,YAAS,oBAAoB,WAAW,UAAU;;IAEnD,CAAC,WAAW,CAAC;AAoBhB,QAAO;EACL;EACA,aAAa,EACX,aArBgB,aACjB,UAA4C;AAC3C,OAAI,CAAC,QAAS;AACd,OAAI,MAAM,WAAW,EAAG;AAGxB,OADe,MAAM,OACV,UAAU,iBAAiB,CAAE;AAExC,SAAM,gBAAgB;AAEtB,UAAO,UAAU,MAAM;AACvB,aAAU,UAAU,KAAK,KAAK;AAC9B,eAAY,UAAU;AACtB,iBAAc,KAAK;KAErB,CAAC,QAAQ,CAMI,EACZ;EACF"}