Skip to content

feat: support native text selection for selectable Text on iOS - #56236

Open
Saadnajmi wants to merge 1 commit into
react:mainfrom
Saadnajmi:fabric/text-selection-ios
Open

feat: support native text selection for selectable Text on iOS#56236
Saadnajmi wants to merge 1 commit into
react:mainfrom
Saadnajmi:fabric/text-selection-ios

Conversation

@Saadnajmi

@SaadnajmiSaadnajmi commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

Hi, I would have made this an RFC but I figured it's easier to just see this as a PR. If we like, I can gate this behind a React Native Feature Flag too.

This is upstreaming a change we've had in React Native macOS a while (albeit on Paper, the Fabric one just landed recently), actually originally made by the React Native Desktop team at Meta.

Summary:

React Native on iOS has been missing native selectable text for a while, leading to 3rd parties like Bluesky writing their own native modules to use UITextView. Presumbly the issue is perf, UITextView is much heavier than just rendering text. This PR takes an approach to only pay that cost if selectable is true. When false, we follow the oiriginal fast path.

When enabled:

  • A UITextView (RCTParagraphSelectableTextView) is created and swapped in as the content view, replacing the lightweight RCTParagraphTextView
  • Text storage is synced from RCTTextLayoutManager so rendering matches
  • The UITextView handles selection natively (long press to select, drag handles, double-tap for word selection)
  • The context menu (copy) continues to work alongside selection
  • The UITextView is torn down on prepareForRecycle and when the prop toggles back to false

Also exposes getTextStorageForAttributedString:paragraphAttributes:size: on RCTTextLayoutManager as a public API, which simply wraps the existing private _textStorageAndLayoutManagerWithAttributesString: method.

Changelog:

[iOS][Added] - Native text selection support for <Text selectable={true}>

Test Plan:

Screen.Recording.2026-03-26.at.5.55.39.PM.mov

Summary:
The `selectable` prop on `<Text>` currently only enables a context menu
(long press → copy) but does not provide actual native text selection.
This adds real text selection by swapping the content view to a UITextView
when `selectable={true}`.
When `selectable={false}` (the default, ~99% of text), behavior is
completely unchanged — no UITextView is created. When enabled:
- A UITextView (RCTParagraphSelectableTextView) is created and swapped in
as the content view, replacing the lightweight RCTParagraphTextView
- Text storage is synced from RCTTextLayoutManager so rendering matches
- The UITextView handles selection natively (long press to select, drag
handles, double-tap for word selection)
- The context menu (copy) continues to work alongside selection
- The UITextView is torn down on prepareForRecycle and when the prop
toggles back to false
Also exposes `getTextStorageForAttributedString:paragraphAttributes:size:`
on RCTTextLayoutManager as a public API, which simply wraps the existing
private `_textStorageAndLayoutManagerWithAttributesString:` method.
Changelog: [iOS][Added] - Native text selection support for `<Text selectable={true}>`
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@meta-clameta-claBot 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 Mar 26, 2026
@github-actions

Copy link
Copy Markdown

Warning

JavaScript API change detected

This PR commits an update to ReactNativeApi.d.ts, indicating a change to React Native's public JavaScript API.

  • Please include a clear changelog message.
  • This change will be subject to additional review.

This change was flagged as: POTENTIALLY_BREAKING

@facebook-github-toolsfacebook-github-toolsBot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Mar 26, 2026
@NickGerleman

Copy link
Copy Markdown
Contributor

Note that, partially for Android, RCTSelectableText was recently added, to accomplish this kind of this. JS side prefers that for selectable text. Right now, that's tied to some feature flags never enabled on iOS though.

@Saadnajmi

Copy link
Copy Markdown
ContributorAuthor

Note that, partially for Android, RCTSelectableText was recently added, to accomplish this kind of this. JS side prefers that for selectable text. Right now, that's tied to some feature flags never enabled on iOS though.

Ah, would you rather I refactor to use that, and just move the UITextView based component to that? When macOS gets there, I can remember to do the same there too.

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

Labels

CLA SignedThis label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.p: MicrosoftPartner: MicrosoftPartnerShared with MetaApplied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Saadnajmi@NickGerleman