Просмотр исходного кода

`.handleInputChange()` - use `.currentTarget`; clear the input using `''` (#5381)

* everywhere - proper typing, `target` => `currentTarget`, `null` => `''`

* everywhere - update the comment id
Evgenia Karunus 6 месяцев назад
Родитель
Сommit
9a4b8ef4db

+ 5 - 2
packages/@uppy/dashboard/src/Dashboard.tsx

@@ -17,6 +17,7 @@ import toArray from '@uppy/utils/lib/toArray'
 import getDroppedFiles from '@uppy/utils/lib/getDroppedFiles'
 import { defaultPickerIcon } from '@uppy/provider-views'
 
+import type { TargetedEvent } from 'preact/compat'
 import { nanoid } from 'nanoid/non-secure'
 import memoizeOne from 'memoize-one'
 import * as trapFocus from './utils/trapFocus.ts'
@@ -766,9 +767,11 @@ export default class Dashboard<M extends Meta, B extends Body> extends UIPlugin<
     }
   }
 
-  private handleInputChange = (event: InputEvent) => {
+  private handleInputChange = (
+    event: TargetedEvent<HTMLInputElement, Event>,
+  ) => {
     event.preventDefault()
-    const files = toArray((event.target as HTMLInputElement).files!)
+    const files = toArray(event.currentTarget.files || [])
     if (files.length > 0) {
       this.uppy.log('[Dashboard] Files selected through input')
       this.addFiles(files)

+ 7 - 8
packages/@uppy/dashboard/src/components/AddFiles.tsx

@@ -31,16 +31,15 @@ class AddFiles extends Component {
     this.mobilePhotoFileInput.click()
   }
 
-  private onFileInputChange = (event: $TSFixMe) => {
+  private onFileInputChange = (
+    event: TargetedEvent<HTMLInputElement, Event>,
+  ) => {
     this.props.handleInputChange(event)
 
-    // We clear the input after a file is selected, because otherwise
-    // change event is not fired in Chrome and Safari when a file
-    // with the same name is selected.
-    // ___Why not use value="" on <input/> instead?
-    //    Because if we use that method of clearing the input,
-    //    Chrome will not trigger change if we drop the same file twice (Issue #768).
-    event.target.value = null // eslint-disable-line no-param-reassign
+    // Clear the input so that Chrome/Safari/etc. can detect file section when the same file is repeatedly selected
+    // (see https://github.com/transloadit/uppy/issues/768#issuecomment-2264902758)
+    // eslint-disable-next-line no-param-reassign
+    event.currentTarget.value = ''
   }
 
   private renderHiddenInput = (isFolder: $TSFixMe, refCallback: $TSFixMe) => {

+ 6 - 11
packages/@uppy/drag-drop/src/DragDrop.tsx

@@ -2,7 +2,7 @@ import { UIPlugin, type Uppy } from '@uppy/core'
 import type { DefinePluginOpts } from '@uppy/core/lib/BasePlugin.js'
 import type { UIPluginOptions } from '@uppy/core/lib/UIPlugin.js'
 import type { Body, Meta } from '@uppy/utils/lib/UppyFile'
-import type { ChangeEvent } from 'preact/compat'
+import type { TargetedEvent } from 'preact/compat'
 import toArray from '@uppy/utils/lib/toArray'
 import isDragDropSupported from '@uppy/utils/lib/isDragDropSupported'
 import getDroppedFiles from '@uppy/utils/lib/getDroppedFiles'
@@ -80,22 +80,17 @@ export default class DragDrop<M extends Meta, B extends Body> extends UIPlugin<
     }
   }
 
-  private onInputChange = (event: ChangeEvent) => {
-    const files = toArray((event.target as HTMLInputElement).files!)
+  private onInputChange = (event: TargetedEvent<HTMLInputElement, Event>) => {
+    const files = toArray(event.currentTarget.files || [])
     if (files.length > 0) {
       this.uppy.log('[DragDrop] Files selected through input')
       this.addFiles(files)
     }
 
-    // We clear the input after a file is selected, because otherwise
-    // change event is not fired in Chrome and Safari when a file
-    // with the same name is selected.
-    // ___Why not use value="" on <input/> instead?
-    //    Because if we use that method of clearing the input,
-    //    Chrome will not trigger change if we drop the same file twice (Issue #768).
-    // @ts-expect-error TS freaks out, but this is fine
+    // Clear the input so that Chrome can detect file section when the same file is repeatedly selected
+    // (see https://github.com/transloadit/uppy/issues/768#issuecomment-2264902758)
     // eslint-disable-next-line no-param-reassign
-    event.target.value = null
+    event.currentTarget.value = ''
   }
 
   private handleDragOver = (event: DragEvent) => {

+ 7 - 11
packages/@uppy/file-input/src/FileInput.tsx

@@ -4,7 +4,7 @@ import { UIPlugin, Uppy, type UIPluginOptions } from '@uppy/core'
 import toArray from '@uppy/utils/lib/toArray'
 import type { Body, Meta } from '@uppy/utils/lib/UppyFile'
 import type { DefinePluginOpts } from '@uppy/core/lib/BasePlugin.js'
-
+import type { TargetedEvent } from 'preact/compat'
 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 // @ts-ignore We don't want TS to generate types for the package.json
 import packageJson from '../package.json'
@@ -65,19 +65,15 @@ export default class FileInput<M extends Meta, B extends Body> extends UIPlugin<
     }
   }
 
-  private handleInputChange(event: Event) {
+  private handleInputChange(event: TargetedEvent<HTMLInputElement, Event>) {
     this.uppy.log('[FileInput] Something selected through input...')
-    const files = toArray((event.target as HTMLFileInputElement).files)
+    const files = toArray(event.currentTarget.files || [])
     this.addFiles(files)
 
-    // We clear the input after a file is selected, because otherwise
-    // change event is not fired in Chrome and Safari when a file
-    // with the same name is selected.
-    // ___Why not use value="" on <input/> instead?
-    //    Because if we use that method of clearing the input,
-    //    Chrome will not trigger change if we drop the same file twice (Issue #768).
-    // @ts-expect-error yes
-    event.target.value = null // eslint-disable-line no-param-reassign
+    // Clear the input so that Chrome can detect file section when the same file is repeatedly selected
+    // (see https://github.com/transloadit/uppy/issues/768#issuecomment-2264902758)
+    // eslint-disable-next-line no-param-reassign
+    event.currentTarget.value = ''
   }
 
   private handleClick() {