UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

143 lines (140 loc) 4.16 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { cn } from '../../lib/utilsComprehensive.js'; import { GripVertical } from 'lucide-react'; import { useState, useRef, useCallback, useEffect } from 'react'; import '../../primitives/GlassCore.js'; import '../../primitives/glass/GlassAdvanced.js'; import '../../primitives/OptimizedGlassCore.js'; import '../../primitives/glass/OptimizedGlassAdvanced.js'; import '../../primitives/MotionNative.js'; import { MotionFramer } from '../../primitives/motion/MotionFramer.js'; /** * GlassDraggable component * Makes any element draggable with visual feedback */ const GlassDraggable = ({ id, type, data, handle, children, disabled = false, onDragStart, onDragEnd, className, ...props }) => { const [isDragging, setIsDragging] = useState(false); const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 }); const dragRef = useRef(null); const dragStartPos = useRef({ x: 0, y: 0 }); const elementStartPos = useRef({ x: 0, y: 0 }); const dragData = { id, type, data }; // Handle mouse down const handleMouseDown = useCallback(e => { if (disabled) return; e.preventDefault(); const rect = dragRef.current?.getBoundingClientRect(); if (!rect) return; dragStartPos.current = { x: e.clientX, y: e.clientY }; elementStartPos.current = { x: rect.left, y: rect.top }; setIsDragging(true); setDragOffset({ x: 0, y: 0 }); onDragStart?.(dragData); // Add global event listeners document.addEventListener("mousemove", handleMouseMove); document.addEventListener("mouseup", handleMouseUp); }, [disabled, dragData, onDragStart]); // Handle mouse move const handleMouseMove = useCallback(e => { if (!isDragging) return; const deltaX = e.clientX - dragStartPos.current.x; const deltaY = e.clientY - dragStartPos.current.y; setDragOffset({ x: deltaX, y: deltaY }); }, [isDragging]); // Handle mouse up const handleMouseUp = useCallback(() => { if (!isDragging) return; setIsDragging(false); setDragOffset({ x: 0, y: 0 }); onDragEnd?.(dragData); // Remove global event listeners document.removeEventListener("mousemove", handleMouseMove); document.removeEventListener("mouseup", handleMouseUp); }, [isDragging, dragData, onDragEnd]); // Clean up event listeners useEffect(() => { return () => { document.removeEventListener("mousemove", handleMouseMove); document.removeEventListener("mouseup", handleMouseUp); }; }, [handleMouseMove, handleMouseUp]); // Default drag handle const defaultHandle = handle || jsx("div", { className: 'glass-flex glass-items-center glass-justify-center w-6 h-6 text-primary/60 hover:text-primary cursor-grab active:cursor-grabbing', children: jsx(GripVertical, { className: 'w-4 h-4' }) }); return jsxs(MotionFramer, { "data-glass-component": true, preset: "fadeIn", className: cn("relative cursor-grab active:cursor-grabbing select-none", isDragging && "z-50", disabled && "cursor-not-allowed opacity-50", className), style: isDragging ? { transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)`, zIndex: 50 } : undefined, ref: dragRef, onMouseDown: handleMouseDown, ...props, children: [jsx("div", { className: 'absolute glass-top-2 right-2 z-10', children: defaultHandle }), jsx("div", { className: cn("transition-all duration-200", isDragging && "shadow-2xl scale-105 rotate-2"), children: children }), isDragging && jsx("div", { className: 'fixed pointer-events-none z-40 opacity-50', style: { left: elementStartPos.current.x, top: elementStartPos.current.y, transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)` }, children: jsx("div", { className: 'scale-95', children: children }) })] }); }; export { GlassDraggable, GlassDraggable as default }; //# sourceMappingURL=GlassDraggable.js.map