Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add onPaste to TextInput #804

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

s77rt
Copy link

@s77rt s77rt commented Jul 18, 2024

Proposal on adding onPaste prop to TextInput component to detect paste event. View rendered proposal

@NickGerleman
Copy link

NickGerleman commented Jul 19, 2024

On web, the analog of this event shape is ClipboardEvent, where we have cut/copy/paste events. https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent

Notably, the events expose clipboardData, with clipboard content cut or pasted. This may include more types than just text (like pasting an image, or a file), and may also be attached in more places (the API shares similarities to drag and drop).

With current proposal, the way we could try to maybe infer content from the underlying mutation, but this can be tricky. We also cannot rely on the global clipboard, since it is async, and could point to something different by the time we ask for its content in response to paste event. So, we really want a reference to the underlying data when the paste happens.

Partially modeling something like clipboardData, so the underlying text content can be exposed (or, I guess image/file data for what was referenced) feels important to this proposal.


## Unresolved questions

- onPaste event does not expose any clipboard data. How can we add such data?
Copy link
Author

Choose a reason for hiding this comment

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

@NickGerleman Can we handle this as a follow up?

Choose a reason for hiding this comment

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

I don't think so. The event without data would require accessing clipboard afterward, and since that happens asynchronously, the data may have changed or be incorrect. A concrete example of this, is if you paste a password, a password manager might immediately clear it from the clipboard.

I.e. the current approach without the data is impossible to make reliable, and would encourage users to add code which falls into the anti-pattern.

I don't know how much time @cipolleschi has dedicated to this change, but did want to share the context I had on this, and some of the baselines of what these events should look like.

Copy link
Author

Choose a reason for hiding this comment

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

The data can be as follow:

{
    target: viewTag,
    items: [
        {
            type: "image/jpeg", // MIME type
            data: "data:image/jpeg;base64,..." // data: plaintext for text/plain and base64 encoded data for the rest
        }
    ],
}

items is an array that holds different items present in the clipboard, but for the current implementation only the first item is added.

Android implementation facebook/react-native@af06d9e

Screen.Recording.2024-07-24.at.3.22.50.AM-2.mov

Copy link
Author

Choose a reason for hiding this comment

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

Regarding pasting files, using base64 string is not looking very performant (dealing with long strings can be slow). I'm looking into passing the URI instead, for Android we can directly use clipData.getItemAt(0).getUri()

(still investigating the same for iOS)

Copy link
Author

Choose a reason for hiding this comment

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

On iOS the clipboard items do not expose any URI. When a file is pasted, we copy its data into a temporarily file and provide that file's URI instead. Proposal updated.

@s77rt s77rt requested a review from NickGerleman July 27, 2024 00:55
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.

2 participants