Skip to content

[lexical-playground] Feature: Add file attachment support with drag & drop functionality#7895

Closed
Yjason-K wants to merge 0 commit intofacebook:mainfrom
Yjason-K:main
Closed

[lexical-playground] Feature: Add file attachment support with drag & drop functionality#7895
Yjason-K wants to merge 0 commit intofacebook:mainfrom
Yjason-K:main

Conversation

@Yjason-K
Copy link
Copy Markdown

@Yjason-K Yjason-K commented Oct 1, 2025

Description

Current behavior:

  • The lexical playground editor only supports text, images, and other basic content types
  • No built-in support for file attachments or document uploads
  • Users cannot attach files like PDFs, Word documents, or other file types to their content

Changes being added:

  • AttachmentNode: New decorator node for handling file attachments with metadata (name, size, type, URL)
  • AttachmentComponent: React component for rendering attachment nodes with file type icons and interaction controls
  • AttachmentPlugin: Plugin providing drag & drop file upload, file insertion commands, and attachment management
  • File validation: Support for multiple file types (PDF, Office docs, images, videos, audio) with 3MB size limit
  • Serialization support: Base64 conversion for proper attachment persistence and export
  • UI integration: Toolbar button with file upload dialog and attachment preview
  • Comprehensive testing: E2E tests covering drag & drop, file validation, and attachment interactions

The implementation includes proper cleanup of object URLs, keyboard navigation support, and responsive styling that matches the playground theme.

Test plan

Before

  • Users could only add text, images, and basic content to the editor
  • No file attachment capabilities
  • Limited content types supported

After

File Upload Dialog:

  • Click attachment button in toolbar opens file selection dialog
  • File preview shows metadata (name, size, type) before insertion
  • Validation prevents oversized files (>3MB) and unsupported types

Drag & Drop Functionality:

  • Drag files directly into editor to create attachment nodes
  • Visual feedback during drag operations
  • Automatic file type detection and validation

Attachment Display:

  • File type icons for different formats (PDF, Word, Excel, etc.)
  • File metadata display (name, size)
  • Hover effects and selection states
  • Delete functionality with keyboard support

Serialization & Persistence:

  • Attachments properly serialize to/from JSON with base64 data
  • DOM export/import maintains attachment data
  • Object URL cleanup prevents memory leaks

Supported File Types:

  • Documents: PDF, Word (.doc/.docx), Excel (.xls/.xlsx), PowerPoint (.ppt/.pptx)
  • Images: JPEG, PNG, GIF, WebP
  • Videos: MP4, AVI, QuickTime
  • Audio: MP3, WAV, FLAC
  • Archives: ZIP, RAR
  • Text: TXT, CSV

E2E Test Coverage:

  • ✅ File upload via dialog
  • ✅ Drag & drop functionality
  • ✅ File type validation
  • ✅ Size limit enforcement
  • ✅ Attachment deletion
  • ✅ Keyboard navigation
  • ✅ Serialization/deserialization
attachment-plugin-test attachment-plugin-floating-toolbar
attachment.mov

@vercel
Copy link
Copy Markdown

vercel Bot commented Oct 1, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
lexical Ready Ready Preview Comment Oct 1, 2025 8:14am
lexical-playground Ready Ready Preview Comment Oct 1, 2025 8:14am

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 1, 2025
@ivailop7 ivailop7 added the extended-tests Run extended e2e tests on a PR label Oct 1, 2025
@etrepum
Copy link
Copy Markdown
Collaborator

etrepum commented Oct 1, 2025

File uploads encoded as base64 isn't really a very good idea. It's done for images just for demonstration purposes, but in order to support attachments (and images) in any real production capacity you would really need to have some server-side code or service provider (amazon s3, cloudflare r2, etc.) storing those files and the document should only store the URLs. My concern about adding more examples of what not to do will lead to more bad code in people's applications.

@Yjason-K
Copy link
Copy Markdown
Author

Yjason-K commented Oct 2, 2025

@etrepum
Thanks for the feedback—I understand your point and I’m removing the base64 approach.
I fully agree that in production files should be uploaded to a server/storage provider and referenced by URL only. To align with that, I’ll add an abstracted AttachmentStore interface so developers can plug in a real backend with the same API.
For the playground demo (which resets on reload), I’ll keep it server-free and generate session-scoped object URLs (blob:) from uploaded files, so the document still stores URLs only during the session (no base64).
To avoid encouraging bad practices, I’ll limit the demo to a few formats (eg. PDF, DOCX, Markdown), enforce MIME/size checks, and include clear “demo only” notes, plus Export/Import and a “Clear storage” action.
If you see a better direction, I’m glad to follow it :)

@vadimkantorov
Copy link
Copy Markdown

vadimkantorov commented Oct 7, 2025

One useful primitive that I found when using Lexical for editing markdown blog pages on GitHub (and GitHub API)-backed site is:

  • having blob:// urls (similar to your proposal) during document editing until the file/image is committed yet to the server storage (this means maintaining a map between local<>remote urls, having an util for committing the uncommitted files and updating their urls, providing an util for converting a relative path to absolute https-url)
  • having support for relative urls used in images/attachments: like /uploads/myimage.jpg, and having the base url prefix be attached only when rendering to the img tag (unfortunately we cannot have a special <base> tag just for images) and the prefix can also be stripped back when converting <img> to markdown

Like so, content with attached images/files can be nicely edited in markdown and conversion markdown <> visual representation

I named this "ImageRegistry" in my path, but maybe this concept could be fused into AttachmentStore


Export/import of images/attachments with base64 contents can also be useful in some settings, e.g. for self-contained document representation. So having such explicit configurable support in export/import would also be useful. But I agree that in the most well-spread mode should be with URL's.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants