{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "drag-and-drop-flow", "title": "Drag and Drop Flow", "description": "Simulated file drag into a dropzone followed by upload progress.", "dependencies": [ "remotion" ], "files": [ { "path": "registry/remocn/drag-and-drop-flow/index.tsx", "content": "\"use client\";\n\nimport {\n Easing,\n interpolate,\n interpolateColors,\n useCurrentFrame,\n useVideoConfig,\n} from \"remotion\";\n\nexport interface DragAndDropFlowProps {\n accent?: string;\n dropzoneLabel?: string;\n fileName?: string;\n background?: string;\n speed?: number;\n className?: string;\n}\n\nfunction FileIcon({ color }: { color: string }) {\n return (\n \n \n \n \n \n \n \n );\n}\n\nexport function DragAndDropFlow({\n accent = \"#0ea5e9\",\n dropzoneLabel = \"Drop file to upload\",\n fileName = \"design.fig\",\n background = \"#fafafa\",\n speed = 1,\n className,\n}: DragAndDropFlowProps) {\n const frame = useCurrentFrame() * speed;\n const { durationInFrames } = useVideoConfig();\n\n // Phase split\n const dragEnd = Math.round(durationInFrames * 0.45);\n const highlightEnd = Math.round(durationInFrames * 0.55);\n const progressEnd = durationInFrames;\n\n // Phase 1: file moves from start to center of dropzone\n const dragProgress = interpolate(frame, [0, dragEnd], [0, 1], {\n extrapolateRight: \"clamp\",\n easing: Easing.out(Easing.cubic),\n });\n\n const startX = -220;\n const startY = -120;\n const fileX = interpolate(dragProgress, [0, 1], [startX, 0]);\n const fileY = interpolate(dragProgress, [0, 1], [startY, 0]);\n\n // Phase 2: dropzone border highlights as file approaches\n const borderColor = interpolateColors(\n frame,\n [dragEnd - 10, highlightEnd],\n [\"#d4d4d8\", accent],\n );\n\n // Phase 3: file fades, progress bar grows\n const fileOpacity = interpolate(\n frame,\n [highlightEnd - 4, highlightEnd + 8],\n [1, 0],\n { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" },\n );\n\n const progressOpacity = interpolate(\n frame,\n [highlightEnd, highlightEnd + 6],\n [0, 1],\n { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" },\n );\n\n const progress = interpolate(\n frame,\n [highlightEnd, progressEnd - 4],\n [0, 100],\n { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" },\n );\n\n const dropzoneWidth = 420;\n const dropzoneHeight = 260;\n\n return (\n \n \n \n \n \n {dropzoneLabel}\n\n {/* Progress bar (after drop) */}\n \n \n {fileName}\n {Math.round(progress)}%\n \n \n \n \n \n \n\n {/* Animated file icon that moves into the dropzone */}\n \n \n \n \n );\n}\n", "type": "registry:component", "target": "components/remocn/drag-and-drop-flow.tsx" } ], "type": "registry:component" }