feat: Add clipboard paste and drag-and-drop file support to both themes#5829
Conversation
Add paste and drag-and-drop support for file attachments in the send box, consistent across both basic and fluent themes. Users can now paste files from the clipboard or drag files onto the chat to attach them. - Basic theme: Add onPaste handler, DropZone component, and handleAddFiles helper - Fluent theme: Add onPaste handler (drag-and-drop already existed) - All file types supported, respects disableFileUpload style option Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: Destructure props in DropZone to satisfy ESLint rule Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: Address PR review feedback - Gate paste and drop on uiState === 'disabled' in both themes - Respect sendAttachmentOn: 'attach' in basic theme handleAddFiles - Hide DropZone when UI is disabled Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> test: Add E2E tests for paste and drag-and-drop in basic theme - Add pasteFile.html: tests pasting files into send box, verifies attachment bar shows items and multiple pastes accumulate - Add dragAndDrop.upload.html: tests drag-and-drop flow in basic theme, verifies drop zone appears, files are attached on drop - Add sendBoxDropZone test ID to basic theme DropZone component Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: Remove snapshot assertions from new E2E tests New tests cannot include baseline snapshot images without running in the CI Docker environment. Use assertion-only checks instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> test: Restore snapshot assertions for consistency with existing tests Baseline snapshot images need to be generated in the CI Docker environment. The tests will fail until baselines are committed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> test: Add baseline snapshots and fix pasteFile test - Generate baseline snapshot images for both E2E tests using Docker Selenium environment - Fix pasteFile test to use text/plain files instead of fake image/png to avoid thumbnail decode errors in browser Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: Regenerate snapshots via jest-server for correct 360x640 viewport Previous snapshots used wrong viewport (780x441) because they bypassed the jest-server which sets the window to 360x640. Now generated through the jest-server proxy matching CI configuration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: Update snapshots for position:relative on send box main div The DropZone component requires position:relative on .webchat__send-box__main for its absolute positioning overlay. This causes minor rendering differences in existing snapshot tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Check WIP Changelog and use js ext
0f57dd3 to
fd39635
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds clipboard paste and drag-and-drop file upload support to the basic theme's send box, mirroring the behavior already present in the fluent theme. To avoid duplicating logic, the existing drag-and-drop state-management code is extracted from fluent-theme/.../DropZone.tsx into a shared useFileDropZone hook in the react-hooks package, which both themes now consume. A new basic-theme DropZone overlay component is layered onto BasicSendBox via CSS grid named areas, and handlePaste/handleAddFiles callbacks integrate with useMakeThumbnail, useSendBoxAttachments, useSubmit, and the sendAttachmentOn/disableFileUpload/uiState options.
Changes:
- Extract document-level drag/drop state and handlers into shared
useFileDropZonehook and re-export it through component/bundle hook surfaces. - Add basic-theme
DropZone.tsxoverlay and wire paste + drop file handling (with thumbnail generation and auto-submit) intoBasicSendBox. - Add fluent-theme
onPastehandler and add HTML2 e2e tests covering both paste and drag-and-drop flows.
Reviewed changes
Copilot reviewed 13 out of 28 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-hooks/src/useFileDropZone.ts | New shared hook centralizing drag-enter/leave/over/drop document listeners and drop-zone state. |
| packages/react-hooks/src/index.ts | Exports the new hook and DropZoneState type. |
| packages/fluent-theme/src/components/dropZone/DropZone.tsx | Removes inlined drag logic and consumes useFileDropZone. |
| packages/fluent-theme/src/components/sendBox/SendBox.tsx | Adds onPaste handler gated on disableFileUpload/uiState. |
| packages/component/src/SendBox/DropZone.tsx | New basic-theme drop zone overlay using shared hook and emotion styles. |
| packages/component/src/SendBox/BasicSendBox.tsx | CSS grid layout, handleAddFiles, handlePaste, and conditional <DropZone> rendering. |
| packages/component/src/testIds.ts | Adds sendBoxDropZone test ID. |
| packages/component/src/boot/hook.ts | Re-exports useFileDropZone and DropZoneState. |
| packages/component/package.json | Adds sed post-processing of DropZoneState in rolled-up .d.ts. |
| packages/bundle/src/boot/actual/hook/minimal.ts | Re-exports the new hook/type from the bundle. |
| CHANGELOG.md | Adds changelog entry. |
| tests/html2/basic/pasteFile.html | New e2e test for clipboard paste. |
| tests/html2/basic/dragAndDrop.upload.html | New e2e test for drag-and-drop into basic theme. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Given the way e2e tests around the drag-and-drop are written I think, current coverage is already sufficient: no multiple files and no folder will be added for the PR. |
Changelog Entry
Description
This PR adds clipboard paste and drag-and-drop file upload support to Web Chat's send box in basic theme. The implementation creates a reusable
useFileDropZonehook to share drag-and-drop state management logic between themes ensuring consistent behavior.Design
The implementation follows a shared-logic pattern with theme-specific UI:
Shared State Management: Created
useFileDropZonehook in@msinternal/botframework-webchat-react-hooksto manage document-level drag events and drop zone statefalse,'visible', or'droppable') based on drag targetCSS Grid Stacking: Basic theme uses CSS grid with named areas to stack the drop zone overlay on top of the send box without
position: relative/absolute'suggested-actions'and'content'(where both__mainand__drop-zoneare stacked)File Handling: Both
onPasteandonDrophandlers use the samehandleAddFilescallbackdisableFileUploadanduiState === 'disabled'flagsuseMakeThumbnailhooksendAttachmentOnoption to auto-submit when set to'attach'Specific Changes
New Files:
packages/react-hooks/src/useFileDropZone.ts: Shared hook for drag-and-drop state management (132 lines)packages/component/src/SendBox/DropZone.tsx: Basic theme drop zone overlay component (66 lines)__tests__/html2/basic/dragAndDrop.upload.html: E2E test for drag-and-drop functionality__tests__/html2/basic/pasteFile.html: E2E test for clipboard paste functionalityModified Files:
packages/component/src/SendBox/BasicSendBox.tsx:handleAddFilescallback for file processing with thumbnail supporthandlePasteclipboard event handler<DropZone>when file upload is enabledpackages/fluent-theme/src/components/dropZone/DropZone.tsx:useFileDropZonehookpackages/fluent-theme/src/components/sendBox/SendBox.tsx:handlePasteclipboard event handlerdisableFileUploadanduiStatepackages/react-hooks/src/index.ts: ExporteduseFileDropZoneandDropZoneStatetypepackages/component/src/boot/hook.ts: Re-exporteduseFileDropZonefrom react-hookspackages/bundle/src/boot/actual/hook/minimal.ts: ExporteduseFileDropZonefrom bundlepackages/component/src/testIds.ts: AddedsendBoxDropZonetest IDpackages/component/src/Styles/StyleSet/SendBox.ts: Styles for the new grid layoutTest Updates: Updated snapshot files to reflect CSS grid layout changes in send box
CHANGELOG.mdI have updated documentationReview Checklist
z-index)package.jsonandpackage-lock.jsonreviewed