Skip to content

feat: Add clipboard paste and drag-and-drop file support to both themes#5829

Merged
OEvgeny merged 11 commits into
mainfrom
feat/paste-dnd-white-label
May 15, 2026
Merged

feat: Add clipboard paste and drag-and-drop file support to both themes#5829
OEvgeny merged 11 commits into
mainfrom
feat/paste-dnd-white-label

Conversation

@OEvgeny
Copy link
Copy Markdown
Collaborator

@OEvgeny OEvgeny commented May 14, 2026

Fixes #

Changelog Entry

  • Added clipboard paste and drag-and-drop file support to both basic and fluent themes, in PR #5829, by @OEvgeny

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 useFileDropZone hook 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:

  1. Shared State Management: Created useFileDropZone hook in @msinternal/botframework-webchat-react-hooks to manage document-level drag events and drop zone state

    • Tracks entrance counter for nested drag events across DOM boundaries
    • Returns drop zone state (false, 'visible', or 'droppable') based on drag target
    • Provides drag/drop event handlers for the drop zone component
  2. CSS 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

    • Avoids creating stacking contexts that interfere with middleware decorations
    • Grid areas: 'suggested-actions' and 'content' (where both __main and __drop-zone are stacked)
  3. File Handling: Both onPaste and onDrop handlers use the same handleAddFiles callback

    • Respects disableFileUpload and uiState === 'disabled' flags
    • Generates thumbnails for image files using existing useMakeThumbnail hook
    • Honors sendAttachmentOn option 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 functionality
  • Modified Files:

    • packages/component/src/SendBox/BasicSendBox.tsx:

      • Added CSS grid layout with named areas for drop zone stacking
      • Implemented handleAddFiles callback for file processing with thumbnail support
      • Added handlePaste clipboard event handler
      • Conditionally renders <DropZone> when file upload is enabled
    • packages/fluent-theme/src/components/dropZone/DropZone.tsx:

      • Factored out drag-and-drop logic into useFileDropZone hook
    • packages/fluent-theme/src/components/sendBox/SendBox.tsx:

      • Added handlePaste clipboard event handler
      • Gated paste functionality on disableFileUpload and uiState
    • packages/react-hooks/src/index.ts: Exported useFileDropZone and DropZoneState type

    • packages/component/src/boot/hook.ts: Re-exported useFileDropZone from react-hooks

    • packages/bundle/src/boot/actual/hook/minimal.ts: Exported useFileDropZone from bundle

    • packages/component/src/testIds.ts: Added sendBoxDropZone test ID

    • packages/component/src/Styles/StyleSet/SendBox.ts: Styles for the new grid layout

  • Test Updates: Updated snapshot files to reflect CSS grid layout changes in send box

  • I have added tests and executed them locally
  • I have updated CHANGELOG.md
  • I have updated documentation

Review Checklist

This section is for contributors to review your work.

  • Accessibility reviewed (tab order, content readability, alt text, color contrast)
  • Browser and platform compatibilities reviewed
  • CSS styles reviewed (minimal rules, no z-index)
  • Documents reviewed (docs, samples, live demo)
  • Internationalization reviewed (strings, unit formatting)
  • package.json and package-lock.json reviewed
  • Security reviewed (no data URIs, check for nonce leak)
  • Tests reviewed (coverage, legitimacy)

OEvgeny added 2 commits May 14, 2026 20:50
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
@OEvgeny OEvgeny force-pushed the feat/paste-dnd-white-label branch from 0f57dd3 to fd39635 Compare May 14, 2026 21:05
@OEvgeny OEvgeny marked this pull request as ready for review May 15, 2026 00:29
@OEvgeny OEvgeny requested a review from a-b-r-o-w-n as a code owner May 15, 2026 00:29
Copilot AI review requested due to automatic review settings May 15, 2026 00:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 useFileDropZone hook and re-export it through component/bundle hook surfaces.
  • Add basic-theme DropZone.tsx overlay and wire paste + drop file handling (with thumbnail generation and auto-submit) into BasicSendBox.
  • Add fluent-theme onPaste handler 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.

Comment thread packages/component/src/SendBox/DropZone.tsx Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread packages/component/src/SendBox/DropZone.tsx Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts
Comment thread packages/react-hooks/src/useFileDropZone.ts
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/react-hooks/src/useFileDropZone.ts
Comment thread packages/react-hooks/src/useFileDropZone.ts Outdated
Comment thread packages/fluent-theme/src/components/sendBox/SendBox.tsx
Comment thread packages/fluent-theme/src/components/sendBox/SendBox.tsx Outdated
Comment thread packages/fluent-theme/src/components/dropZone/DropZone.tsx
Comment thread packages/fluent-theme/src/components/dropZone/DropZone.tsx
Comment thread packages/component/src/SendBox/DropZone.tsx
Comment thread packages/component/src/SendBox/BasicSendBox.tsx Outdated
Comment thread packages/fluent-theme/src/components/dropZone/DropZone.tsx
Comment thread packages/component/src/SendBox/BasicSendBox.tsx
Comment thread __tests__/html2/basic/dragAndDrop.upload.html
Comment thread __tests__/html2/basic/pasteFile.html
Comment thread packages/component/src/boot/hook.ts
Comment thread packages/component/src/SendBox/BasicSendBox.tsx
Comment thread packages/component/src/SendBox/BasicSendBox.tsx Outdated
Comment thread packages/component/src/SendBox/BasicSendBox.tsx Outdated
@OEvgeny
Copy link
Copy Markdown
Collaborator Author

OEvgeny commented May 15, 2026

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.

@OEvgeny OEvgeny merged commit 2a3d1d3 into main May 15, 2026
32 checks passed
@OEvgeny OEvgeny deleted the feat/paste-dnd-white-label branch May 15, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants