feat: add linkOnPaste prop to EnrichedTextInput (iOS, Android, Web) - #746
Open
jtatar wants to merge 1 commit into
Open
feat: add linkOnPaste prop to EnrichedTextInput (iOS, Android, Web)#746jtatar wants to merge 1 commit into
jtatar wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an opt-in linkOnPaste prop to EnrichedTextInput across iOS/Android/Web so that pasting a bare URL over a non-empty selection linkifies the selected text instead of replacing it, matching common rich-text editor behavior while keeping default behavior unchanged.
Changes:
- Introduces the
linkOnPasteprop end-to-end (types/defaults, native codegen spec, native + web wrappers). - Implements platform-specific paste interception/linkification logic (iOS/Android/Web) with “whole-string URL” detection and scheme-less
https://normalization. - Updates example apps and adds Playwright E2E coverage for Web.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/web/linkOnPaste.ts | Implements web linkOnPaste paste handler and URL normalization. |
| src/web/EnrichedTextInput.tsx | Wires handleLinkOnPaste into TipTap paste handling and threads prop via refs. |
| src/utils/EnrichedTextInputDefaultProps.ts | Adds linkOnPaste: false default. |
| src/types.ts | Documents and exposes linkOnPaste?: boolean on the public props interface. |
| src/spec/EnrichedTextInputNativeComponent.ts | Adds linkOnPaste?: boolean to codegen native props. |
| src/native/EnrichedTextInput.tsx | Passes linkOnPaste through the native wrapper to the native component. |
| ios/styles/LinkStyle.mm | Adds “match entire string” link-regex helper for bare-URL paste detection. |
| ios/interfaces/StyleHeaders.h | Exposes the new LinkStyle “entire string” matcher in headers. |
| ios/EnrichedTextInputView.mm | Adds tryAddLinkAt... (BOOL return) and linkURLIfEntireString: helper for iOS paste flow. |
| ios/EnrichedTextInputView.h | Exposes linkOnPaste ivar and new helper method declarations. |
| ios/enrichedInputTextView/EnrichedInputTextView.mm | Adds iOS paste: branch for linkifying selection + refactors plain-text extraction helper. |
| docs/INPUT_API_REFERENCE.md | Documents the new linkOnPaste prop behavior and platform support. |
| apps/example/src/screens/TestScreen.tsx | Enables linkOnPaste in the native example screen for manual testing. |
| apps/example/src/screens/DevScreen.tsx | Enables linkOnPaste in the native dev screen for manual testing. |
| apps/example-web/src/testScreens/TestLinks.tsx | Enables linkOnPaste in the web example test screen. |
| apps/example-web/src/App.tsx | Enables linkOnPaste in the main web example app configuration. |
| android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputViewManager.kt | Adds ViewManager setter for linkOnPaste. |
| android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputView.kt | Implements Android selection-linkify-on-paste logic + whole-string regex companion. |
| .playwright/tests/links.spec.ts | Adds E2E suite covering linkOnPaste success + fallback cases. |
| .playwright/helpers/clipboard.ts | Adds helper to paste over an existing selection without collapsing it. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jtatar
force-pushed
the
feat/link-on-paste
branch
from
August 5, 2026 13:20
c404c81 to
b0a05c2
Compare
When enabled, pasting clipboard content that is solely a URL over a
non-empty selection turns the selected text into a link pointing to that
URL instead of replacing the selection. Disabled by default.
- Recognizes a URL only when it fully matches linkRegex (or the default
link-detection patterns); scheme-less URLs get an https:// prefix.
- Falls back to a normal paste for empty/whitespace selections, non-bare-URL
clipboard text, or when the link style is blocked (inline code, code block).
- No effect when link detection is disabled via linkRegex={null}.
JS: prop on the codegen spec, types, default props, native/web wrappers.
iOS: gated branch in paste:, tryAddLinkAt:/linkURLIfEntireString: on the view,
matchesEntireLinkRegexWithConfig: on LinkStyle.
Android: gated branch in handleTextPaste, linkifySelectionOnPaste helper,
linkExactRegex companion, setLinkOnPaste ViewManager setter.
Web: handleLinkOnPaste wired into TipTap handlePaste.
Docs (INPUT_API_REFERENCE), example apps and a Playwright linkOnPaste suite
(4 cases, all green; full links suite 35 passed).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jtatar
force-pushed
the
feat/link-on-paste
branch
from
August 5, 2026 13:23
b0a05c2 to
3770d52
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in
linkOnPasteprop to<EnrichedTextInput />(iOS, Android, Web).When enabled, pasting clipboard content that is solely a URL over a
non-empty selection turns the selected text into a link pointing to that
URL, instead of replacing the selection with the pasted text. This is a common
rich-text convenience (it mirrors the "paste URL onto selected text" behavior
of editors like Google Docs, Notion, Slack).
Disabled by default (
linkOnPaste={false}), so existing behavior isunchanged for current users — the feature only activates when explicitly turned
on.
Behavior details:
configured
linkRegex(or the default link-detection patterns whenlinkRegexis not set). Clipboard text containing a URL plus other text(e.g.
see https://example.com) is not treated as a link and falls backto a normal paste.
www.example.com) get anhttps://prefix in theresulting link href, while the visible selected text is preserved.
or when the link style cannot be applied at the selection (inside inline code
or a code block).
linkRegex={null}.Implementation:
types.ts, default props (false), and thenative/web
EnrichedTextInputwrappers.EnrichedInputTextView'spaste:; a newtryAddLinkAt:...(returns whether the link was applied) andlinkURLIfEntireString:onEnrichedTextInputView; amatchesEntireLinkRegexWithConfig:full-string variant onLinkStyle.handleTextPaste; alinkifySelectionOnPastehelper plus a
linkExactRegex(whole-string) companion tolinkRegex, and asetLinkOnPasteViewManager setter.handleLinkOnPastewired into the TipTap editor'shandlePaste,reusing the existing autolink regex and the
EnrichedLink.setLinkcommand(which already bails out when the link style is blocked).
Test Plan
Web (automated): added a
test-links linkOnPastesuite to.playwright/tests/links.spec.tscovering: linkifying the selection with a fullURL,
https://prefixing for a scheme-less URL, and the two fallback cases(non-bare-URL text, and no selection). Run with
yarn test:e2e:web. The fulllinks suite (35 tests) passes.
Manual (all platforms). The example app enables
linkOnPasteon its editorscreens. To verify:
Hello world, selectworld.linkRegexaccepts and paste over the selection→
worldbecomes a link to that URL (visible text unchanged).www.…) → the link href is prefixed withhttps://.see https://…) → normal paste(selection replaced, not linkified).
linkOnPaste={false}→ step 2 becomes a normal paste again (selectionreplaced), confirming the default/off behavior is unchanged.
yarn typecheck,yarn lint, andyarn lint-clangall pass; the AndroidGradle
lintVerifybuilds the module cleanly.Compatibility
Checklist