瀏覽代碼

`<Dashboard/>`, `<DragDrop/>`, `drop-target` - new anti-flickering solution (#5326)

* `<Dashboard/>`, `drag-drop`, `drop-target` - switch from `setTimeout()` to `css { pointer-events: none }`

* <DragDrop/> - remove leftover `return`

* http://localhost:5173 - remove padding-right in { inline: true } mode

Because it makes working with drops confusing, dropping behaviour thinks uppy spans 100% of the page

* `<DragDrop/>` - remove `{ pointer-events: none }`

`<DragDrop/> flickers in Chrome when we DO have `{ pointer-events: none }`, because it doesn't have any child elements.
Evgenia Karunus 9 月之前
父節點
當前提交
0291c631c5

+ 1 - 12
packages/@uppy/dashboard/src/Dashboard.tsx

@@ -259,8 +259,6 @@ export default class Dashboard<M extends Meta, B extends Body> extends UIPlugin<
     typeof setTimeout
   >
 
-  private removeDragOverClassTimeout!: ReturnType<typeof setTimeout>
-
   constructor(uppy: Uppy<M, B>, opts?: DashboardOptions<M, B>) {
     const autoOpen = opts?.autoOpen ?? null
     super(uppy, { ...defaultOptions, ...opts, autoOpen })
@@ -813,7 +811,6 @@ export default class Dashboard<M extends Meta, B extends Body> extends UIPlugin<
       !this.uppy.getState().allowNewUpload
     ) {
       event.dataTransfer!.dropEffect = 'none' // eslint-disable-line no-param-reassign
-      clearTimeout(this.removeDragOverClassTimeout)
       return
     }
 
@@ -822,7 +819,6 @@ export default class Dashboard<M extends Meta, B extends Body> extends UIPlugin<
     // browser, https://github.com/transloadit/uppy/issues/1978).
     event.dataTransfer!.dropEffect = 'copy' // eslint-disable-line no-param-reassign
 
-    clearTimeout(this.removeDragOverClassTimeout)
     this.setPluginState({ isDraggingOver: true })
 
     this.opts.onDragOver?.(event)
@@ -832,12 +828,7 @@ export default class Dashboard<M extends Meta, B extends Body> extends UIPlugin<
     event.preventDefault()
     event.stopPropagation()
 
-    clearTimeout(this.removeDragOverClassTimeout)
-    // Timeout against flickering, this solution is taken from drag-drop library.
-    // Solution with 'pointer-events: none' didn't work across browsers.
-    this.removeDragOverClassTimeout = setTimeout(() => {
-      this.setPluginState({ isDraggingOver: false })
-    }, 50)
+    this.setPluginState({ isDraggingOver: false })
 
     this.opts.onDragLeave?.(event)
   }
@@ -846,8 +837,6 @@ export default class Dashboard<M extends Meta, B extends Body> extends UIPlugin<
     event.preventDefault()
     event.stopPropagation()
 
-    clearTimeout(this.removeDragOverClassTimeout)
-
     this.setPluginState({ isDraggingOver: false })
 
     // Let any acquirer plugin (Url/Webcam/etc.) handle drops to the root

+ 2 - 0
packages/@uppy/dashboard/src/style.scss

@@ -854,6 +854,8 @@
 .uppy-Dashboard.uppy-Dashboard--isDraggingOver {
   .uppy-Dashboard-dropFilesHereHint {
     visibility: visible;
+    // prevents flickering (https://stackoverflow.com/a/18582960/3192470)
+    pointer-events: none;
   }
 
   .uppy-DashboardContent-bar,

+ 1 - 12
packages/@uppy/drag-drop/src/DragDrop.tsx

@@ -44,8 +44,6 @@ export default class DragDrop<M extends Meta, B extends Body> extends UIPlugin<
   // Check for browser dragDrop support
   private isDragDropSupported = isDragDropSupported()
 
-  private removeDragOverClassTimeout!: ReturnType<typeof setTimeout>
-
   private fileInputRef!: HTMLInputElement
 
   constructor(uppy: Uppy<M, B>, opts?: DragDropOptions) {
@@ -111,7 +109,6 @@ export default class DragDrop<M extends Meta, B extends Body> extends UIPlugin<
     if (!hasFiles || !allowNewUpload) {
       // eslint-disable-next-line no-param-reassign
       event.dataTransfer!.dropEffect = 'none'
-      clearTimeout(this.removeDragOverClassTimeout)
       return
     }
 
@@ -122,7 +119,6 @@ export default class DragDrop<M extends Meta, B extends Body> extends UIPlugin<
     // eslint-disable-next-line no-param-reassign
     event.dataTransfer!.dropEffect = 'copy'
 
-    clearTimeout(this.removeDragOverClassTimeout)
     this.setPluginState({ isDraggingOver: true })
 
     this.opts.onDragOver?.(event)
@@ -132,12 +128,7 @@ export default class DragDrop<M extends Meta, B extends Body> extends UIPlugin<
     event.preventDefault()
     event.stopPropagation()
 
-    clearTimeout(this.removeDragOverClassTimeout)
-    // Timeout against flickering, this solution is taken from drag-drop library.
-    // Solution with 'pointer-events: none' didn't work across browsers.
-    this.removeDragOverClassTimeout = setTimeout(() => {
-      this.setPluginState({ isDraggingOver: false })
-    }, 50)
+    this.setPluginState({ isDraggingOver: false })
 
     this.opts.onDragLeave?.(event)
   }
@@ -145,9 +136,7 @@ export default class DragDrop<M extends Meta, B extends Body> extends UIPlugin<
   private handleDrop = async (event: DragEvent) => {
     event.preventDefault()
     event.stopPropagation()
-    clearTimeout(this.removeDragOverClassTimeout)
 
-    // Remove dragover class
     this.setPluginState({ isDraggingOver: false })
 
     const logDropError = (error: any) => {

+ 2 - 13
packages/@uppy/drop-target/src/index.ts

@@ -42,8 +42,6 @@ export default class DropTarget<
 > {
   static VERSION = packageJson.version
 
-  private removeDragOverClassTimeout?: ReturnType<typeof setTimeout>
-
   private nodes?: Array<HTMLElement>
 
   constructor(uppy: Uppy<M, B>, opts?: DropTargetOptions) {
@@ -79,7 +77,6 @@ export default class DropTarget<
 
     event.preventDefault()
     event.stopPropagation()
-    clearTimeout(this.removeDragOverClassTimeout)
 
     // Remove dragover class
     ;(event.currentTarget as HTMLElement)?.classList.remove('uppy-is-drag-over')
@@ -127,8 +124,6 @@ export default class DropTarget<
     // (and prevent browsers from interpreting this as files being _moved_ into the browser,
     // https://github.com/transloadit/uppy/issues/1978)
     event.dataTransfer.dropEffect = 'copy' // eslint-disable-line no-param-reassign
-
-    clearTimeout(this.removeDragOverClassTimeout)
     ;(event.currentTarget as HTMLElement).classList.add('uppy-is-drag-over')
     this.setPluginState({ isDraggingOver: true })
     this.opts.onDragOver?.(event)
@@ -142,15 +137,9 @@ export default class DropTarget<
     event.preventDefault()
     event.stopPropagation()
 
-    const { currentTarget } = event
+    this.setPluginState({ isDraggingOver: false })
+    ;(event.currentTarget as HTMLElement)?.classList.remove('uppy-is-drag-over')
 
-    clearTimeout(this.removeDragOverClassTimeout)
-    // Timeout against flickering, this solution is taken from drag-drop library.
-    // Solution with 'pointer-events: none' didn't work across browsers.
-    this.removeDragOverClassTimeout = setTimeout(() => {
-      ;(currentTarget as HTMLElement).classList.remove('uppy-is-drag-over')
-      this.setPluginState({ isDraggingOver: false })
-    }, 50)
     this.opts.onDragLeave?.(event)
   }
 

+ 2 - 0
packages/@uppy/drop-target/src/style.scss

@@ -11,4 +11,6 @@
   background-color: rgba($gray-200, 0.5);
   border: 5px dashed $gray-400;
   content: '';
+  // prevents flickering (https://stackoverflow.com/a/18582960/3192470)
+  pointer-events: none;
 }

+ 6 - 1
private/dev/index.html

@@ -7,7 +7,12 @@
     <link rel="icon" type="image/png" href="https://uppy.io/img/logo.svg" />
     <style>
       main {
-        padding-top: 100px;
+        display: block;
+        width: fit-content;
+        margin: 100px auto;
+      }
+
+      h1 {
         text-align: center;
       }