@@ -16,8 +16,17 @@ export default class extends Controller {
1616 declare readonly previewClearButtonTarget : HTMLButtonElement ;
1717 declare readonly previewFilenameTarget : HTMLDivElement ;
1818 declare readonly previewImageTarget : HTMLDivElement ;
19-
20- static targets = [ 'input' , 'placeholder' , 'preview' , 'previewClearButton' , 'previewFilename' , 'previewImage' ] ;
19+ declare readonly containerTarget : HTMLDivElement ;
20+
21+ static targets = [
22+ 'container' ,
23+ 'input' ,
24+ 'placeholder' ,
25+ 'preview' ,
26+ 'previewClearButton' ,
27+ 'previewFilename' ,
28+ 'previewImage' ,
29+ ] ;
2130
2231 initialize ( ) {
2332 this . clear = this . clear . bind ( this ) ;
@@ -56,38 +65,60 @@ export default class extends Controller {
5665 this . inputTarget . value = '' ;
5766 this . inputTarget . style . display = 'block' ;
5867 this . placeholderTarget . style . display = 'block' ;
68+ this . previewTarget . innerHTML = '' ;
5969 this . previewTarget . style . display = 'none' ;
60- this . previewImageTarget . style . display = 'none' ;
61- this . previewImageTarget . style . backgroundImage = 'none' ;
62- this . previewFilenameTarget . textContent = '' ;
6370
6471 this . dispatchEvent ( 'clear' ) ;
6572 }
6673
6774 onInputChange ( event : any ) {
68- const file = event . target . files [ 0 ] ;
69- if ( typeof file === 'undefined' ) {
75+ const files = event . target . files ;
76+ if ( files . length === 0 ) {
77+ this . previewClearButtonTarget . style . display = 'none' ;
7078 return ;
7179 }
7280
7381 // Hide the input and placeholder
7482 this . inputTarget . style . display = 'none' ;
7583 this . placeholderTarget . style . display = 'none' ;
7684
77- // Show the filename in preview
78- this . previewFilenameTarget . textContent = file . name ;
79- this . previewTarget . style . display = 'flex' ;
85+ // Clear previous previews
86+ this . previewTarget . innerHTML = '' ;
87+
88+ for ( const file of files ) {
89+ // Create a container for each file preview
90+ const filePreviewContainer = document . createElement ( 'div' ) ;
91+ filePreviewContainer . classList . add ( 'dropzone-preview-file' ) ;
92+
93+ // Create a filename preview element
94+ const fileNameElement = document . createElement ( 'span' ) ;
95+ fileNameElement . textContent = file . name ;
96+ filePreviewContainer . appendChild ( fileNameElement ) ;
97+
98+ // Create an image preview element if the file is an image, else a default svg file icon
99+ if ( file . type ) {
100+ const imagePreviewElement = document . createElement ( 'div' ) ;
101+ if ( file . type . indexOf ( 'image' ) !== - 1 ) {
102+ imagePreviewElement . classList . add ( 'dropzone-preview-image' ) ;
103+ this . _populateImagePreview ( file , imagePreviewElement ) ;
104+ } else {
105+ imagePreviewElement . classList . add ( 'dropzone-preview-svg' ) ;
106+ }
107+
108+ filePreviewContainer . appendChild ( imagePreviewElement ) ;
109+ }
110+
111+ // Append the file preview container to the main preview target
112+ this . previewTarget . appendChild ( filePreviewContainer ) ;
80113
81- // If the file is an image, load it and display it as preview
82- this . previewImageTarget . style . display = 'none' ;
83- if ( file . type && file . type . indexOf ( 'image' ) !== - 1 ) {
84- this . _populateImagePreview ( file ) ;
114+ this . dispatchEvent ( 'change' , file ) ;
85115 }
86116
87- this . dispatchEvent ( 'change' , file ) ;
117+ // Show the preview container
118+ this . previewTarget . style . display = 'grid' ;
88119 }
89120
90- _populateImagePreview ( file : Blob ) {
121+ _populateImagePreview ( file : Blob , imagePreviewElement : HTMLElement ) {
91122 if ( typeof FileReader === 'undefined' ) {
92123 // FileReader API not available, skip
93124 return ;
@@ -96,8 +127,8 @@ export default class extends Controller {
96127 const reader = new FileReader ( ) ;
97128
98129 reader . addEventListener ( 'load' , ( event : any ) => {
99- this . previewImageTarget . style . display = 'block' ;
100- this . previewImageTarget . style . backgroundImage = `url(" ${ event . target . result } ")` ;
130+ imagePreviewElement . style . backgroundImage = `url(" ${ event . target . result } ")` ;
131+ imagePreviewElement . style . display = 'block' ;
101132 } ) ;
102133
103134 reader . readAsDataURL ( file ) ;
@@ -107,6 +138,7 @@ export default class extends Controller {
107138 this . inputTarget . style . display = 'block' ;
108139 this . placeholderTarget . style . display = 'block' ;
109140 this . previewTarget . style . display = 'none' ;
141+ this . containerTarget . classList . add ( 'dropzone-on-drag-enter' ) ;
110142 }
111143
112144 onDragLeave ( event : any ) {
@@ -117,6 +149,7 @@ export default class extends Controller {
117149 this . inputTarget . style . display = 'none' ;
118150 this . placeholderTarget . style . display = 'none' ;
119151 this . previewTarget . style . display = 'block' ;
152+ this . containerTarget . classList . add ( 'dropzone-on-drag-leave' ) ;
120153 }
121154 }
122155
0 commit comments