@@ -10,6 +10,7 @@ import type { ChainInfo, CustomColorRule, StructureInfo, Snapshot, Movie, ColorP
1010import LibraryModal from './components/LibraryModal' ;
1111import { ShareModal } from './components/ShareModal' ;
1212import { SequenceTrack } from './components/SequenceTrack' ;
13+ import { DragDropOverlay } from './components/DragDropOverlay' ;
1314import { OFFLINE_LIBRARY } from './data/library' ;
1415import { fetchPDBMetadata } from './utils/pdbUtils' ;
1516import type { PDBMetadata } from './types' ;
@@ -512,8 +513,53 @@ function App() {
512513 }
513514 } ;
514515
516+ // Drag and Drop State
517+ const [ isDragging , setIsDragging ] = useState ( false ) ;
518+
519+ const handleDragOver = ( e : React . DragEvent ) => {
520+ e . preventDefault ( ) ;
521+ setIsDragging ( true ) ;
522+ } ;
523+
524+ const handleDragEnter = ( e : React . DragEvent ) => {
525+ e . preventDefault ( ) ;
526+ setIsDragging ( true ) ;
527+ } ;
528+
529+ const handleDragLeave = ( e : React . DragEvent ) => {
530+ e . preventDefault ( ) ;
531+ if ( e . relatedTarget === null ) {
532+ setIsDragging ( false ) ;
533+ }
534+ } ;
535+
536+ const handleDrop = ( e : React . DragEvent ) => {
537+ e . preventDefault ( ) ;
538+ setIsDragging ( false ) ;
539+
540+ const files = e . dataTransfer . files ;
541+ if ( files && files . length > 0 ) {
542+ const droppedFile = files [ 0 ] ;
543+ const validExtensions = [ '.pdb' , '.cif' , '.ent' ] ;
544+ const fileExt = droppedFile . name . substring ( droppedFile . name . lastIndexOf ( '.' ) ) . toLowerCase ( ) ;
545+
546+ if ( validExtensions . includes ( fileExt ) ) {
547+ handleUpload ( droppedFile ) ; // Reuse existing upload handler
548+ } else {
549+ alert ( "Invalid file type. Please drop a .pdb, .cif, or .ent file." ) ;
550+ }
551+ }
552+ } ;
553+
515554 return (
516- < main className = { `w-full h-full relative overflow-hidden transition-colors duration-300 ${ isLightMode ? 'bg-slate-50 text-slate-900' : 'bg-neutral-950 text-white' } ` } >
555+ < main
556+ className = { `w-full h-full relative overflow-hidden transition-colors duration-300 ${ isLightMode ? 'bg-slate-50 text-slate-900' : 'bg-neutral-950 text-white' } ` }
557+ onDragOver = { handleDragOver }
558+ onDragEnter = { handleDragEnter }
559+ onDragLeave = { handleDragLeave }
560+ onDrop = { handleDrop }
561+ >
562+ < DragDropOverlay isDragging = { isDragging } />
517563
518564 < LibraryModal
519565 isOpen = { isLibraryOpen }
0 commit comments