11import template from 'lodash.template' ;
2+ import { StyleHelpers } from './helpers' ;
3+ import styles from './FileUploadWidget.scss' ;
24
35
46export class FileUploadWidget {
@@ -12,6 +14,8 @@ export class FileUploadWidget {
1214 private readonly initialData : Object [ ] ;
1315 private readonly initialRequired : boolean ;
1416 private readonly maxUploadSize : number ;
17+ private readonly baseSelector = 'django-formset .dj-control-panel:has(input[type="file"])' ;
18+ private readonly styleSheet : CSSStyleSheet ;
1519 public readonly inputElement : HTMLInputElement ;
1620 public uploadedFiles : Object [ ] ;
1721
@@ -44,6 +48,7 @@ export class FileUploadWidget {
4448 this . observer = new MutationObserver ( mutationsList => this . attributesChanged ( mutationsList ) ) ;
4549 this . observer . observe ( this . inputElement , { attributes : true } ) ;
4650 this . chooseFileButton . disabled = inputElement . disabled ;
51+ this . styleSheet = StyleHelpers . stylesAreInstalled ( this . baseSelector ) ?? this . transferStyles ( ) ;
4752
4853 const initialData = document . getElementById ( `initial_${ inputElement . id } ` ) ;
4954 if ( initialData ?. textContent ) {
@@ -228,6 +233,43 @@ export class FileUploadWidget {
228233 }
229234 }
230235
236+ private transferStyles ( ) : CSSStyleSheet {
237+ const declaredStyles = document . createElement ( 'style' ) ;
238+ declaredStyles . innerText = styles ;
239+ document . head . appendChild ( declaredStyles ) ;
240+ if ( ! declaredStyles . sheet )
241+ throw new Error ( "Could not create <style> element" ) ;
242+ this . inputElement . style . transition = 'none' ; // prevent transition while pilfering styles
243+ let loaded = false ;
244+ for ( let index = 0 ; declaredStyles . sheet && index < declaredStyles . sheet . cssRules . length ; index ++ ) {
245+ const cssRule = declaredStyles . sheet . cssRules . item ( index ) as CSSStyleRule ;
246+ const selector = cssRule . selectorText . trim ( ) ;
247+ let extraStyles = '' ;
248+ switch ( selector ) {
249+ case this . baseSelector :
250+ loaded = true ;
251+ break ;
252+ default :
253+ break ;
254+ }
255+ if ( extraStyles ) {
256+ declaredStyles . sheet . insertRule ( `${ selector } {${ extraStyles } }` , ++ index ) ;
257+ }
258+ }
259+ this . inputElement . style . transition = '' ;
260+ StyleHelpers . pushMediaQueryStyles (
261+ declaredStyles . sheet ,
262+ this . baseSelector ,
263+ {
264+ '--outline-color' : 'outline-color' ,
265+ } ,
266+ this . inputElement ,
267+ ) ;
268+ if ( ! loaded )
269+ throw new Error ( `Could not load styles for ${ this . baseSelector } ` ) ;
270+ return declaredStyles . sheet as CSSStyleSheet ;
271+ }
272+
231273 public inProgress ( ) : boolean {
232274 return ! ! this . inputElement . files && this . inputElement . files . length > 0 && ! this . uploadedFiles . length ;
233275 }
0 commit comments