Skip to content

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

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

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

Conversation

@Saadnajmi
Copy link
Copy Markdown
Contributor

@Saadnajmi Saadnajmi commented Mar 26, 2026

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-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 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-tools facebook-github-tools bot 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
Contributor Author

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 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. p: Microsoft Partner: Microsoft Partner Shared with Meta Applied 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