Skip to content

Commit

Permalink
Fix: dropzone doesn't receive drop event (#5415)
Browse files Browse the repository at this point in the history
* Fix: dropzone doesn't get drop events

* Improve

* Changelog

* Add test
  • Loading branch information
OEvgeny authored Jan 29, 2025
1 parent 1f5e557 commit b40802d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
- Fixed math parsing that could cause Web Chat to hang when processing certain LaTeX expressions, in PR [#5377](https://github.com/microsoft/BotFramework-WebChat/pull/5377), by [@OEvgeny](https://github.com/OEvgeny)
- Fixed long math formula should be scrollable, in PR [#5380](https://github.com/microsoft/BotFramework-WebChat/pull/5380), by [@compulim](https://github.com/compulim)
- Fixed [#4948](https://github.com/microsoft/BotFramework-WebChat/issues/4948). Microphone should stop after initial silence, in PR [#5385](https://github.com/microsoft/BotFramework-WebChat/pull/5385)
- Fixed [#5390](https://github.com/microsoft/BotFramework-WebChat/issues/5390). Fixed drop zone remaining visible when file is dropped outside of the zone, in PR [#5394](https://github.com/microsoft/BotFramework-WebChat/pull/5394), by [@OEvgeny](https://github.com/OEvgeny)
- Fixed [#5390](https://github.com/microsoft/BotFramework-WebChat/issues/5390). Fixed drop zone remaining visible when file is dropped outside of the zone, in PR [#5394](https://github.com/microsoft/BotFramework-WebChat/pull/5394), in PR [#5415](https://github.com/microsoft/BotFramework-WebChat/pull/5415), by [@OEvgeny](https://github.com/OEvgeny)

# Removed

Expand Down
12 changes: 12 additions & 0 deletions __tests__/html/fluentTheme/dragAndDrop.upload.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@
// THEN: Should render the drop zone.
await host.snapshot();

// WHEN: Dragging a file over the document.
const dragOverDocumentEvent = new DragEvent('dragover', {
bubbles: true,
cancelable: true,
dataTransfer
});

document.dispatchEvent(dragOverDocumentEvent);

// THEN: The default browser behavior should be prevented.
await pageConditions.became('DragOver event preventDefault is called', () => dragOverDocumentEvent.defaultPrevented, 1000);

// WHEN: Dropping out of the drop zone.
const dropEvent1 = new DragEvent('drop', {
bubbles: true,
Expand Down
30 changes: 25 additions & 5 deletions packages/fluent-theme/src/components/dropZone/DropZone.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { hooks } from 'botframework-webchat-component';
import cx from 'classnames';
import React, { memo, useCallback, useEffect, useRef, useState, type DragEventHandler } from 'react';
import React, {
memo,
useCallback,
useEffect,
useRef,
useState,
type DragEvent as ReactDragEvent,
type DragEventHandler
} from 'react';
import { useRefFrom } from 'use-ref-from';

import { AddDocumentIcon } from '../../icons';
Expand All @@ -10,8 +18,14 @@ import { useStyles } from '../../styles';

const { useLocalizer } = hooks;

const handleDragOver: DragEventHandler<HTMLDivElement> = event => {
// This is for preventing the browser from opening the dropped file in a new tab.
const handleDragOver = (event: ReactDragEvent<unknown> | DragEvent) => {
// Prevent default dragover behavior to enable drop event triggering.
// Browsers require this to fire subsequent drop events - without it,
// they would handle the drop directly (e.g., open files in new tabs).
// This is needed regardless of whether we prevent default drop behavior,
// as it ensures our dropzone receives the drop event first. If we allow
// default drop handling (by not calling preventDefault there), the browser
// will still process the drop after our event handlers complete.
event.preventDefault();
};

Expand Down Expand Up @@ -47,6 +61,8 @@ const DropZone = (props: { readonly onFilesAdded: (files: File[]) => void }) =>
let entranceCounter = 0;

const handleDragEnter = (event: DragEvent) => {
document.addEventListener('dragover', handleDragOver);

entranceCounter++;

if (isFilesTransferEvent(event)) {
Expand All @@ -63,7 +79,10 @@ const DropZone = (props: { readonly onFilesAdded: (files: File[]) => void }) =>
const handleDragLeave = () => --entranceCounter <= 0 && setDropZoneState(false);

const handleDragEnd = () => {
document.removeEventListener('dragover', handleDragOver);

entranceCounter = 0;

setDropZoneState(false);
};

Expand All @@ -73,15 +92,16 @@ const DropZone = (props: { readonly onFilesAdded: (files: File[]) => void }) =>
}
};

document.addEventListener('dragend', handleDragEnd);
document.addEventListener('dragenter', handleDragEnter);
document.addEventListener('dragleave', handleDragLeave);
document.addEventListener('dragend', handleDragEnd);
document.addEventListener('drop', handleDocumentDrop);

return () => {
document.removeEventListener('dragend', handleDragEnd);
document.removeEventListener('dragenter', handleDragEnter);
document.removeEventListener('dragleave', handleDragLeave);
document.removeEventListener('dragend', handleDragEnd);
document.removeEventListener('dragover', handleDragOver);
document.removeEventListener('drop', handleDocumentDrop);
};
}, [setDropZoneState]);
Expand Down

0 comments on commit b40802d

Please sign in to comment.