react-native-advanced-selectable-text
v0.1.3
Published
High-performance, fully customizable text selection component for React Native using Skia rendering
Maintainers
Readme
react-native-advanced-selectable-text
High-performance, fully customizable text selection component for React Native using Skia rendering. Achieve "ChatGPT-style" text selection with custom cursors, handles, and floating menus.
Features
- 🎨 Skia-powered rendering - Smooth 60fps selection animations
- 📱 Cross-platform - iOS, Android, and Web (Expo compatible)
- 🔗 Multiple Instances - Coordinated selection across many components (perfect for chat feeds)
- ✨ Customizable - Selection colors, cursor styles, handle appearance
- 🎯 Precise selection - Draggable handles with swap support
- 💬 Floating menu - Animated action menu with custom options
- ⚡ Reanimated worklets - UI thread gesture handling
- 🛡️ Strongly Typed - Full TypeScript support, zero
any
Installation
# npm
npm install react-native-advanced-selectable-text
# yarn
yarn add react-native-advanced-selectable-text
# bun
bun add react-native-advanced-selectable-textPeer Dependencies
This package requires the following peer dependencies:
# npm
npm install @shopify/react-native-skia react-native-gesture-handler react-native-reanimated react-native-worklets
# Expo
npx expo install @shopify/react-native-skia react-native-gesture-handler react-native-reanimated react-native-workletsBasic Usage
Wrap your application (or specific screen) with SelectionProvider to enable coordinated selection handling.
import {
SelectableText,
SelectionProvider,
useSelection,
} from "react-native-advanced-selectable-text";
import { GestureHandlerRootView } from "react-native-gesture-handler";
function Example() {
const { selection, clearSelection } = useSelection();
return (
<View style={{ flex: 1 }} onTouchStart={() => clearSelection()}>
<SelectableText
text="Long-press me for selection!"
menuOptions={[
{ label: "Copy", onPress: (text) => console.log("Copy:", text) },
]}
/>
</View>
);
}
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<SelectionProvider>
<Example />
</SelectionProvider>
</GestureHandlerRootView>
);
}Advanced: Coordinated chat list
When using SelectionProvider, multiple SelectableText instances will automatically coordinate. Starting a selection in one message will automatically clear the selection in others.
<SelectionProvider>
<ScrollView>
{messages.map((msg) => (
<SelectableText
key={msg.id}
text={msg.content}
menuOptions={globalMenuOptions}
/>
))}
</ScrollView>
</SelectionProvider>Props
| Prop | Type | Default | Description |
| ------------------- | ---------------------------------------- | ------------------------- | ---------------------------------------------- |
| text | string | required | The text content to display |
| menuOptions | MenuOption[] | required | Array of menu options |
| fontSize | number | 16 | Font size in points |
| fontFamily | string | System font | Font family name |
| textColor | string | #000000 | Text color |
| selectionColor | string | rgba(59, 130, 246, 0.3) | Selection highlight color |
| cursorColor | string | #3b82f6 | Cursor and handle color |
| width | number | Container width | Fixed width for text layout |
| style | ViewStyle | - | Container style |
| selection | Selection \| null | - | Overrides internal selection (controlled mode) |
| onSelectionChange | (selection: Selection \| null) => void | - | Selection change callback |
Hooks
useSelection()
Used inside a SelectionProvider to access or manipulate the active selection.
const {
selection, // Current active selection object
clearSelection, // Function to clear all selections in the provider
setSelection, // Manually set the selection
onSelectionChange, // Standard handler for SelectableText
} = useSelection();Architecture
- Skia Paragraph API: Used for advanced text layout and measuring glyph positions.
- Selection Coordination: Controlled via React Context and internal unique instance IDs.
- Gesture Performance: All gestures run on the UI thread using Reanimated worklets for lag-free handle dragging.
Development
# Install dependencies
bun install
# Build the library
bun run build
# Run example app
cd apps/example
bun run ios # or ‘android’License
MIT
