Skip to content

feat: copyToClipboard ref method for EnrichedMarkdownTextInput#461

Open
mvanhorn wants to merge 1 commit into
software-mansion:mainfrom
mvanhorn:feat/341-copy-to-clipboard
Open

feat: copyToClipboard ref method for EnrichedMarkdownTextInput#461
mvanhorn wants to merge 1 commit into
software-mansion:mainfrom
mvanhorn:feat/341-copy-to-clipboard

Conversation

@mvanhorn

Copy link
Copy Markdown

What/Why?

Resolves #341. An app that renders content through EnrichedMarkdownTextInput wanted a copy button that copies the rich content, but the only way to copy was for the user to manually select text and use the context menu. From JavaScript the app could reach the raw Markdown or plain text, which loses the formatting the user sees on screen.

This adds a copyToClipboard imperative ref method that places the input's full rich content on the system clipboard, producing the same result as selecting all text and pressing the context menu's copy action. The method is a no-op when the input is empty and leaves the current selection untouched, so it is safe to call from a toolbar button at any time.

The command follows the existing removeLink/setValue pattern through the codegen command list and the useImperativeHandle block. On Android it writes the whole Editable to the ClipboardManager, which keeps the inline styles available to rich paste targets without moving the caret. On iOS and macOS it reuses the exact pasteboard format already produced by the user-triggered copy action, writing both plain text and the existing private Markdown pasteboard type so a later paste back into the input restores the formatting.

Testing

yarn typecheck and yarn lint pass, and clang-format --Werror is clean on the changed Objective-C++ files. I also confirmed that React Native codegen regenerates the native command dispatchers so copyToClipboard routes to the new native methods on both platforms. Documentation in docs/INPUT.md and docs/API_REFERENCE.md is updated.

PR Checklist

  • Updated documentation/README if applicable

Native compile, running the example app, and the E2E suite were not performed in this environment, so a maintainer should verify the on-device behavior.

Fixes #341

Adds a copyToClipboard command across the TS, Android, and iOS/macOS
surfaces so an app-level copy button can place the input's full rich
content on the system clipboard, matching the context menu copy action.
Empty input is a no-op and the selection is left unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQ7G74DcZPFPEgDJMTEcCR
// Copies the whole rich content to the system clipboard, matching the
// result of selecting all text and pressing the context menu's copy action.
// Writing the full Editable directly preserves inline styles for rich paste
// targets without disturbing the current selection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The comment says "Writing the full Editable directly preserves inline styles for rich paste targets" — but ClipData.newPlainText(null, content) writes plain text only, it doesn't preserve inline styles. The comment should accurately describe what the method does.

Note: on iOS, copy/paste preserves formatting via a private pasteboard type (kENRMMarkdownPasteboardType). Android doesn't have this round-trip yet — system copy/paste is plain text only. This is a pre-existing gap, not introduced by this PR, but worth tracking as a follow-up if rich paste on Android is desired.

@hryhoriiK97 hryhoriiK97 self-requested a review June 29, 2026 20:11

@hryhoriiK97 hryhoriiK97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This doesn't compile — _textView is typed as ENRMPlatformTextView (UITextView/NSTextView), not ENRMInputTextView, so the compiler can't find copyEntireContents.

Rather than downcasting, I'd suggest removing copyEntireContents from ENRMInputTextView entirely and doing the pasteboard write directly here in EnrichedMarkdownTextInput.mm. This matches how requestMarkdown: (line ~902) already serializes full content in this file. Something like:

- (void)copyToClipboard
{
  NSString *plainText = ENRMGetPlainText(_textView);
  if (plainText.length == 0) {
    return;
  }
  NSString *markdown = [ENRMMarkdownSerializer serializePlainText:plainText
                                                           ranges:[self allRangesIncludingTransient]];
#if TARGET_OS_OSX
  NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
  [pasteboard clearContents];
  NSMutableArray *types = [NSMutableArray arrayWithObject:NSPasteboardTypeString];
  if (markdown.length > 0) {
    [types addObject:kENRMMarkdownPasteboardType];
  }
  [pasteboard declareTypes:types owner:nil];
  [pasteboard setString:plainText forType:NSPasteboardTypeString];
  if (markdown.length > 0) {
    [pasteboard setString:markdown forType:kENRMMarkdownPasteboardType];
  }
#else
  UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
  NSMutableDictionary *items = [NSMutableDictionary dictionary];
  items[UTTypePlainText.identifier] = plainText;
  if (markdown.length > 0) {
    items[kENRMMarkdownPasteboardType] = markdown;
  }
  pasteboard.items = @[ items ];
#endif
}

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.

Ref method for copy to clipboard

2 participants